CAN通信 初心者です。助けてください !

はじめまして、『そろそろ』と申します。

 

NAKAさんのサンプルプログラムでCAN通信しようとしていますがうまくいっていません。

有識者方々にアドバイスが頂けると助かります。

 

NAKAさんプログラムからの主な変更点は、★部分です。

 (1) CAN0MCKE = 1;     //CANモジュールへX1クロックを供給 ★

⇒ CAN0MCKE = 0

 (2) GCFGL = 0x0010; //DCS=1:fCAN=X1=8MHzに設定 DLC配置禁止とは?★

⇒ GCFGL = 0x0000

(3) C0CFGL = 0x0000; //C0CFGL+1で分周=ボーレートプリスケラ = fCAN_8Mhz/((0+1)×16Tq)= 500Kbps★

⇒ C0CFGL = 0x0002

 

※(1)~(3)の設定理由は、X1クロックでなくてCPU/周辺ハードウェアクロック(fCLK)を使用しています。

 fCLKが24MHzなのでfCAN=(24MHz/2)((2+1)×16Tq) = 250Kbpsになります。

 

■■質問1■■

本来は、500Kbpsにしたかったのですが、設定可能でしょうか?

 

■■質問2■■

CANUSBというツールを使ってPCからRL78にCAN通信しようとしています。

 

CANUSBについてはこちら

http://www.compass-lab.com/CAN_Tool/CANUSB.htm

http://www.can232.com/?page_id=75

http://www.h5.dion.ne.jp/~enarin/page043.html

 

PCからRL78に

11bit標準CANフォーマット CANフレーム送信

をしていますが、RL78のRX, TXの信号がオシロでパタパタしません。

 

PCから通信できないのはCANUSBがおかしいかもしれないので

試しに

   TMDF00L = CAN_RX_ID >> 8;     //受信IDを送信

   TMDF00H = (unsigned char)(CAN_RX_ID & 0x00FF);

   TMDF10L = CAN_RX_DLC;         //受信DLCを送信

   TMDF10H = CAN_RX_DATA[0];   //受信DATA0を送信

   TMDF20L = CAN_RX_DATA[1];   //受信DATA1を送信

   TMDF20H = CAN_RX_DATA[2];   //受信DATA2を送信

   TMDF30L = CAN_RX_DATA[3];   //受信DATA3を送信

   TMDF30H = 0x12;                   //固定データを送信

の部分を

   TMDF00L = 0x00;

   TMDF00H = 0x01;

   TMDF10L = 0x10;

   TMDF10H = 0x11;

   TMDF20L = 0x20;

   TMDF20H = 0x21;

   TMDF30L = 0x30;

   TMDF30H = 0x31;

に変更したところ

   RFDF00L;

   RFDF00H;

   RFDF10L;

   RFDF10H;

   RFDF20L;

   RFDF20H;

   RFDF30L;

   RFDF30H;

については0x00のままで変化はなく

   RFDF01Lが0x00;

   RFDF01Hが0x01;

   RFDF11Lが0x10;

   RFDF11Hが0x11;

   RFDF21Lが0x20;

   RFDF21Hが0x21;

   RFDF31Lが0x30;

   RFDF31Hが0x31;

となっています。

この挙動は正しいのでしょうか?

/////////////////////////////////

下記 NAKAさん サンプルプログラム

http://japan.renesasrulz.com/cafe_rene/f/forum18/3353/rl78-f13-14can

/*************************************************************************
// 関数名 : fn_Init_CAN(void)
// 動作 : CAN通信の初期化
// 引数 :
// 作成 : NAKA  16.02.08
// 備考 :
// ***********************************************************************/
void fn_Init_CAN(void)
{
 //CANポートの設定
 PIOR4 = 0x40;        //周辺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"

 //外付け水晶振動子 8MHz使用時----------
 CAN0EN = 1;          //CANモジュールへクロックを供給
 CAN0MCKE = 1;     //CANモジュールへX1クロックを供給 ★
    __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 = 0x0010;                //DCS=1:fCAN=X1=8MHzに設定 DLC配置禁止とは?★
 C0CFGH = 0x0049;             //SJW=1 TSEG2=5 TSEG1=10  に設定 ボーレートプリスケラ(1)分周無しの場合
 C0CFGL = 0x0000;             //C0CFGL+1で分周=ボーレートプリスケラ = fCAN_8Mhz/((0+1)×16Tq)= 500Kbps★
 
 //受信ルール設定
 GAFLCFG = 0x0006;    //受信ルール数設定 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;      //
 C0CTRL |= 0x0008;    //RTBO=1:バスオフ強制復帰させる ?
 
 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();
}


