こんにちは。KKと申します。
以前RL78でのCAN FIFO実装や2出力パルスセンサの検知方法にご協力いただきました。
ご指導いただいた方々その節は大変お世話になりました。
そのRL78についてご質問なのですが、
実車で試験中にどうやらCANの受信ができなくなる場合があるようです。
机上でCANバスにIDを20ヶほど流してみても特に症状は発生しませんでした。
受けるIDは20ヶほどで受信間隔は20ms毎のものが多いです。
送信側は約100ms周期で6ヶほどのCANを送信しています。
CANを送受信しながら入力パルス測定ポートにてパルス信号を車速データに変換しています。
パルスの範囲は300μs~200msほどになります。
現在はCANの受信とパルス間隔測定の割り込みレベルを上げ、カウントダウンタイマやAD変換の割り込みレベルを下げて、
多重割り込みを許可しているなど自分なりに原因を考えて対策してみているのですが、実機で操作中に発生しているようです。
デバッガーを接続した状態では走行操作などができないため、原因究明にいたっておりません。
なにか考えられることがあれば教えていただけないでしょうか?
tf様
毎度毎度のことながらご回答いただき、ありがとうございます。
ご認識の通りF13/14を使用しています。
仰られているように、現在は1メッセージ毎に割り込みをしているような状況なので、
ある程度バッファにためてから処理するほうが良いかもしれません。
初心者なのでうまく処理が出来るか分かりませんが…
また、一度FIFOあふれが生じるともうCANは受信できないのでしょうか?
2秒以上CANを受信できないとエラーで落とすようにしているのですが、エラーを検出してしまっている状況です。
現象が発生している時にCANのバス上には正常にCANが流れていたので、
受信側の問題だと推察しています。
現状のフローは以下のようにしています。
1メッセージ受信毎に割り込み処理で配列にデータを取り込むようにしています。
void caninit(void) //CAN通信初期設定{ DI(); //割り込み禁止 PM1.0 = 0; P1.0 = 1; PM1.1 = 1; CAN0EN = 1; //CANモジュールイネーブル(fclk) while (GSTS & (1<<3)) //CAN用RAMクリア完了確認(GRAMINIT=0) {;} GCTRL = 0x0001; //グローバルリセットモードへ(GSLPR=0) wait(); while (!(GSTS & (1<<0))) //遷移待ち(GRSTSTS==1) {;} C0CTRL = 0x0001; //チャネルリセットモードへ(CSLPR=0) wait(); GRWCR = 0x0001; //RPAGE=1 GCFGH = 0x0000; //タイムスタンプ/ミラー機能/DLCフィルタ/送信優先順位 GCFGL = 0x0301; //インターバルタイマプリスケーラー(FIFO時のみ) C0CFGH = 0x012F; //SJW:2Tq/TSEG2:3Tq/TSEG1:16Tq C0CFGL = 0x0001; //fCAN / ((BPR + 1) * 1ビットタイムのTq数) //250Kbps=10000KHz/((BRP+1)*20Tq) /************************************/ /* CAN受信ルール設定 */ /************************************/ GAFLCFG = CAN_RX_RULE; /*チャネル0受信ルール数設定(r_cg_userdefine.h)*/ GERFLL = 0x0004; GRWCR = 0; /*受信ルール・アクセス用にウインドウ0に切り替え*//*受信ルール1(7ED)*/ GAFLIDL0 = 0x07ED; /*受信ルールのID設定(下位バイト)*/ GAFLIDH0 = 0x0000; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML0 = 0xFFFF; /*IDビット(下位バイト)を比較する*/ GAFLMH0 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL0 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH0 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール2(0CFDD7XX)*/ GAFLIDL1 = 0xD700; /*受信ルールのID設定(下位バイト)*/ GAFLIDH1 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML1 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH1 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL1 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH1 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/
/*受信ルール3(0CFDA9XX)*/ GAFLIDL2 = 0xA900; /*受信ルールのID設定(下位バイト)*/ GAFLIDH2 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML2 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH2 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL2 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH2 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/
/*受信ルール4(0CFDD8XX)*/ GAFLIDL3 = 0xD800; /*受信ルールのID設定(下位バイト)*/ GAFLIDH3 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML3 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH3 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL3 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH3 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール5(0CFDD9XX)*/ GAFLIDL4 = 0xD900; /*受信ルールのID設定(下位バイト)*/ GAFLIDH4 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML4 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH4 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL4 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH4 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール6(0CF004XX)*/ GAFLIDL5 = 0x0400; /*受信ルールのID設定(下位バイト)*/ GAFLIDH5 = 0x8CF0; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML5 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH5 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL5 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH5 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール7(0CFDDBXX)*/ GAFLIDL6 = 0xDB00; /*受信ルールのID設定(下位バイト)*/ GAFLIDH6 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML6 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH6 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL6 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH6 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール8(0CFDDAXX)*/ GAFLIDL7 = 0xDA00; /*受信ルールのID設定(下位バイト)*/ GAFLIDH7 = 0x8CFD; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)*/ GAFLML7 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH7 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL7 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH7 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール9(18A600XX)*/ GAFLIDL8 = 0x0000; /*受信ルールのID設定(下位バイト)=全受信なのでALL0*/ GAFLIDH8 = 0x98A6; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)=18A7を指定*/ GAFLML8 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH8 = 0xFFFF; /*IDEビットを比較する RTRビットを比較する IDビット(上位バイト)を比較する*/ GAFLPL8 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH8 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール10(18A700XX)*/ GAFLIDL9 = 0x0000; /*受信ルールのID設定(下位バイト)=全受信なのでALL0*/ GAFLIDH9 = 0x98A7; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)=18A7を指定*/ GAFLML9 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH9 = 0xFFFF; /*IDEビットを比較しない RTRビットを比較しない IDビット(上位バイト)を比較しない*/ GAFLPL9 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH9 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ /*受信ルール11(18FED9XX)*/ GAFLIDL10 = 0xD900; /*受信ルールのID設定(下位バイト)=全受信なのでALL0*/ GAFLIDH10 = 0x98FE; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)=18A7を指定*/ GAFLML10 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH10 = 0xFFFF; /*IDEビットを比較しない RTRビットを比較しない IDビット(上位バイト)を比較しない*/ GAFLPL10 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH10 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/
/*受信ルール12(0CF013XX)*/ GAFLIDL11 = 0x1300; /*受信ルールのID設定(下位バイト)=全受信なのでALL0*/ GAFLIDH11 = 0x8CF0; /*IDE=拡張ID RTR=データ・フレーム 受信ルール対象メッセージ=他ノードからの受信時 受信ルールID設定(上位バイト)=18A7を指定*/ GAFLML11 = 0xFF00; /*ソースアドレス(下位2バイト)を比較しない*/ GAFLMH11 = 0xFFFF; /*IDEビットを比較しない RTRビットを比較しない IDビット(上位バイト)を比較しない*/ GAFLPL11 = 0x0001; /*受信バッファを使用しない 受信バッファ番号=0 CAN0送受信FIFOバッファを選択しない 受信FIFOバッファ0を使用する*/ GAFLPH11 = 0; /*DLCチェックしない 受信ルール・ラベル情報なし*/ GRWCR = 1; /*受信ルール・アクセス用にウインドウ1に切り替え*/
/***************************************/ /* 受信FIFOバッファの設定 */ /***************************************/ RMNB = 0; //受信バッファは使用しないため、0をセット(リプロ用で受信バッファを使っているのでここでもう一度使用しないことをレジスタにセットおかないとおかしな挙動になった) RFCC0 = 0x1102; /*1メッセージ受信完了毎に受信FIFO割り込みを発生する。*/ CANGRFRPR0 = 0; //CAN送信割込プライオリティ設定 CANGRFRPR1 = 0; //01:レベル1 CANGRFRMK = 0; //CANグローバル受信割込マスクフラグ 0:許可 /***************************************/ /* 送信バッファの設定 */ /***************************************/ //送信バッファ設定 TMIEC = 0x000F; //CAN0送信バッファ0~3の割込み許可 C0CTRH |= 0x0080; //ERRD=1:エラー全表示 CAN0TRMMK = 0; //CAN送信割込マスクフラグ 0:許可 CAN0TRMPR0 = 0; //CAN送信割込プライオリティ設定 CAN0TRMPR1 = 1; //10:レベル2 GCTRL &= 0xFFFC; //グローバル動作モードへ wait(); while (GSTS & (1<<0)) //遷移待ち(GRSTSTS==0) {;} RFCC0 |= 0x0001; /*受信FIFOバッファの許可*/ C0CTRL &= 0xFFFC; //チャネル通信モードへ(CSLPR=0) //wait(); while (C0STSL & (1<<0)) //遷移待ち(CRSTSTS==0) {;} //C0CTRL |= 0x0008; //RTBO=1:バスオフ強制復帰させる TXBOX[0] = 1; //送信バッファ0空き設定 TXBOX[1] = 1; //送信バッファ1空き設定 TXBOX[2] = 1; //送信バッファ2空き設定 TXBOX[3] = 1; //送信バッファ3空き設定 T1ms_H = CAN_RX_CLEAR1; //受信周期クリアタイマセット T1ms_I = CAN_RX_CLEAR2; //受信周期クリアタイマセット T1ms_J = CAN_RX_CLEAR3; //受信周期クリアタイマセット T1ms_K = CAN_RX_CLEAR4; //受信周期クリアタイマセット T1ms_L = CAN_RX_CLEAR5; //受信周期クリアタイマセット T1ms_M = CAN_RX_CLEAR6; //受信周期クリアタイマセット T1ms_N = CAN_RX_CLEAR7; //受信周期クリアタイマセット T1ms_O = CAN_RX_CLEAR8; //受信周期クリアタイマセット T1ms_P = CAN_RX_CLEAR9; //受信周期クリアタイマセット T1ms_Q = CAN_RX_CLEAR10; //受信周期クリアタイマセット T1ms_R = CAN_RX_CLEAR11; //受信周期クリアタイマセット T1ms_S = CAN_RX_CLEAR12; //受信周期クリアタイマセット T1ms_T = CAN_RX_CLEAR13; //受信周期クリアタイマセット T1ms_U = CAN_RX_CLEAR14; //受信周期クリアタイマセット T1ms_V = CAN_RX_CLEAR15; //受信周期クリアタイマセット T1ms_W = CAN_RX_CLEAR16; //受信周期クリアタイマセット EI(); //割り込み許可}
__interrupt void CanFIFORcvInterrupt(void) //受信完了割り込み{ DI(); //割り込み 禁止 RFSTS0 &= 0xFFF7; //受信FIFO0メッセージロストクリア、割り込み要求クリア RX_CANID_0 =(((unsigned long)RFIDH0)<<16); RX_CANID_0 =RX_CANID_0+RFIDL0; RX_CANID_0 &= 0x1fffffff; //CANIDの振り分け 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_RULE2: RX_DATA_DT1[2] = RFDF00 & 0x00FF; RX_DATA_DT2[2] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[2] = RFDF10 & 0x00FF; RX_DATA_DT4[2] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[2] = RFDF20 & 0x00FF; RX_DATA_DT6[2] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[2] = RFDF30 & 0x00FF; RX_DATA_DT8[2] = (RFDF30 & 0xFF00)>>8; T1ms_I = CAN_RX_CLEAR2; 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; case CAN_RX_RULE4: RX_DATA_DT1[4] = RFDF00 & 0x00FF; RX_DATA_DT2[4] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[4] = RFDF10 & 0x00FF; RX_DATA_DT4[4] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[4] = RFDF20 & 0x00FF; RX_DATA_DT6[4] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[4] = RFDF30 & 0x00FF; RX_DATA_DT8[4] = (RFDF30 & 0xFF00)>>8; T1ms_K = CAN_RX_CLEAR4; break; case CAN_RX_RULE5: RX_DATA_DT1[5] = RFDF00 & 0x00FF; RX_DATA_DT2[5] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[5] = RFDF10 & 0x00FF; RX_DATA_DT4[5] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[5] = RFDF20 & 0x00FF; RX_DATA_DT6[5] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[5] = RFDF30 & 0x00FF; RX_DATA_DT8[5] = (RFDF30 & 0xFF00)>>8; T1ms_L = CAN_RX_CLEAR5; break;
case CAN_RX_RULE6: RX_DATA_DT1[6] = RFDF00 & 0x00FF; RX_DATA_DT2[6] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[6] = RFDF10 & 0x00FF; RX_DATA_DT4[6] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[6] = RFDF20 & 0x00FF; RX_DATA_DT6[6] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[6] = RFDF30 & 0x00FF; RX_DATA_DT8[6] = (RFDF30 & 0xFF00)>>8; T1ms_M = CAN_RX_CLEAR6; break; case CAN_RX_RULE7: RX_DATA_DT1[7] = RFDF00 & 0x00FF; RX_DATA_DT2[7] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[7] = RFDF10 & 0x00FF; RX_DATA_DT4[7] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[7] = RFDF20 & 0x00FF; RX_DATA_DT6[7] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[7] = RFDF30 & 0x00FF; RX_DATA_DT8[7] = (RFDF30 & 0xFF00)>>8; T1ms_N = CAN_RX_CLEAR7; break; case CAN_RX_RULE8: RX_DATA_DT1[8] = RFDF00 & 0x00FF; RX_DATA_DT2[8] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[8] = RFDF10 & 0x00FF; RX_DATA_DT4[8] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[8] = RFDF20 & 0x00FF; RX_DATA_DT6[8] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[8] = RFDF30 & 0x00FF; RX_DATA_DT8[8] = (RFDF30 & 0xFF00)>>8; T1ms_O = CAN_RX_CLEAR8; break;
case CAN_RX_RULE9: RX_DATA_DT1[9] = RFDF00 & 0x00FF; RX_DATA_DT2[9] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[9] = RFDF10 & 0x00FF; RX_DATA_DT4[9] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[9] = RFDF20 & 0x00FF; RX_DATA_DT6[9] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[9] = RFDF30 & 0x00FF; RX_DATA_DT8[9] = (RFDF30 & 0xFF00)>>8; T1ms_P = CAN_RX_CLEAR9; break; case CAN_RX_RULE10: RX_DATA_DT1[10] = RFDF00 & 0x00FF; RX_DATA_DT2[10] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[10] = RFDF10 & 0x00FF; RX_DATA_DT4[10] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[10] = RFDF20 & 0x00FF; RX_DATA_DT6[10] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[10] = RFDF30 & 0x00FF; RX_DATA_DT8[10] = (RFDF30 & 0xFF00)>>8; T1ms_Q = CAN_RX_CLEAR10; break; case CAN_RX_RULE11: RX_DATA_DT1[11] = RFDF00 & 0x00FF; RX_DATA_DT2[11] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[11] = RFDF10 & 0x00FF; RX_DATA_DT4[11] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[11] = RFDF20 & 0x00FF; RX_DATA_DT6[11] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[11] = RFDF30 & 0x00FF; RX_DATA_DT8[11] = (RFDF30 & 0xFF00)>>8; T1ms_R = CAN_RX_CLEAR11; break; case CAN_RX_RULE12: RX_DATA_DT1[12] = RFDF00 & 0x00FF; RX_DATA_DT2[12] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[12] = RFDF10 & 0x00FF; RX_DATA_DT4[12] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[12] = RFDF20 & 0x00FF; RX_DATA_DT6[12] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[12] = RFDF30 & 0x00FF; RX_DATA_DT8[12] = (RFDF30 & 0xFF00)>>8; T1ms_S = CAN_RX_CLEAR12; break;
case CAN_RX_RULE13: RX_DATA_DT1[13] = RFDF00 & 0x00FF; RX_DATA_DT2[13] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[13] = RFDF10 & 0x00FF; RX_DATA_DT4[13] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[13] = RFDF20 & 0x00FF; RX_DATA_DT6[13] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[13] = RFDF30 & 0x00FF; RX_DATA_DT8[13] = (RFDF30 & 0xFF00)>>8; T1ms_T = CAN_RX_CLEAR13; break; case CAN_RX_RULE14: RX_DATA_DT1[14] = RFDF00 & 0x00FF; RX_DATA_DT2[14] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[14] = RFDF10 & 0x00FF; RX_DATA_DT4[14] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[14] = RFDF20 & 0x00FF; RX_DATA_DT6[14] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[14] = RFDF30 & 0x00FF; RX_DATA_DT8[14] = (RFDF30 & 0xFF00)>>8; T1ms_U = CAN_RX_CLEAR14; break;
case CAN_RX_RULE15: RX_DATA_DT1[15] = RFDF00 & 0x00FF; RX_DATA_DT2[15] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[15] = RFDF10 & 0x00FF; RX_DATA_DT4[15] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[15] = RFDF20 & 0x00FF; RX_DATA_DT6[15] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[15] = RFDF30 & 0x00FF; RX_DATA_DT8[15] = (RFDF30 & 0xFF00)>>8; T1ms_V = CAN_RX_CLEAR15; break; case CAN_RX_RULE16: RX_DATA_DT1[16] = RFDF00 & 0x00FF; RX_DATA_DT2[16] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[16] = RFDF10 & 0x00FF; RX_DATA_DT4[16] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[16] = RFDF20 & 0x00FF; RX_DATA_DT6[16] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[16] = RFDF30 & 0x00FF; RX_DATA_DT8[16] = (RFDF30 & 0xFF00)>>8; T1ms_W = CAN_RX_CLEAR16; break; case CAN_RX_RULE17: RX_DATA_DT1[17] = RFDF00 & 0x00FF; RX_DATA_DT2[17] = (RFDF00 & 0xFF00)>>8; RX_DATA_DT3[17] = RFDF10 & 0x00FF; RX_DATA_DT4[17] = (RFDF10 & 0xFF00)>>8; RX_DATA_DT5[17] = RFDF20 & 0x00FF; RX_DATA_DT6[17] = (RFDF20 & 0xFF00)>>8; RX_DATA_DT7[17] = RFDF30 & 0x00FF; RX_DATA_DT8[17] = (RFDF30 & 0xFF00)>>8; T1ms_AC = CAN_RX_CLEAR17; break;
} RFPCTR0 = 0x00ff; //受信FIFO0CAN受信FIFOポインタインクリメント EI(); //割り込み 許可}
KKさま
割り込み処理の問題である可能性が高いのかと考えてます。
>仰られているように、現在は1メッセージ毎に割り込みをしているような状況なので、
>ある程度バッファにためてから処理するほうが良いかもしれません。
1メッセージ受信毎に割り込みを掛けるか、複数メッセージ溜まったら割り込みを掛けるかは問題ではありません。(どちらでも良い)
ポイントは、割り込みを抜ける条件です。
・メッセージが到達 ★受信割り込み発生
・メッセージが到達
-----割り込みルーチン
・割り込みフラグを落とす
・メッセージの受信処理(1メッセージ)
-----割り込みルーチン(抜ける)
FIFOに複数のメッセージが溜まっているにも関わらずFIFOが空になっていないのに、受信割り込みを抜けてしまってます。
単純に
while(1)
{
受信処理
if(RFEMP==1) break;
}
の様な処理で良いかと思います。(割り込みルーチン内で全ての受信データを処理する)
>また、一度FIFOあふれが生じるともうCANは受信できないのでしょうか?
FIFOにデータが入らないだけで、FIFOに空きが出来るとFIFOに格納されます。(FIFOフルの状態で受信したデータは捨てられる。)
なお、もう1点注意点があり、RL78のCAN受信割り込みは、エッジ割り込みです。これがくせ者です。
(同系統のCANマクロを搭載した、RX26Tなどはレベル割り込みになっています。)
エッジ割り込みの掛かる条件は、グルーピングされている(CANマクロの)割り込みフラグが1つも立っていない状態から、割り込みフラグが立ったタイミングです。
(レベル割り込みであれば、フラグが立った状態で割り込みルーチン抜けても、直ぐに次の割り込みが掛かります。エッジの場合は、フラグが「変化」するタイミングが無ければなりません。)
割り込みフラグをクリアしない状態で、割り込みルーチンを抜けてしまうと、次にメッセージを受信した際に、割り込みには飛んできません。
現在起こっている現象は、(なんとなくですが)CANマクロ(=CANのハードウエア)は、正しくメッセージを受信していると思います。但し、(割り込みが入らないので)受信したメッセージを取りに行く人が居ない、という状態ではないかと思うのですが。
提示されているコード内では、FIFO(1)を使っていませんが、実はFIFO(1)が有効になっていないでしょうか。割り込みルーチン内では、FIFO(1)のフラグはクリアしていません。どこかで、FIFO(1)側のフラグが立った場合、FIFO(0)のデータを受信しても割り込みは掛かりません。(グルーピングされている割り込みフラグを全てクリアしなければならない、という条件です)(もしくは、何らかの条件下でフラグをクリアしないで割り込みルーチンを抜けてしまうケースがある)
>RFSTS0 &= 0xFFF7; //受信FIFO0メッセージロストクリア、割り込み要求クリア
メッセージロスト(b2)はクリアされていない?そもそも、メッセージロストを起こさない事が重要ですが。
(割り込み処理の問題であれば、単純にポーリングで受信データを処理するという手もあります。メイン関数内で空き時間を全て受信のポーリングに当てるとか、5ms位のタイマで受信処理を回すなど。基本的には、非同期で発生するイベントである受信は、割り込みで処理すべきだと思いますが。)