こんにちは。KKと申します。
以前RL78でのCAN FIFO実装や2出力パルスセンサの検知方法にご協力いただきました。
ご指導いただいた方々その節は大変お世話になりました。
そのRL78についてご質問なのですが、
実車で試験中にどうやらCANの受信ができなくなる場合があるようです。
机上でCANバスにIDを20ヶほど流してみても特に症状は発生しませんでした。
受けるIDは20ヶほどで受信間隔は20ms毎のものが多いです。
送信側は約100ms周期で6ヶほどのCANを送信しています。
CANを送受信しながら入力パルス測定ポートにてパルス信号を車速データに変換しています。
パルスの範囲は300μs~200msほどになります。
現在はCANの受信とパルス間隔測定の割り込みレベルを上げ、カウントダウンタイマやAD変換の割り込みレベルを下げて、
多重割り込みを許可しているなど自分なりに原因を考えて対策してみているのですが、実機で操作中に発生しているようです。
デバッガーを接続した状態では走行操作などができないため、原因究明にいたっておりません。
なにか考えられることがあれば教えていただけないでしょうか?
tf様
続けての投稿申し訳ございません。
受信バッファ1の設定を有効にして割り込み処理を変更致しました。
机上では問題なく受信できているようです。
このような書き方で良いのでしょうか?
RF0IF/RF1IFは1メッセージ毎の割り込みのため、どちらかしかフラグ立たないと思っていましたが、
どちらも立った状態で割り込みに入ることがあるのですね…
==========================================
__interrupt void CanFIFORcvInterrupt(void) //受信完了割り込み{ DI(); //割り込み 禁止 //受信FIFOバッファ0に割り込み要求 if((RFISTS & 0x0001) == 1) { RFSTS0 &= 0xFFF3; //受信FIFO0メッセージロストクリア、割り込み要求クリア
//受信FIFOバッファ0にメッセージが残っているか? while((RFSTS0 & 0x0001) == 0) { RX_CANID_0 =(((unsigned long)RFIDH0)<<16); RX_CANID_0 =RX_CANID_0+RFIDL0; RX_CANID_0 &= 0x1fffffff; switch(RX_CANID_0) { case CAN_RX_RULE1: RX_DATA_DT1[1] = RFDF00 & 0x00FF; RX_DATA_DT2[1] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[1] = RFDF10 & 0x00FF; RX_DATA_DT4[1] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[1] = RFDF20 & 0x00FF; RX_DATA_DT6[1] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[1] = RFDF30 & 0x00FF; RX_DATA_DT8[1] = (RFDF30 & 0xFF00)>>8; //T1ms_H = CAN_RX_CLEAR1; break; case CAN_RX_RULE3: RX_DATA_DT1[3] = RFDF00 & 0x00FF; RX_DATA_DT2[3] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[3] = RFDF10 & 0x00FF; RX_DATA_DT4[3] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[3] = RFDF20 & 0x00FF; RX_DATA_DT6[3] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[3] = RFDF30 & 0x00FF; RX_DATA_DT8[3] = (RFDF30 & 0xFF00)>>8; T1ms_J = CAN_RX_CLEAR3; break; } RFPCTR0 = 0x00ff; //受信FIFO0CAN受信FIFOポインタインクリメント } }
//受信FIFOバッファ1に割り込み要求 if(((RFISTS & 0x0002)>>1) == 1) { RFSTS1 &= 0xFFF3; //受信FIFO1メッセージロストクリア、割り込み要求クリア
//受信FIFOバッファ1にメッセージが残っているか? while((RFSTS1 & 0x0001) == 0) { RX_CANID_1 =(((unsigned long)RFIDH1)<<16); RX_CANID_1 =RX_CANID_1+RFIDL1; RX_CANID_1 &= 0x1fffffff; switch(RX_CANID_1) { case CAN_RX_RULE2: RX_DATA_DT1[2] = RFDF01 & 0x00FF; RX_DATA_DT2[2] = (RFDF01 & 0xFF00)>>8; RX_DATA_DT3[2] = RFDF11 & 0x00FF; RX_DATA_DT4[2] = (RFDF11 & 0xFF00)>>8; RX_DATA_DT5[2] = RFDF21 & 0x00FF; RX_DATA_DT6[2] = (RFDF21 & 0xFF00)>>8; RX_DATA_DT7[2] = RFDF31 & 0x00FF; RX_DATA_DT8[2] = (RFDF31 & 0xFF00)>>8; T1ms_I = CAN_RX_CLEAR2; break; case CAN_RX_RULE9: RX_DATA_DT1[9] = RFDF01 & 0x00FF; RX_DATA_DT2[9] = (RFDF01 & 0xFF00)>>8; RX_DATA_DT3[9] = RFDF11 & 0x00FF; RX_DATA_DT4[9] = (RFDF11 & 0xFF00)>>8; RX_DATA_DT5[9] = RFDF21 & 0x00FF; RX_DATA_DT6[9] = (RFDF21 & 0xFF00)>>8; RX_DATA_DT7[9] = RFDF31 & 0x00FF; RX_DATA_DT8[9] = (RFDF31 & 0xFF00)>>8; T1ms_P = CAN_RX_CLEAR9; break; case CAN_RX_RULE10: RX_DATA_DT1[10] = RFDF01 & 0x00FF; RX_DATA_DT2[10] = (RFDF01 & 0xFF00)>>8; RX_DATA_DT3[10] = RFDF11 & 0x00FF; RX_DATA_DT4[10] = (RFDF11 & 0xFF00)>>8; RX_DATA_DT5[10] = RFDF21 & 0x00FF; RX_DATA_DT6[10] = (RFDF21 & 0xFF00)>>8; RX_DATA_DT7[10] = RFDF31 & 0x00FF; RX_DATA_DT8[10] = (RFDF31 & 0xFF00)>>8; T1ms_Q = CAN_RX_CLEAR10; break; } RFPCTR1 = 0x00ff; //受信FIFO1CAN受信FIFOポインタインクリメント } } EI(); //割り込み 許可
}
>このような感じでいいのでしょうか?
残念ながらNGです。
割り込み関数に入ってから(割り込みルーチン実行中に)、データがやってくる事が考えられていません。
F24のハードウェアマニュアル図18-46の(バッファ・エンプティ)Yesで左側から開始の部分に戻るルートがありません。
while(1)
{
if ((RFISTS & 0x03) == 0) break;
--
KK様が作成されているコード
上記の様にすべきかと考えます。割り込みが掛かる条件が、
(RFISTS.RF1F, RFISTS.RF0IF)
(0,0) → (1,0) 〇割り込みが掛かる
(0,0) → (0,1) 〇割り込みが掛かる
(0,1) → (1,1) ✕割り込みは掛からない
(1,0) → (1,1) ✕割り込みは掛からない
です。RFISTSのb0(RF0IF)とb1(RF1F)が(0,0)となっているタイミングが必ず必要です。
(1,1)で割り込みルーチンに飛んでくる
(0,1)最初の方でRFIFO(0)の処理を行うのでこのように変化
(0,1)RFFIFO(0)読み出し処理
(1,1)RFFIFO(1)のフラグクリア前に再度RFFIFO(0)にデータが来る
(1,0)RFFIFO(1)読み出し処理
(1,0)のまま割り込みルーチンを抜ける
→次にデータが来ても二度と割り込みルーチンには来ない
→(0,0)が割り込みルーチンを抜ける条件でなければならない
>RF0IF/RF1IFは1メッセージ毎の割り込みのため、どちらかしかフラグ立たないと思っていましたが、
>どちらも立った状態で割り込みに入ることがあるのですね…
フラグが立ってからフラグをクリアするまでの時間は割り込みで処理してもゼロにはなりませんので、想定としては両方立つという事は考えておかなければならないと思います。