鳥なき里のマイコン屋(125) Nucleo+MCP2562でCANバスにフレーム送信

Joseph Halfmoon

前回、M5StackとArduino Uno間でCANフレームの送受信ができるようになりました。しかしCANは「バス」です。1対1で通信できても物足りませぬ。そこで今回はST MicroelectronicsのSTM32マイコン搭載、Nucleo-F072RBをCANバスに接続してみます。でもね、PHYはMicrochip製MCP2562。

(送信実験用のC++コード全文は末尾に)

Nucleo-F072RB、STM32搭載のマイコンボード

前回までは、CANインタフェースを持たないマイコンに外付けでCANインタフェースを取り付けておりました。しかし今回は違います。ST Microelectronics社製STM32F072RBT6マイコンには、CANインタフェース機能が搭載されているのであります。なお、このマイコンはSTM32シリーズの中ではちょっと古くて小さい感じだと思うのですが、しっかり量産中でした。

CANインタフェースを搭載ということでCANのプロトコルに関わる処理は「やってくれる」のです。しかし、物理層までは搭載されていません。デジタルな0/1で処理できるTXD/RXDのレベルまで。実際にNucleo-F072RBボードのどこに端子が出ているかを示すためにST社の図を1枚引用させていただきます。図の赤丸のところの端子を取り出して使わせてもらっています。

CN10headerCANインタフェースは1チャネルのみですが、2か所に出ています。そのうちの右側を選んだのはタマタマです。

MCP2562 CANトランシーバ

さて実際に差動信号で動作しているCANバスに接続するためにはCANトランシーバ(PHY)が必要です。今回使用させていただきましたのは Microchip社製 MCP2562であります。2561と2562が兄弟チップのようですが、今回は2562を購入(秋月通商殿)。これは2562の特徴としてデジタルIO端子への電源が主電源端子と別になっていて便利なためです。なおArduino Uno用のCANインタフェースボードにもMicrochip社製の同系列のデバイス、MCP2551が搭載されていました。

Nucleo-F072RBとMCP2562の接続

接続そのものは簡単で、以下で一応動作いたしました。

F072RB_MCP2562_CIR実際に接続している様子を以下の写真に掲げました。CANバスに現れるフレームを解読するために例によってCAN解読モードのAnalog Discovery 2も接続しているのでCANのところの配線込み入っています。

NucleoF072RB_MCP2562とりあえずCANフレーム垂れ流しの送信実験

末尾に掲げたコードは、Arm Mbed OS上で動作する筈のCANのサンプルコードを「勝手改造」してしまったものです。オンラインのMbedコンパイラ環境上で、CANのサンプルプログラムをゲットし、無改造でそのまま走らせてみたのですが、ランタイムエラーが発生してしまいダメでした。そこで「不細工に」大幅改造してしまったものです。これであればCANフレームの垂れ流し動作、一応できています。Analog Discovery 2で解読するとこんな感じ。なお速度は125kHzといたしました。

SEND_WAVEFORMしかしながら2点問題あり、です。1点目は、ペイロードを1バイト、値としては0~255の循環で載せているつもりなのですが、ペイロードは常に0になってしまっています。要追及。

BUILD_RESULTもう1点は、Mbedオンライン・コンパイラのビルド結果です。Flashメモリはまだ余裕シャキシャキなのですが、RAMはいっぱいいっぱいでした。残り0.2kB。動いたことが僥倖という感じのギリギリ使用量です。もしかすると正式のサンプルプログラムが実行時エラーになってしまう原因かもしれないです。

ビルド構成など変えてどこまでRAMを少なくできるのか?末尾のコードを見ていただくと分かる通り、今現在も「ほとんど何もやってない」プログラムです。メモリ使用量がこのままではCANフレームの垂れ流し以上のコードは載せられない可能性大です。

まあ、もっとRAMに余裕のあるマイコン・ボード使うほうが良いとは思うのです。手元にあるもう一枚のNucleoボード、F401REは上位機種でまだRAMに余裕ありそうなのですが、残念なことにCANインタフェースが無い!

なかなか思ったようにはうまく行きませぬ。まあね、キツキツなところを押したり引いたりするのがマイコン、ですけれども。

鳥なき里のマイコン屋(124) M5StackとUno間、CANフレームのラウンドトリップ へ戻る

Nucleo-F072RB用 CANフレーム送信実験用コード(Arm Mbed OS)
#include "mbed.h"

DigitalOut led1(LED1);
CAN can1(PA_11, PA_12, 125000);
char counter = 0;

int main()
{
    printf("main()\n");
    while (1) {
      can1.write(CANMessage(1337, &counter, 1));
      counter++;
      printf("Message sent: %d\n", counter);
      led1 = !led1;
      ThisThread::sleep_for(1000);
    }
}