[H8-ML(3307)] Re: 割込みによるシリアル通信について
From: "Masanobu Suzuki" <signas@xxxxxxxxxxxxxxx>
Date: 2003年05月27日(火)18時58分17秒
鈴木さん>

> >>RXBUF[rx_len++] = SCI0.RDR;             /* バッファへの書き込み */
> 等によるバッファへの蓄積ルーチンは、どこに記述するのが正しいのでしょうか
> 実は、ここがよく分かっていないポイントなのです。
> (メインルーチンの中??・・・・)

答えを先に書くと、受信割り込みルーチンの中です。

ところが、先の鈴木さんの受信割り込みルーチンでは、
while(条件式){
    RXBUF[rx_len++] = SCI0.RDR;             /* バッファへの書き込み */
}
となって、while文でRDRのデータを繰り返しポインタrx_lenを進め
ながら蓄積しようとされていました。

この処理の問題点は以下です。

・RDRの値は(先にご説明したように)何度読んでも同じですから、
 文字バッファは同じデータで産め尽くされること。

・条件式がRDRFbit==1のため、このwhile文を抜けられないこと。

・その結果無限ループになり、ポインタrx_lenが0〜255まで進み
 最初に用意した文字バッファの配列数を超え、隣接する他の
 変数など が書き換わって暴走する原因になっていること。
 (C言語は、実効時のエラーチェックを行ないません。)

では、どうすれば良いかといいますと、

受信割り込み関数(void){
  ①割り込みステータスフラグのread&クリア0
  ②受信が許可されているかの判断
  (許可されていなければバッファに書き込まず割り込みを抜ける)
  ③受信が許可されていれば、ポインタを+1する ( rx_len++ )
  ④もしポインタが文字バッファ容量を越えている場合の処理
  ⑤バッファに1文字書き込む (RXBUF [ rx_len ] = SCI0.RDR)
  ⑥受信完了フラグを立てるかどうかの判断文
}

です。ここで、⑥ですが、例えばPCなどのハイパーターミナル
などで文字を送ると、文字の最後は 'C/R' または'C/R'+'L/F'
が文末に送られますので、'C/R' か'L/F'(デリミタと言います)
を受信した場合に受信完了フラグ(FLG)をセットします。
尚、デリミタ文字は任意ですが普通はC/RかL/Fです。

こうしておくと、メインからこのフラグを見たときセットされていれば
いつでも何らかの文字列が入っていることになり、先頭からデリミタ
までの個数を調べれば取り出すべき文字列が判ります。
(ポインタで調べてもいいです)
メインでは、文字バッファを読んだあとは、
・ポインタを先頭に戻す。
・受信を許可する(受信完了フラグをリセット=受信許可としても良い)

その他、受信した文字にエラーがあるのかどうかは、H8では
受信エラー割り込みが別に用意されていますから、ここで必要な
処理を独立して記述(エラーフラグを立てるなど)しておけば簡単
です。メインは文字バッファから読み込む前に、このエラーフラグ
をチェックし、エラーがあればなにも考えず受信データを捨てれば
良いわけです。

但し、受け取った文字列が正しいかどうかの判断は、メイン側で
別途行なう必要があることに注意してください。
また、受信の考え方はこれだけではないので、あくまでひとつの
参考とお考え下さい。長くなってすいません。

鈴木(正)


スレッド概略
[3288(R)](起点)
 └[3304(U)]
   └[表示中]
     └[3308(1)]


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]