PIC24Fのシリアルポートで気をつけること
花岡ちゃんのウィークエンド
これまで、PIC24Fを使って、ハイクラスPICの使い勝手を調べてきました。結果としては良好で、速度やRAM容量が必要だったり、シリアルポートが2本必要なプロジェクトなどでは、採用する価値ありだと思います。
そこで、本業の方でちょうどいい案件があったので、早速採用してみました。モノはパソコンから115200bpsで定期的に送信されるシリアルデータを、複数のSPIチャネルに仕分けして転送する機械です。ちょこっとテストしたところ問題なく動作したので、実機に組み込んだところ、あれれ?、ハングアップしてしまいます。症状はシリアル通信を全く受け付けないだけで、その他の機能、タイマー割り込みでのランプの点滅とか、テストボタンの反応だとかは正常に動作しています。
この機械では、以前のプロジェクトで試したコードをタネにして、シリアル受信を割り込みで実装しています。
割り込みハンドラはこんな感じです。
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
unsigned char i;
i = U1RXREG; //受信データ読み込み
//
// ここに処理の本体
//
IFS0bits.U1RXIF = 0; //受信割り込みフラグ解除
}
現在の装置では、パソコンからデータストリームの送信が最初に始まり、その後、試作機械が立ち上がります。つまり、試作機械が立ち上がった時には、すでにパソコンからのデータが送り込まれていることになります。
いろいろ調べていくと、試作機械を先に立ち上げて、その後にパソコンからのデータストリームの送信を開始すると問題ないことがわかりました。試作機械は立ち上げ時に、シリアル受信をイネーブルにした後、100msほど初期化処理をした後に、受信割り込みを許可しています。どうもこの時差に問題があるように思えます。
色々やってみた結果、次のようなメカニズムで、受信割り込みが掛からなくなってしまうのが原因のようです。
シリアル受信をON
↓
初期化中に5バイト以上のシリアルデータが入ってきて、受信バッファがオーバーフロー
↓
シリアル割り込みを許可
↓
受信バッファがオーバーフローしているので、受信割り込みがかからない
PIC24Fはシリアル受信バッファとして4バイトのFIFOを持っていますが、これがオーバーフローすると、なんと受信割り込みが掛からなくなる仕様になっているようです。対策としては、シリアル受信をONにするタイミングを初期化処理後にもってくるのが一番簡単ですが、これだと、なんらかの理由でバッファがあふれてしまうと、やっぱりハングアップしてしまいますから、割り込みハンドラのなかできちんと対応することにしました。
新しいハンドラはこうなりました。
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
unsigned char i;
i = U1RXREG; //受信データ読み込み
//
// ここに処理の本体
//
//受信バッファフルへの対応(コレをしないと受信割り込みがかからなくなる)
if(U1STAbits.OERR) U1STAbits.OERR = 0;
IFS0bits.U1RXIF = 0; //受信割り込みフラグ解除
}
割り込みフラグを解除する前に、バッファオーバーフローエラーが出ていたら、それをリセット(受信データは全て破棄)する処理を挿入し、次の受信でちゃんと割り込みが掛かるようにしています。
« 【昔語り4】信越電機商会の頃−2 | トップページ | catkin超入門(その1)・ざっくり理解する »
「花岡ちゃんのウィークエンド」カテゴリの記事
- レーザー距離センサVL53L0Xを複数使うには(2022.05.01)
- 【訂正!】PIC24Fでレーザー距離センサVL53L0Xを使う(2022.04.13)
- PIC24Fでレーザー距離センサVL53L0Xを使う(おしまい)(2022.04.14)
- PIC24Fでレーザー距離センサVL53L0Xを使う(その3)(2022.04.13)
- PIC24Fでレーザー距離センサVL53L0Xを使う(その2)(2022.04.12)
コメント