So-net無料ブログ作成
検索選択

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

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。