//********************************************************************
//*************メインルーチン*****************************************
//********************************************************************
unsigned char  CAN_RX_DATA[8];
unsigned char  CAN_RX_DLC;
unsigned short  CAN_RX_ID;
unsigned short  i;

while (1)
{
 if(f_TRD0 != 0)                   //1ms毎のイベント(TRD0-コンペアマッチ)
 {
  f_TRD0 = 0;
   i++;
   if(i >= 1000)                   //1s毎のタイミング
   {
    i=0;
          
    //★★★CANの送信(1秒毎の定期送信)★★★★★★★★★★★★★★★
    TMSTS0 &= 0xF9;              //送信結果フラグクリア
    while((TMSTS0 & 0x06)!=0){}  //確認
    TMIDH0 = 0x0000;             //標準ID データフレーム 履歴をバッファしない
    // IDセット
    TMIDL0 = 0x0123;             //送信IDバッファ0にIDをSET!
    // データ長セット
    TMPTR0 = 0x8000;             //送信DLCバッファ0にDLCをSET!
    // データセット
    TMDF00L = CAN_RX_ID >> 8;     //受信IDを送信
    TMDF00H = (unsigned char)(CAN_RX_ID & 0x00FF);
    TMDF10L = CAN_RX_DLC;         //受信DLCを送信
    TMDF10H = CAN_RX_DATA[0];    //受信DATA0を送信
    TMDF20L = CAN_RX_DATA[1];    //受信DATA1を送信
    TMDF20H = CAN_RX_DATA[2];    //受信DATA2を送信
    TMDF30L = CAN_RX_DATA[3];    //受信DATA3を送信
    TMDF30H = 0x12;                   //固定データを送信
    TMC0 |= 0x01;                      //送信要求 TMTRを"1"に


    //★★★CANの受信★★★★★★★★★★★★★★★★★★★★★★★★★   
    CAN_RX_ID = RFIDL0;          //IDを格納
    CAN_RX_DLC = RFPTR0 >> 12;   //DLCを格納
    CAN_RX_DATA[0] = RFDF00L;    //Data0を格納
    CAN_RX_DATA[1] = RFDF00H;    //Data1を格納
    CAN_RX_DATA[2] = RFDF10L;    //Data2を格納
    CAN_RX_DATA[3] = RFDF10H;    //Data3を格納
    CAN_RX_DATA[4] = RFDF20L;    //Data4を格納
    CAN_RX_DATA[5] = RFDF20H;    //Data5を格納
    CAN_RX_DATA[6] = RFDF30L;    //Data6を格納
    CAN_RX_DATA[7] = RFDF30H;    //Data7を格納
    RFPCTR0 = 0x00FF;                //バッファポインターインクリメント
   
   }
  }
 }

  • そろそろ様

    同期ミスの確率とのトレードオフになってしまいますが、
    Tqを12にすれば、
    C0CFGL = 0x0001で
    (24MHz/2) / (2* 12Tq) = 500kbps
    になるので、クロック24MHzで動作させている私の場合は
    これで対応しています。

    CANUSBについて
    オシロでパタパタしませんとありますが、
    通信自体できていないのですかね。
    (トランシーバの段階ではじかれている?)

    因みに同僚がCANUSB使っておりますが、
    問題なく双方向に通信できているそうです。
  • Sugachance さま、
    早速のリプライ、ありがとうございます。
    そろそろです。

    500Kbpsの件、試してみます。

    トランシーバの件、私も気になったので調べています。
    トランシーバの制御はシンプルでStandByのポートがあるだけです。
    StandbyのポートをHighにするとStandby状態になります。
    まずはCAN通信できるようにするのが目的なので常にLowでStandbyにならないようにしています。

    PCからフレーム送信するとRL78のRx, Txはパタパタしないです。
    その代わりにRL78から下記の固定値を送信するとTx, Rx共にパタパタして
    トランシーバからの出力もパタパタしているのですが、PCにデータが届かない状態です。

    FDF01Lが0x00;
    RFDF01Hが0x01;
    RFDF11Lが0x10;
    RFDF11Hが0x11;
    RFDF21Lが0x20;
    RFDF21Hが0x21;
    RFDF31Lが0x30;
    RFDF31Hが0x31;

    初歩的な質問で申し訳ないのですが、
    RL78のTxとRxを見ているとTxで送出したものをRxで受信しているように見えます。
    RL78の設定でミラー?的な設定があったので試してみましたが
    Tx, Rxの信号に変化はなかったです。
  • そろそろ様

    確かに、Txで送出したものをRxで受信している感じですが、
    セルフテストモードになってるか、
    ハード的につながっているかですかね?

    C0CTRHの値はどうなっているのか、
    送信バッファ0の送信完了割り込みに入るのか、
    入ったとしたらその時のTMSTS0の値はどうなのか
    を見てみるとよいかもしれません。

     

    追記

    意図的に送信エラーを発生させたところ

    確かにRFDF01~RFDF31に送信データが入りますね・・・

    マニュアルに書いてあったかな…

    送信成功でもRFDF01~に送信データが入りました。

    少し横道にそれましたが、送信バッファ0以外を用いると入らないようです。

     

    とうことから、まずは送信ができているか確認するという事で

    ・送信バッファ0の送信完了を確かめる

    ・送信バッファ1を用いた送信を試してみる

    のが良いと思います。

  • >PCからフレーム送信するとRL78のRx, Txはパタパタしないです。

    RXが変化しないようでは、PCから信号が出ているのか確かめた方が良いですね。
    プログラムを見ても無駄です。
  • gachanceさま、リカルドさま、お世話になっております。
    そろそろ です。

    セルフテストモードにはなっていませんでした。

    ①RL78がら送信するとTXとRXがパタパタしますが、
    CANH, Lには出力されません。

    ②PCから送信するとCANH, Lがパタパタしません。

    CANHとLが怪しいという事で確認したところ
    CANHとCANLの配線が逆になっていました。

    DSUBでどのPinをCANH,CANLに振り分けるかは
    規格で決まっているわけではないのでミスが起きてしまったようです。

    CANHとCANLの配線を逆にしてもらったところ
    上記①と②が解決しました。

    ご協力、ありがとうございました。

    電気的は通信できるようになったのですが、
    PCからRL78に向かって送信するとエラーが発生するので
    その原因調査を始めました。

    Sugachanceさんがチェックしてくれていますが、
    『RFDF01~に送信データが入りました』
    のようですね。この点も謎です。
  • Sugachanceさま、お世話になっております。

    すいません、名前のSuが抜けてました。
  • そろそろ様

    解決したようで何よりです。
    RFDF01については、FIFOバッファを使う/使わないも試してみたのですが
    変わらず送信バッファ0による送信の時のみ発生するようです。
    他に気になる点もあったので、
    サポートに問い合わせ中です。

     

    追記

    サポートから回答があり、

    未使用のCAN受信FIFOバッファは不定となります。貴社ご使用条件において、
    未使用となっていないかご確認ください。

    とのことでした。

    これはマニュアルに書いてあったので、使用した場合を確認したはずでしたが、

    抜けてたのかもしれないので後でもう一度確認してみます。

  • みなさんこんにちは、NAKAといいます。

    しばらく東京出張やなんやかんやでカフェルネにお邪魔しておりませんでした。
    サンプルプログラム試していただきありがとうございます。
    RL78は去年ドライバー作ったので大分詳細はわすれちゃいましたが............汗)
    ちょっとCANUSBなる機器が全くわからないので、どんな感じでデータモニタできるのか
    わかりません。僕はVectorのCAN-CASEというハードを使ってモニタしてます。

    先ずボーレートですが使用する水晶により設定がことなりますので
    取りあえずオンチップオシレータ32MHzを使う設定を紹介します。

    //高速オンチップオシレータ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)=ボーレートプリスケラ =500Kbps

    あと、
    RFCC0 = 0xF302;  としてますので送信バッファ0しか使ってませんのでその他のバッファを読んでも不定です。

    あと、
    PCから送信するとエラーとのことですが、
    定期送信しているので、CANUSBなるもので受信はできているのでしょうか?

    CANのバスに終端抵抗(60Ω程度)は入っているのでしょうか?

    CANUSBが怪しいとのことであれば
    例えばですがボードを2枚用意して同じ設定をし

    //★★★CANの受信★★★★★★★★★★★★★★★★★★★★★★★★★
    CAN_RX_ID = RFIDL0; //IDを格納
    CAN_RX_DLC = RFPTR0 >> 12; //DLCを格納
    CAN_RX_DATA[0] = RFDF00L; //Data0を格納
    CAN_RX_DATA[1] = RFDF00H; //Data1を格納
    CAN_RX_DATA[2] = RFDF10L; //Data2を格納
    CAN_RX_DATA[3] = RFDF10H; //Data3を格納
    CAN_RX_DATA[4] = RFDF20L; //Data4を格納
    CAN_RX_DATA[5] = RFDF20H; //Data5を格納
    CAN_RX_DATA[6] = RFDF30L; //Data6を格納
    CAN_RX_DATA[7] = RFDF30H; //Data7を格納
    RFPCTR0 = 0x00FF;      //バッファポインターインクリメント

    CAN_RX_DATA[0] から CAN_RX_DATA[7]  を シリアル通信(RS232C)に出力して
    パソコンで確認するのはどうでしょうか?定期送信のインターバルを早くしなければ
    余裕でモニタできますよ!
    シリアル通信ならコード生成が使えるので、そんなに苦労しないような気もします。

    こちらに北斗電子さんのRL78/F14ボードがあり、もう一度試しましたが動いてます。

    上手く動いたら、割り込みですね!

    割り込み使うと、ちょー簡単ですよ。
  • Sugachanceさま、リカルドさま、NAKAさま、お世話になっております。
    そろそろ です。

    皆さまの助けを借りて、そろそろ 送受信出来るかな?という事で
    いろいろ試してみたところCANで送受信できるようになりました。

    PCから送ったフレームをRL78まで届いて、
    送り返してきたフレームがPC側のターミナルで表示される
    事が確認できました。

    ご協力、ありがとうございました★!

    試行錯誤で実現した感じでわからない点があります。

    CAN Busのbps設定が正しくなかったので通信エラーが発生していました。

    下記の設定で500kbpsにしているつもりなのですが、
    250kbpsになってしまっています。

    RL78の設定は

    ①コード生成ツールの『クロック発生回路』
    ・メイン・システムクロック(fMain)設定:『高速システム・クロック(fMX)』を選択

    ・高速オンチップオシレータクロック設定
     ・『動作』を選択
     ・周波数:8MHz

    ・高速システム・クロック設定
     ・『外部クロック入力(fEX)』を選択で『16MHz』

    ②GCFGL = 0x0000; //DCS=0:fCAN=fCLK/2=8MHzに設定 DLC配置禁止とは?
    ③C0CFGH = 0x0049; //SJW=1 TSEG2=5 TSEG1=10 に設定 ボーレートプリスケラ(1)分周無しの場合
    ④C0CFGL = 0x0000; //C0CFGL+1で分周=ボーレートプリスケラ = fCAN_8Mhz/((0+1)×16Tq)= 500Kbps

    ①②からfcanは外部クロック入力(fEx)/2=16MHx/2=8MHz
    ③からボーレート・オウリスケーラー分周値 = 1
    ④からTq=16

    従って通信速度
    = fcan/ボーレート・オウリスケーラー分周値×Tq数
    = 8/(1×16) = 500bps

    のはずなのですが、500bpsでは動作しません。
    RL78の対向であるCANUSBの転送レートを250bpsにすると通信できるようになります。

    上記内容でおかしな部分がありましたら指摘して頂けると助かります。

    ①でfMXを『高速システムクロック』にして
    高速システムクロックは『外部クロック入力(fEX)』で16MHz
    この辺りの設定がおかしいのかも???
  • こんにちは、NAKAです。

    ちらっと見た感じでは良さそうですよね!
    外付けに16MHzの発振器をクロック入力につないでるんですよね?
    で、fCLK(システムクロック)をこちらを選択しているんですよね?
    何故、オンチップオシレータを動作させるのかは?ですけど、電気もったいない!

    GCFGL = 0x0000なのでDCSでfCLK側にしていて1/2のDIVがあるから8MHzをfCANに
    使っているんですよね?

    だったら良さそうな感じなんだけどなぁ~

    fCLKをタイマーに使ってLEDチカチカさせて、本当にfCLKが16MHzなのか確認したり
    してはどうでしょうか?

    オンチップオシレータで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

    先日紹介したオンチップオシレータのクロックで試したらどうなるのかな?

    北斗電子のRL78/F14基板は外付けに8MHzの水晶がついてて、fCLKをPLLで32MHzにしてもOK
    GCFGL = 0x0010でDCSをX1(8MHz)側にして直接使ってもOK
    データーシート通りでしたよ。

    原因がわかったら、また紹介してあげてくださいね? みなさんの参考になると思いますので.....