RL78 CANFIFOについて

こんにちは。KKと申します。

以前RL78でのCAN FIFO実装や2出力パルスセンサの検知方法にご協力いただきました。

ご指導いただいた方々その節は大変お世話になりました。

そのRL78についてご質問なのですが、

実車で試験中にどうやらCANの受信ができなくなる場合があるようです。

机上でCANバスにIDを20ヶほど流してみても特に症状は発生しませんでした。

受けるIDは20ヶほどで受信間隔は20ms毎のものが多いです。

送信側は約100ms周期で6ヶほどのCANを送信しています。

CANを送受信しながら入力パルス測定ポートにてパルス信号を車速データに変換しています。

パルスの範囲は300μs~200msほどになります。

現在はCANの受信とパルス間隔測定の割り込みレベルを上げ、カウントダウンタイマやAD変換の割り込みレベルを下げて、

多重割り込みを許可しているなど自分なりに原因を考えて対策してみているのですが、実機で操作中に発生しているようです。

デバッガーを接続した状態では走行操作などができないため、原因究明にいたっておりません。

なにか考えられることがあれば教えていただけないでしょうか?

  • お使いのマイコンは、F13/F14でしたでしょうか。

    FIFOを使うと、16メッセージまではメッセージを処理する受信割り込みが入らない状態でもメッセージを溜められるので、FIFOの段数を16に設定するのは有効かと思います。

    FIFOを使う前提で、受信割り込みが入るタイミングで、RFMLT(メッセージロストフラグ)を確認して、FIFOが溢れているのでメッセージを取りこぼすのか、FIFO溢れは生じていないかの切り分けは必要かと考えます。

    受信割り込みの際に、読み出し手順のフローはどのようにしていますでしょうか。RL78/F13,14 ハードウェアマニュアルの、18.11.2 FIFOの読み出し手順に処理フローが書かれていますが、

    FIFOの受信に関しては、(使用しているマイコンがRL78/F13,14であっても、あえて)RL78/F24のハードウェアマニュアル

    www.renesas.com/.../rl78f23-f24-users-manual-hardware-rev100

    に書かれている

    18.12.2 割り込み処理フロー

    を参照するのが、お勧めです。RL78のCAN受信割り込みは、上手く処理しないと、FIFOにデータを残したまま割り込みルーチンを抜けてしまう事があり(単なる考え抜けが原因ですが)、苦労した記憶があります。(ちょうどメッセージを処理しているタイミングで次のメッセージを受信した際などに、割り込みを抜ける条件が重要であると思います。)

  • 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位のタイマで受信処理を回すなど。基本的には、非同期で発生するイベントである受信は、割り込みで処理すべきだと思いますが。)

  • tf様

    ご丁寧にありがとうございます。

    ブレークをかけたRFCC1のレジスタは0x0000となっていたため、受信FIFOバッファ1は使用していないはずです。

    いっそのこと受信FIFOバッファ1も使用できるようにプログラムを変えてみようかと思います。

    一旦、ご教示いただいた内容+RL78/F23の割り込み処理フローを元に、割り込み処理を変更いたしました。

    このような感じでいいのでしょうか?

    __interrupt void CanFIFORcvInterrupt(void) //受信完了割り込み
    {
    DI(); //割り込み 禁止
    //受信FIFOバッファ0に割り込み要求
    if((RFISTS & 0x0001) == 1)
    {
    RFSTS0 &= 0xFFF3; //受信FIFO0メッセージロストクリア、割り込み要求クリア

    //受信バッファにデータがあるか?
    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_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_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;
    }
    RFPCTR0 = 0x00ff; //受信FIFO1CAN受信FIFOポインタインクリメント
    }

    }
    EI(); //割り込み 許可

    }

  • 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メッセージ毎の割り込みのため、どちらかしかフラグ立たないと思っていましたが、

    >どちらも立った状態で割り込みに入ることがあるのですね…

    フラグが立ってからフラグをクリアするまでの時間は割り込みで処理してもゼロにはなりませんので、想定としては両方立つという事は考えておかなければならないと思います。

  • tf様

    ご返答ありがとうございます。

    来週、机上にて動作確認してみたいと思います。

    詳しくアドバイスいただきありがとうございました!!

    打つ手がなくて、途方に暮れていたため、アドバイスいただいたおかげで、少し前に進めそうです。

    本当にありがとうございます!!

  • tf様

    本日、机上にてアドバイスいただいたプログラムにて動作確認してみましたが、うまくいきませんでした。

    100ms周期のCAN信号を500ms受信できないと受信データをクリアしているのですが、

    そのループに入っていることが確認されました。

    受信中の割り込みループが長すぎるのかCANも時たま送信を止めているような状況です。

    エミュレータでのデバッグ中にウォッチ式がちゃんと値を出したり”?”になったりしているのは、CPUに負荷がかかっているということでしょうか?

    こちらでも、アドバイスを元にプログラムを修正して試してみることにします。

  • 申し訳ございません。

    念のため、現在のプログラムを記載しておきます。

    __interrupt void CanFIFORcvInterrupt(void) //受信完了割り込み
    {
    DI(); //割り込み 禁止

    while(1)
    {
    //受信FIFOバッファ0、1とも割込要求が無い場合のみフローを抜ける
    if ((RFISTS & 0x03) == 0) break;

    //受信FIFOバッファ0に割り込み要求
    if((RFISTS & 0x0001) == 1)
    {
    RFSTS0 &= 0xFFF3; //受信FIFO0メッセージロストクリア、割り込み要求クリア

    //受信FIFOバッファ0にデータがあるか?
    while((RFSTS0 & 0x0001) == 0)
    {
    //CANIDの作成

    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;

    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;

    }
    RFPCTR0 = 0x00ff; //受信FIFO0CAN受信FIFOポインタインクリメント
    }

    }

    //受信FIFOバッファ1に割り込み要求
    if(((RFISTS & 0x0002)>>1) == 1)
    {
    RFSTS1 &= 0xFFF3; //受信FIFO0メッセージロストクリア、割り込み要求クリア

    //受信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;

    case CAN_RX_RULE11:
    RX_DATA_DT1[11] = RFDF01 & 0x00FF;
    RX_DATA_DT2[11] = (RFDF01 & 0xFF00)>>8;
    RX_DATA_DT3[11] = RFDF11 & 0x00FF;
    RX_DATA_DT4[11] = (RFDF11 & 0xFF00)>>8;
    RX_DATA_DT5[11] = RFDF21 & 0x00FF;
    RX_DATA_DT6[11] = (RFDF21 & 0xFF00)>>8;
    RX_DATA_DT7[11] = RFDF31 & 0x00FF;
    RX_DATA_DT8[11] = (RFDF31 & 0xFF00)>>8;
    T1ms_R = CAN_RX_CLEAR11;
    break;

    case CAN_RX_RULE13:
    RX_DATA_DT1[13] = RFDF01 & 0x00FF;
    RX_DATA_DT2[13] = (RFDF01 & 0xFF00)>>8;
    RX_DATA_DT3[13] = RFDF11 & 0x00FF;
    RX_DATA_DT4[13] = (RFDF11 & 0xFF00)>>8;
    RX_DATA_DT5[13] = RFDF21 & 0x00FF;
    RX_DATA_DT6[13] = (RFDF21 & 0xFF00)>>8;
    RX_DATA_DT7[13] = RFDF31 & 0x00FF;
    RX_DATA_DT8[13] = (RFDF31 & 0xFF00)>>8;
    T1ms_T = CAN_RX_CLEAR13;
    break;

    case CAN_RX_RULE14:
    RX_DATA_DT1[14] = RFDF01 & 0x00FF;
    RX_DATA_DT2[14] = (RFDF01 & 0xFF00)>>8;
    RX_DATA_DT3[14] = RFDF11 & 0x00FF;
    RX_DATA_DT4[14] = (RFDF11 & 0xFF00)>>8;
    RX_DATA_DT5[14] = RFDF21 & 0x00FF;
    RX_DATA_DT6[14] = (RFDF21 & 0xFF00)>>8;
    RX_DATA_DT7[14] = RFDF31 & 0x00FF;
    RX_DATA_DT8[14] = (RFDF31 & 0xFF00)>>8;
    T1ms_U = CAN_RX_CLEAR14;
    break;



    }
    RFPCTR1 = 0x00ff; //受信FIFO1CAN受信FIFOポインタインクリメント
    }

    }

    }

    EI(); //割り込み 許可

    }

  • tf様

    度々申し訳ございません。

    こちらのエミュレータから送信しているCAN信号のせいかもしれません。

    特定のCAN信号を受信した際にCANリプログラミングモードに入るようにしているのですが、

    そのモードに入ろうとしていたようです。

    その信号を送信しないようにするとCAN送信が正常周期になり、E1のデバッグ画面の?もなくなりました。

    確認不足で申し訳ございません。

    一度CANリプロも併せて確認し、不具合があれば、再度ご相談させていただきます。