本記事は、WioTerminal(ATSAMD51)でこれまでに試してきたWioTerminalとMCP2515のSPI通信について、ライブラリを作成して使いやすくする過程を示します。
なお、ライブラリをC++でコーディングしていますが、C++コーディング手法については手本にはなりません。ご了承ください。
開発中のGitリポジトリはこちらです。
github.com
これまでにMCP2515を試した記録記事は次の2本です。
embaud-ot.hateblo.jp
- ステップ1 : MCP2515のアドレス定義
- ステップ2 : SPI通信で命令を発行する関数の実装
- ステップ3 : MCP2515の構成設定を実装
- ステップ4 データ受信構造を実装
- ステップ5 バッファ状態出力ピン設定を実装
- ステップ6 データ送信構造を実装
- まとめ
ステップ1 : MCP2515のアドレス定義
まずは、ヘッダファイルにMCP2515の固定値を定義します。
プリプロセッサのDefine命令によって、コーディング用の固定値として登録し、コーディングをスムーズに間違いなく行えるようにします。
今回定義したのは、大まかに次の3つの値です。
- レジスタアドレス
- 動作モード
- 短縮命令
それぞれの定義名の規則は次のようにしました。
- 「MCP2515_REG_」をレジスタ名の定義
- 「MCP2515_MD_ 」を動作モード
- 「MCP2515_CMD_」を短縮命令
ステップ2 : SPI通信で命令を発行する関数の実装
命令のみの発行、命令発行+データの送信、命令発行+データ送信+データ受信 というパターンがあるので、それぞれを行う関数を定義しました。
- orderInst
- orderSend
- orderRecv
ステップ3 : MCP2515の構成設定を実装
CAN通信設定として、CNF1, CNF2, CNF3を設定することで、CAN通信速度を定義します。
setConfig関数を、3つの設定パターンで実装しました。
- セグメント長を手動入力で指定するタイプ
- CNF1, CNF2, CNF3に値を設定するタイプ
- 所望のCANボーレートと、MCP2515への供給クロックを指定することでセグメント長を自動計算するタイプ
MCP2515のConfigurationレジスタ設定を実装したコミット
この時点で、CANCTRLレジスタをオペレーションモードをNormalや、ListenOnlyモード、LoopBackモードに設定することでCAN通信をテストすることができます。
ステップ4 データ受信構造を実装
CANデータを受信するメソッドを実装しました。
READ RX STATUS 命令を用いて、受信データの有無、何番のバッファにデータが入っているかをはじめに調べます。
次に、READ RX BUFFER 命令で IDとデータ長を取得、最後に受信したデータ長分のデータを取り出します。
candata_stという構造体を作成し、そこにパケット情報を詰め込みました。
- recv
- 受信バッファ内のデータ取り出し
- getRxStat
- 受信バッファ内のデータ有無確認
ステップ5 バッファ状態出力ピン設定を実装
CANデータがバッファに入ったことを、毎度SPI通信でレジスタを確認するのも良いですが、頻繁に確認するようだと、オーバヘッドが大きくなります。
MCP2515には、受信バッファのデータ有無をデジタル信号出力する機能があるため、マイコンに信号線をつなげることで信号状態High/Lowによってデータの有無を確認することができます。
- pinMode
MCP2515のDigital Outputピンの設定を実装したコミット
単にデジタルアウトプットピンとしても使用できるため、マイコン入門用にMCP2515のLチカも実装してみました。
MCP2515のLチカ (blink LED)サンプルスケッチ
ステップ6 データ送信構造を実装
データ受信で使用したcandata_st構造体を使用し、そこに格納されたデータを送信する構造を作りました。
送信データの格納は、TXバッファへのロード命令を使用しました。
まとめ
WioTerminalとMCP2515とのSPI通信、SPI通信で命令を発行してレジスタ読み書きをすることで、初期設定、データ受信、データ送信、基本的な操作をするためのライブラリができました。