お世話になっております。
/*参考
*
* CAN/LIN/UART/PORT Checker for RL78/F14
* Target: QB-R5F10PPJ-TB (RL78/F14, 100pin, 256KB ROM, 20KB RAM)
* Author: Yasushi Tanaka
/
移植RL78/F13 評価ボード(QB-R5F10BMG-TB)
開発環境: e2-studio7.4
toolChain: Renesas CC-RL C
デバッグツール: e2-Lite
/* CANの割込(vector.c)の設定 */
#pragma interrupt intcan0err_isr(vect=INTCAN0ERR, bank=RB1)
#pragma interrupt intcan0trm_isr(vect=INTCAN0TRM, bank=RB1)
#pragma interrupt intcangrfr_isr(vect=INTCANGRFR, bank=RB1)
#pragma interrupt intcangerr_isr(vect=INTCANGERR, bank=RB1)
現象は、
送信割り込みを使ってCAN送信しようとしますが、
CAN0のスロットにデータは入っても(確認済)、割込のルーチンintcan0trm_isr()は呼び出されません。
下記のように割り込みが許可されていて問題なさそうに見えますが。
/* CAN0送信割り込みを許可 */
MK2H &= (u1)(~RL78F_MK2H_CAN0TRMMK);
考えてられる原因は何でしょうか、ヒントをいただければ助かります。
よろしくお願いします。
(ちなみに割り込み使わずにCAN APIを使って通信は確認できています)
ikkiさん NAKAです。 午前中は出張でした!! 特別! 出血サービス! 下のソースをMAIN.cのファイルに張り付けてください。他は一切必要ないです。 QB-R5F10BMG-TBボードは持ち合わせがないので、北斗電子のF14で作りました。 なのでポートの設定部分だけをP72,P73からP10,P11にリダクションせずに使ってください。 送信完了すると割込み関数CAN_TX_INTの中のc_TXがカウントアップしましすし、受信するとc_RXがカウントアップします。 タイミングもあえてタイマーなど使わずfor文で回してあります。 もぉ~~ これ以上簡単に出来ない!!! /***********************************************************************/ /* */ /* FILE :Main.c */ /* DATE :2019/09/24 */ /* DESCRIPTION :Main Program */ /* CPU TYPE :RL78_F14 */ /* */ /* NOTE:THIS IS A TYPICAL EXAMPLE. */ /* */ /***********************************************************************/ #include "iodefine.h" /************************************************************************/ /* 割り込みベクタ設定 */ /************************************************************************/ void __near CAN_TX_INT(void); #pragma interrupt CAN_TX_INT(vect=INTCAN0TRM) //CAN送信割り込み宣言 void __near CAN_RX_INT(void); #pragma interrupt CAN_RX_INT(vect=INTCANGRFR) //CAN受信割り込み宣言 /************************************************************************/ /* 関数プロトタイプ宣言 外部関数 */ /************************************************************************/ void main(void); /************************************************************************/ /* グローバル変数定義 */ /************************************************************************/ unsigned char c_TX; unsigned char c_RX; unsigned short CAN_SID; unsigned short CAN_DLC; unsigned char CAN_DATA[8]; /************************************************************************/ /************************************************************************/ /* メインルーチン */ /************************************************************************/ /************************************************************************/ void main(void) { unsigned long i; __DI(); //割り込み 禁止 //************ オンチップオシレータ32MHzの初期化 **************************/ CMC = 0x00; //X1発振モード外部クロック入力モードは辞める MSTOP = 1; //X1発振回路 停止 MCM0 = 0; //メインクロックに高速オンチップオシレータを選択 XTSTOP = 1; //XT1(サブ)発振回路 停止 SELLOSC = 1; //低速オンチップオシレータ 起動 CSS = 0; //CPU/周辺をメイン/PLLクロックを選択 MDIV = 0; //fMP/1=32MHz? RTCCL = 0xC2; //RTCのクロック選択 適当? TRD_CKSEL = 0; //TRD用クロックの選択 = 32MHz /***************** CANの初期化 **************************/ //CANポートの設定 //P72とP73使用時 PIOR4 = 0x40; //P72.P73をCAN用CTX.CRXに割り当てする 周辺I/Oリダイレクションレジスタ設定 P7 |= 0x04; //P72(CTXD) PM7 &= 0xFB; //CTXD0(P72pin)を"0":出力に PMC7 &= 0xFB; //PMCの設定CAN使用時は"0" PM7 |= 0x08; //CRXD0(P73pin)を"1":入力に PMC7 &= 0xF7; //PMCの設定CAN使用時は"0" //P10とP11使用時 /* P1 |= 0x01; //P10(TXD)34pin PM1 &= 0xFE; //CTXD0(P10_34pin)を"0":出力に PM1 |= 0x02; //CRXD0(P35pin)を"1":入力に */ //高速オンチップオシレータ32MHz使用 CAN0EN = 1; //CANモジュールへクロックを供給 __nop(); while((GSTS&0x0008)!=0){} //CAN用RAMクリアを待つ GRAMINITフラグが"0":RAMクリアになったか? GCTRL &= 0xFFFB; //GSLPR=0 グローバルリセットモードに変遷 (GMDC=01) while((GSTS&0x0004)!=0){} //CANグローバルリセットモード変遷を確認 C0CTRL &= 0xFFFB; //CSLPR=0 チャンネルストップモード⇒チャンネルリセットモードに変遷 while((C0STSL&0x0004)!=0){} //CANチャンネルリセットモードに変遷を確認 GCFGL = 0x0000; //DCS=0:fCAN=fCLK/2=16MHzに設定 DLC配置禁止とは? C0CFGH = 0x0049; //SJW=1 TSEG2=5 TSEG1=10 に設定 ボーレートプリスケラ(1)分周無しの場合 C0CFGL = 0x0001; //C0CFGL+1 = 2で分周(16MHz/2 =8MHz)=ボーレートプリスケラ = fCAN_8Mhz/((0+1)×16Tq)= 500Kbps //受信ルール設定 GAFLCFG = 0x0001; //受信ルール数設定 0:ルール無し? or 1:受信バッファを使用する? GRWCR = 0x0000; //受信ルール変更準備 GAFLIDL0 = 0x0000; //受信ルール① ID設定 比較しない? GAFLIDH0 = 0x0000; //受信ルール② 標準ID・データフレーム GAFLML0 = 0x0000; //受信ルール③ 対応IDをマスクしない "0000"なので全bitチェックしないので全て受信する。 GAFLMH0 = 0xE000; //受信ルール④ 標準IDか?とデータフレームか?他のCANノードが送信? を比較する。 GAFLPL0 = 0x0001; //受信ルール⑤ 受信FIFOバッファ0(GAFLFDP0)をのみ選択する GAFLPH0 = 0x0000; //受信ルール⑥ DLCチェックしない GRWCR = 0x0001; //受信ルール変更完了 //受信バッファ設定 RFCC0 = 0xF302; //RFIGCV(001:1個でFIFO割込)、RFIM(1:1メッセージ受信毎)、RFDC(16)、RFIE(1:受信FIFO割込許可)、 //送信バッファ設定 TMIEC = 0x0001; //CAN0送信バッファ0の割込み許可 バッファ1~3は未使用 C0CTRL |= 0x0008; //RTBO=1:バスオフ強制復帰させる ? //割込設定 割り込み名称:INTCANGRFR(グローバルFIFO受信割込み) INTCAN0TRM(チャンネル送信割込み) CANGRFRPR0 = 0; //CAN受信割込プライオリティ設定 CANGRFRPR1 = 1; //01:レベル2 CANGRFRMK = 0; //CAN受信割込マスクフラグ 0:許可 CAN0TRMPR0 = 0; //CAN送信割込プライオリティ設定 CAN0TRMPR1 = 1; //01:レベル2 CAN0TRMMK = 0; //CAN送信割込マスクフラグ 0:許可 GCTRL &= 0xFFFC; //GSLPR=0 グローバルリセットモード⇒グローバル動作モードに変遷 (GMDC=00) while((GSTS&0x0001)!=0){} //CANグローバル動作モード変遷を確認 RFCC0 |= 0x0001; //RFE(1:FIFOバッファ使用許可) 注)グローバル動作モードに変更するp1264 C0CTRL &= 0xFFFC; //CSLPR=0 チャンネルリセットモード⇒CANチャンネル通信モードに変遷 (CHMDC=00) while((C0STSL&0x0001)!=0){} ///CANチャンネル通信モードに変遷を確認 __nop(); __EI(); //割り込み 許可 while (1) { for(i=0;i<0x01FFFFF;i++) { __nop(); } //CANの定期送信テスト TMSTS0 &= 0xF9; //送信結果フラグクリア while((TMSTS0 & 0x06)!=0){} //確認 TMIDH0 = 0x0000; //標準ID データフレーム 履歴をバッファしない TMIDL0 = 0x0123; //送信IDバッファ0にIDをSET! TMPTR0 = 0x8000; //送信DLCバッファ0にDLCをSET! TMDF00L = 0x01; //送信DATAバッファ0にDATAをSET! TMDF00H = 0x02; //送信DATAバッファ0にDATAをSET! TMDF10L = 0x03; //送信DATAバッファ0にDATAをSET! TMDF10H = 0x04; //送信DATAバッファ0にDATAをSET! TMDF20L = 0x05; //送信DATAバッファ0にDATAをSET! TMDF20H = 0x06; //送信DATAバッファ0にDATAをSET! TMDF30L = 0x07; //送信DATAバッファ0にDATAをSET! TMDF30H = c_TX; //送信DATAバッファ0にDATAをSET! TMC0 |= 0x01; //送信要求 TMTRを"1"に } } /************************************************************************/ /* CAN送信完了割り込み関数 */ /************************************************************************/ void __near CAN_TX_INT(void) { c_TX++; } /************************************************************************/ /* CAN受信完了割り込み関数 */ /************************************************************************/ void __near CAN_RX_INT(void) { __DI(); //割り込み 禁止 RFSTS0 &= 0xFFF7; //RFIF受信FIFO割り込み要求クリア CAN_SID = RFIDL0; //IDを格納 CAN_DLC = RFPTR0 >> 12; //DLCを格納 CAN_DATA[0] = RFDF00L; //Data0を格納 CAN_DATA[1] = RFDF00H; //Data1を格納 CAN_DATA[2] = RFDF10L; //Data2を格納 CAN_DATA[3] = RFDF10H; //Data3を格納 CAN_DATA[4] = RFDF20L; //Data4を格納 CAN_DATA[5] = RFDF20H; //Data5を格納 CAN_DATA[6] = RFDF30L; //Data6を格納 CAN_DATA[7] = RFDF30H; //Data7を格納 RFPCTR0 = 0x00FF; //バッファポインターインクリメント __EI(); //割り込み 許可 c_RX++; }
ikkiさん NAKAです。 ごめんなさい、見逃してました!! チョコ先生からアドバイスがあったので、実践しているのですが、NAKAはコード生成は初期設定を参考に覗くだけで、関数は自分で作るようにしています。新規のプロジェクトを作って、MAINに貼るだけで、CAN通信に必要な設定は全てされているため、他は必要ないはずです。僕の北斗電子のF14ボードで一度たりともCANエラーはでたことがないので、多分大丈夫だと思います。
他の機能を使う時のクロックの設定が違ってたりしないでしょうか?以前マサさんのコードを参考にされてた時はオンチップオシレータの設定を16MHzのようでしたが、上のサンプルではオンチップオシレータ32MHzですけど良かったでしょうか?
ikkiさん NAKAです。
CANでトラブった経験がそんなに無いので、アドバイスが難しいかも?ですが終端処理とかしっかりしてますか?
一応、朝から北斗電子のF14ボード引っ張り出し、プロジェクトにぺたんと貼って動かしてみましたが、やはりエラーは出ませんし、
データに 「TMDF30H = c_TX; //送信DATAバッファ0にDATAをSET!」とかしてモニタしても当然、カウンタ値は抜けませんし......
ハードなのかなぁ~???
唯一
極まれにエラーフレームが発生する!という事例で調査したことがあって
原因と思われるのが、
基板実装屋さんが電源のコンデンサを指示したものと間違えてESRの高いものが実装されてたことがありました。
電源ICのカタログでは
のようにESR3Ω以上だと安定領域から外れる恐れがあり、ついていたアルミ電解は
のようでさらに温度特性で低温になるとさらに悪化するらしいです。
実際の波形が
このように負荷電流の変化がトランジェント応答に現れちゃってる感じになったことがあります。
これでも、CANの規格は十分に満足しており、実機での評価中は2日間一度もエラーフレームは発生しませんでした。
極低温の環境だと可能性があるのかもしれません。
そして、当初に設計したコンデンサを実装したところ
このように電源も波形も安定して、その後そういった報告は無いと聞いております。
もう一度確認ですが、先のサンプルに一切手を加えない状態でエラーがあるのでしょうか?
だとやっぱり、ハード?