SSブログ

ColdFire V1 とチャット - シリアル・インターフェースの実験 [ColdFire (ColdeFire) V1]このエントリーを含むはてなブックマーク#

DEMOQE128には、シリアルインターフェースが付属しています。 これを利用して、通信を行ってみます。

お便利関数の宣言

このプログラムでは、SCIを使った通信を行います。 通信の最も低レベルな関数群をここで宣言しています。 実際の関数の中身は、後ろのほうで定義しています。

#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

// お便利関数の宣言
int     getc(void);
void    putc(int ch);
void    puts(const char *s);

大域変数の宣言

続いて、大域変数を宣言していますが、 このプログラムでは、文字バッファひとつだけです。

// 大域変数の宣言
int    c;               // 文字バッファ

初期設定

メイン関数は、初期設定から始まります。

// メイン関数
void main(void) {

  // SOPT1を設定する
  SOPT1 = 0
    | SOPT1_WAITE_MASK    // Enable WAIT instruction
    | SOPT1_RSTOPE_MASK   // Enable RSTO* port
    | SOPT1_BKGDPE_MASK   // Enable BKGD port
    | SOPT1_RSTPE_MASK ;  // Enable RESET* port

いつものように、SOPT1レジスタを設定して、 COPを黙らせます。

  // ICSを設定する
  //   REFCLK = 38,400Hz
  //   DCO    = 39,321,600Hz
  //   BUSCLK = 19,660,800Hz
  ICSTRM          = NVICSTRM;
  ICSSC_FTRIM     = NVFTRIM_FTRIM;
  ICSC2_BDIV      = 0;  // BDIV 1/1
  ICSSC_DRST_DRS  = 1;  // FLL x1024

このプログラムでは、バス・クロックの周波数をボーレートの512倍に設定することにより、 通信エラーが起きにくいようにしています。 このため、デバッガでプログラムを書き込むときに、 内部参照クロックのトリム値を38,400Hzにあわせるのを忘れないようにしなくてはなりません。 バス・クロックは、19.8808MHzとかなり高速動作させています。

  // SCI1を設定する
  //   BAUD   = 38,400
  //   BR     = BUSCLK / BAUD / 16 = 32
  SCI1BD_SBR = 32;      // BUSCLK / BAUD / 16
  SCI1C2_TE  = 1;       // 送信機能を有効にする
  SCI1C2_RE  = 1;       // 受信機能を有効にする

  EnableInterrupts; /* enable interrupts */
  /* include your code here */

SCIは、ボーレートを38,400baudに合わせています。 バス・クロックを合わせこんだため、 SBRレジスタは、32というキリの良い数値になっています。

  for(;;) {
    puts("\nReady* ");    // プロンプトを表示する
    for (;;) {
      c = getc();         // 一文字受信する
      if (c == '\n') break; // 行末文字なら脱出
      putc(c);            // 受信した文字を送信する
    }
  } /* loop forever */
  /* please make sure that you never leave main */
}

メイン関数は、二つの無限ループから構成されています。 外側のループは、一行入力ごとに回ります。 内側のループは、一文字入力ごとにまわり、 行末を見つけたらbreak文で脱出します。

お便利関数の定義

ここから、お便利関数の定義が並びます。

// 一文字受信ルーチン
int getc(void) {
  int ch;
  
  // 受信バッファがいっぱいになるのを待つ
  while (!SCI1S1_RDRF) {
    // Do nothing
  }
  ch = SCI1D;           // 一文字受け取る
  if (ch == '\r') {     // Enterキーは、
    ch = '\n';          // 行末文字に変換する
  }
  return ch;            // 受け取った文字を返す
}

一文字受信ルーチンでは、 RDRFフラグで文字の到着を待ち、 到着した文字を受け取ります。 Enterキーが検出されたら、行末文字に変換して値を返します。

// 一文字送信ルーチン
void putc(int ch) {
  if (ch == '\n') {     // 行末文字の前にCRを付ける
    // 送信バッファが空くのを待つ
    while (!SCI1S1_TDRE) {
      // Do nothing
    }
    SCI1D = '\r';       // SCIにCR文字を送信する
  }
  // 送信バッファが空くのを待つ
  while (!SCI1S1_TDRE) {
    // Do nothing
  }
  SCI1D = (byte)ch;     // SCIに一文字送信する
}

一文字送信ルーチンは、 送信バッファが空いたのを確認してから文字をSCIに引き渡します。 このルーチンでは、行末文字を見つけたら、 CR+LFに変換して送信します。

// 文字列送信ルーチン
void puts(const char *s) {
  while (*s) {          // 文字列末でなければ、
    putc(*s++);         // 一文字送信する
  }
}

文字列送信ルーチンでは、 文字列末まで一文字ずつ値を取り出して、一文字送信ルーチンを呼び出しています。

ツール・キットを入手しよう

プログラムを書き込んだら、シリアル・インターフェースをPCとつなぎます。 この時、通常であればPCにシリアル・インターフェースを準備しなくてはならないのですが、 DEMOQE128には、USB接続に使われているHCS12チップが シリアルインターフェースのフリをしてくれる機能があります。 ところが、 この機能は、どうやら規格が公になっているのではないらしいので、 P&Eが提供するアプリケーション・ソフトウェア(ツール・キット)を使用する必要があります。

DEMOQE128のクイック・スタート文書などには、同梱のDVD-ROMに アプリケーション・ソフトウェアが入っているという表現が見られるのですが、 少なくとも私のところに来たDVD-ROMでは、 該当するアプリケーションを見つけられませんでした。

ツール・キットは、以下の場所から入手できます。 http://www.pemicro.com/fixedlinks/DEMOQEToolkit.cfm このページに並んでいる、"Terminal"が目的のアプリケーション・ソフトウェアです。 注意書きに従って、ダウンロード、実行すると、端末ウィンドウが開きます。


nice!(0)  コメント(2)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 2

hamayan

是非、putc、getcを低水準入出力として登録して、printf、scanfを実現して、マイコンでもhello worldできるようにしてください。
by hamayan (2008-01-24 07:57) 

noritan

printf や scanf は、性に合わないので、もっぱら write や read を使っていました。 hello world は、ぜひ別の方法で。

今回のプロンプトがヒントです。

次は、リング・バッファに挑戦の予定。
by noritan (2008-01-24 08:32) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。