CANとは
自動車用に開発された通信規格
- バス方式
- 2本の通信線(それぞれ
CAN H
CAN L
と呼ばれる)を使用して通信 - 全てのノードは
CAN H
とCAN L
に繋がる
- 2本の通信線(それぞれ
- マルチマスター方式
- 各ノードはいつでもデータを送信でき、他のノードが送信したデータをどのノードも受信できる
ここより下の話はSTM32やESP32が対応しているCAN 2.0B activeでの話です
回路的な話
ドミナントとレセッシブ
CANは差動伝送でCAN H
とCAN L
の電位の差で0と1を表現する
RenesasのCAN入門書より
CAN H
CAN L
に電位差が無いときをレセシブ、CAN H
CAN L
に電位差があるときをドミナントと呼ぶ
レセシブは1
、ドミナントは0
また、ドミナントは優勢 レセシブは劣勢という意味もあり、CANバス上にノードAとBがあるとき、Aがレセシブを出力してBがドミナントならドミナントが優先されCANバス全体がドミナントとなります
TIPS
差動伝送はペアとなる信号線、両方に同じノイズがのるため結局電位差は変わらないのでノイズに強い
> vectorのはじめてのCAN/CAN FDより
CANバス
CAN H
とCAN L
のことをまとめてCANバスと呼ぶ
バスの両端には終端抵抗と呼ばれる抵抗が付く(これは通常120Ω)
フレーム
CANでデータをやりとりする単位をフレームと呼び
- データフレーム
- リモートフレーム
- エラーフレーム
- オーバーロードフレーム
- インターフレームスペース
の5つがありますが、データフレームとリモートフレーム以外はCANコントローラーが勝手に生成して必要なときに送ってくれるので説明は省きます
データフレーム
データフレームは他のノードにデータを送るためのフレームです
RenesasのCAN入門書より
- SOF(Start Of Frame)
- フレームの始まりを示す
- 調停フィールド
- フレームのID
- 標準フォーマットと拡張フォーマットがあり、標準フォーマットでは11bit 拡張フォーマットでは29bitとなります
- 制御フィールド
- 送りたいデータのバイト数
- データフィールド
- 送りたいデータ(8byte以下)
- CRCフィールド
- CRCは誤り検出符号の一つでデータが破損せず遅れてるかチェックするための値
- この値はデータフィールドに入ってるデータから計算して出た値で受信側でも同じ計算をして同じ結果になれば破損してないことが確認できます
- ACKフィールド
- 正常に各ノードが受信できたかを確認するフィールド
- EOF(End Of Frame)
- フレームの終わりを示す
からなります
マイコンからCANコントローラーに対して指定するのはIDと送りたいデータであり、残りのSOFや制御フィールド、CRC、ACK、EOFは送信時にCANコントローラー側で生成してくれます
リモートフレーム
他のノードにデータを要求するためのフレームです
RenesasのCAN入門書より
- SOF(Start Of Frame)
- 調停フィールド
- 制御フィールド
- 要求するデータのバイト数
- CRCフィールド
- ACKフィールド
- EOF(End Of Frame)
からなり、ほぼデータフレームと構成は変わりません
違いはデータフィールドが無いことと、調停フィールドのRTRでレセシブかドミナントかくらいです
リモートフレームを送り他のノードにデータを要求し、要求されたデータを他のノードが返すという使われ方らしいですが、要求を高頻度でする場合は要求されなくてもデータを定期的にCANバス上に垂れ流すほうが結果的に通信量が少なくなるとかであまり使われてないらしい
IMPORTANT
CANはマルチマスター方式なので各ノードが好きなタイミングでデータを送れますがCANバス上で同時に通信できるノードは一つです。もし通信の開始タイミングが被った場合どうするかはIDで決まります。他のノードがレセシブのときに自分がドミナントなら他のノードは送信を取りやめるという決まりになってます。例えば標準フォーマットのデータフレームで
- 10100000000000
- 10101000000000
という2つのIDのフレームが送られようとしてるなら上から4bit目までは同じですが5bit目に来たところで上のIDはドミナントで下のIDはレセシブなので上のIDのフレームは送信を継続し下のIDのフレームを送ろうとしていたノードは送信を辞めますこのように通信の優先度を決めているためIDを送るフィールドは調停フィールドと呼ばれています
WARNING
i2cなどと混同しやすいですがIDは各ノードごとに固有のものというわけではなく各ノードが送るデータに対して固有で、受信側はIDでデータフィールドのデータがなんのデータなのかを判別します。また、IDは必ず被ってはいけません
例としては100から200の間のIDをセンサーの値を送るIDとして決めておいてノードAは101をノードBは105を使用してセンサーの値を各ノードに送信するという風に
コントローラーとトランシーバー
CANで通信するために殆どの場合はCANコントローラーとCANトランシーバーの2つを使用します
wikipediaより
コントローラー
CANコントローラーはデータの送受信をマイコンの代わりに実行するものです
マイコンから送りたいデータをセットするとあとは勝手に送信処理を行ってくれて、受信したデータはマイコンから好きなタイミングで取り出せます
STM32やESP32にはこのCANコントローラーは内蔵されてるものもあり、GPIOに後述のCANトランシーバーをつなげるだけでCANで通信できます
トランシーバー
CANトランシーバーはコントローラーとCANバスの間に位置し、0 1とドミナント レセシブの変換を行います
CANコントローラーからのTXピンがHigh
ならCANバスをドミナントに、Low
ならレセシブに。
CANバスがレセシブならトランシーバーのRXピンをLow
に、ドミナントならHigh
にします
最後に
間違ってたらごめんなさい