RX64MのCAN通信

マイコンプログラムは初心者レベルです。

RX64MでCAN通信をしていますが、不可解な現象があり悩んでいます。

一応、下記の対応で改善はされたのですが、改善された理由がいまいち明確でないので、詳しい方のご意見をお伺いしたく投稿しました。

※e2studioでFITドライバを使用しています。(GCCコンパイラ、RX-CCどちらも同じ現象)

 

<プログラムの概要>

①メインループで受信メッセージBOXを監視して、データがあれば読み込み

while(1)

{

 status = R_CAN_RxPoll(ch, mbox);
 if (status == R_CAN_OK)
 {
  //受信データあり
  status = R_CAN_RxRead(ch, mbox, frame_p);
  if (status == R_CAN_OK)
  {
   //受信データ読み出しOK
  }
 }

}

②CMTタイマー割込み(2ms)の関数内で、送信

 R_CAN_TxSet(ch, mbox, dataframe, DATA_FRAME);

 

<現象>

①で受信データがないにも関わらず、「//受信データあり」になってしまう。

※不定期のタイミング(数ミリ秒~数秒)で受信ありになる場合がある。

※受信データは、この処理以前に受信していた最後のデータになっている。

 

<対応>

 

R_CAN_RxPoll()実行中に、②の割り込みが発生してしまい、受信有りのレジスタがおかしくなった(?)と考え、割込みでは送信フラグをONするだけにし、

メインループで送信フラグONのときに送信するようにした。→R_CAN_RxPoll()中にR_CAN_TxSet()が発生しないように。。

 

while(1)

{

 if (send_flg)

 {

  R_CAN_TxSet(ch, mbox, dataframe, DATA_FRAME);

  send_flg = 0;
 }

 status = R_CAN_RxPoll(ch, mbox);
 if (status == R_CAN_OK)
 {
  //受信データあり
  status = R_CAN_RxRead(ch, mbox, frame_p);
  if (status == R_CAN_OK)
  {
   //受信データ読み出しOK
  }
 }

 

}

 

 

 

  • ★補足します
    受信処理中は割り込み禁止にした場合でも、改善されました。
    ただ、頻繁にR_BSP_InterruptsDisable();、R_BSP_InterruptsEnable();を繰返す事はあまりよくないのでしょうか?
    それとも全く問題ない、当たり前の事でしょうか?

     R_BSP_InterruptsDisable();

     status = R_CAN_RxPoll(ch, mbox);
     if (status == R_CAN_OK)
     {
      //受信データあり
      status = R_CAN_RxRead(ch, mbox, frame_p);
      if (status == R_CAN_OK)
      {
       //受信データ読み出しOK
      }
     }

     R_BSP_InterruptsEnable();
  • love0510さん、こんにちは。NoMaYです。

    CANのことは分からないのですが、どういう訳か気になって、ソースコードとAPIドキュメントを読んでみました。そして、気になったのが、あたかも近藤科学のサーボモータの単線UART通信のように(あるいはRS485(だったかな)の単線UART通信のように)、CAN APIは以下の手順で使われることを想定されて設計されているのではないかなぁ、という点です。

    (1) 送信モードに切り替える → 送信する
    (2) 受信モードに切り替える → 受信する
    (2') 受信モードに切り替える → ポーリングする → 受信する

    このイメージがCAN APIと1対1対応では無さそうなので説明し難いのですが、うまくいかないというケースでは上の手順に適合していないのが原因なのではないでしょうか?逆に、うまくいくケースでは上の手順に適合していたからだったのではないでしょうか?

    例えば、割り込みがどうのこうのではなく、メインループで以下のシーケンスでCAN APIを呼び出した場合でもうまくいかないのではないでしょうか?

    受信ポーリング → 受信データあり → 送信 → 受信データ読み出し → NG

    そんな気がしたのです、、、

  • NoMaYさん、ありがとうございます。

    今は試している時間がないので、取り急ぎ、受信処理中は割り込み禁止にして対応するつもりです。
    原因はどこかではっきりさせたいですが。。
  • こんにちは、hira です。

    自分の RX マイコンフレームワークでは、CAN のサンプルプログラムを用意してあります。
    参考にどうぞ。

    RX600/can.hpp
    common/can_io.hpp
    common/can_analize.hpp
    CAN_sample/main.cpp

    RX64M/RX71M/RX66T/RX72N 対応

    RX64M/RX71M では、CAN0、CAN1 を有効にして、チャネルを切り替えて動作。

    CAN0、CAN1 のポートは、RX600/port_map.hpp を参考。

    サンプルプログラムは、シリアル接続でターミナルなどを接続して、対話形式で CAN 通信を行う事が出来ます。
    また、CAN バスの全ての通信を監視して、ID を収集してマッピングします。

    プログラムは C++17 で実装されていて、Renesas GNU RX 8.3.0 でコンパイル可能です。
    ※C++/boost が必要です。

    独自のフレームワークを使っていて、Windows MSYS2 環境用(Makefile)です。

    github.com/.../READMEja.md

    全ソースコードは github にあり、MIT ライセンスです。

    ---

    ブログでも解説しています。
    www.rvf-rc45.net/.../