クラス CAN -- Controller Area Network 通信バス
CAN は、クラシック CAN (F4、F7 MCU で利用可能)および CAN FD (H7 シリーズ)コントローラーをサポートしています。物理レベルで CAN バスは RX と TX の 2 本のラインで構成されます。Pyboard を CAN バスに接続するには、CAN トランシーバーを使って、Pyboard の CAN ロジック信号をバス上の適切な電圧レベルに変換する必要があることに注意してください。
クラシック CAN コントローラーをループバック(トランシーバー不要)モードで使用する例:
from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126
can.send('message!', 123) # id 123 でメッセージを送信
can.recv(0) # FIFO 0 上でメッセージを受信
すべてのオプションを有効にした CAN FD コントローラーの使用例:
# FD フレーム + BRS モード + 拡張フレーム ID。500 Kbit/s のアービトレーションフェーズ、1Mbit/s のデータフェーズ。
can = CAN(1, CAN.NORMAL, baudrate=500_000, brs_baudrate=1_000_000, sample_point=80)
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))
can.send('a'*64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)
以降の CAN モジュール関数とその引数は、特に明記されていない限り、クラシック CAN コントローラーと FD CAN コントローラーの両方で利用できます。
コンストラクタ
- class pyb.CAN(bus, ...)
指定したバス上に CAN オブジェクトを構築します。 bus は 1-2 または 'YA'、'YB' を指定できます。追加のパラメータを指定しない場合、CAN オブジェクトは作成されますが初期化されません(バスの最後の初期化設定が保持されている場合は、それが適用されます)。追加の引数を指定すると、バスが初期化されます。初期化のパラメータについては
CAN.init()を参照してください。CAN バスの物理ピンは次のとおりです。
CAN(1)、YA:(RX, TX) = (Y3, Y4) = (PB8, PB9)CAN(2)、YB:(RX, TX) = (Y5, Y6) = (PB12, PB13)
メソッド
- CAN.init(mode, prescaler=100, *, sjw=1, bs1=6, bs2=8, auto_restart=False, baudrate=0, sample_point=75,
- num_filter_banks=14, brs_sjw=1, brs_bs1=8, brs_bs2=3, brs_baudrate=0, brs_sample_point=75)
指定のパラメータで CAN バスを初期化します:
mode は NORMAL、LOOPBACK、SILENT、SILENT_LOOPBACK のいずれか
prescaler は、CAN 入力クロックを分周して名目ビット時間クオンタを生成する値です。クラシックCANでは 1~1024 の範囲の値を指定できます。CAN FD では 1~512 の範囲の値を指定できます。
sjw は再同期ジャンプ幅であり、Nominal Bit のタイムクオンタムの単位数で指定します。クラシック CAN では 1~4 の範囲の値を指定できます。CAN FDでは 1~128 の範囲の値を指定できます。
bs1 はサンプルポイントの位置を定義するものであり、Nominal Bit のタイムクオンタムの単位数で指定します。クラシック CAN では 1~16 の範囲の値を指定できます。CAN FD では 2~256 の範囲の値を指定できます。
bs2 は転送ポイントの位置を定義するものであり、Nominal Bit のタイムクオンタムの単位数で指定します。クラシック CAN では 1~8 の範囲の値を指定できます。CAN FD では 2~128 の範囲の値を指定できます。
auto_restart は、コントローラーがバスオフ状態に入った後、自動的に通信を再開するかを設定します。無効の場合でも、
restart()を使ってバスオフ状態を解除できます。baudrate に 0 以外の値を指定すると、この関数は CAN の Nominal Bit 時間を自動計算しようとします(prescaler, bs1, bs2 を上書きします)。設定した baudrate (誤差 0.1% 以内)と sample_point (1% 単位で最も近い値)を満たすように調整されます。CAN のタイミングを正確に制御したい場合は prescaler, bs1, bs2 を直接設定してください。
sample_point はビットサンプルの位置を、名目ビット時間全体に対する整数パーセントで指定します。デフォルトの sample_point は 75% です。 baudrate が設定されていない場合、このパラメータは無視されます。
num_filter_banks は、クラシック CAN の場合、CAN(1) に割り当てるバンクの数を指定します。28 バンクの内の残りは CAN(2) に割り当てられます。
残りのパラメータは、CAN FD をサポートするボードにのみ存在し、オプションの CAN FD ビットレートスイッチ (BRS)機能を設定します。
brs_prescaler は、CAN FD の入力クロックを分周してデータビットのタイムクオンタを生成する値です。プリスケーラには 1〜32 の範囲の値を指定できます。
brs_sjw は再同期ジャンプ幅で、データビットのタイムクオンタムの単位数で指定します。1〜16 の範囲の値を指定できます
brs_bs1 は、データビットのタイムクオンタムの単位数でサンプルポイントの位置を定義します。1〜32 の範囲の値を指定できます
brs_bs2 は、データビットのタイムクオンタムの単位数で転送ポイントの位置を定義します。1〜16 の範囲の値を指定できます
brs_baudrate に 0 以外の値を指定すると、この関数は CAN のデータビット時間を自動計算しようとします( brs_prescaler 、 brs_bs1 、 brs_bs2 を上書きします)。設定した brs_baudrate (誤差 0.1% 以内)と brs_sample_point (1% 単位で最も近い値)の両方を満たすように調整されます。BRS のタイミングをより正確に制御したい場合は、 brs_prescaler 、 brs_bs1 、 brs_bs2 のパラメータを直接設定してください。
brs_sample_point はビットサンプルの位置を、名目ビット時間全体に対する整数パーセントで指定します。デフォルトの brs_sample_point は 75% です。 brs_baudrate が設定されていない場合、このパラメータは無視されます。
タイムクオンタ tq は CAN バスの基本的な時間の単位です。tq は CAN のプリスケーラの値を PCLK1 (内部ペリフェラルバス 1 の周波数)で割ったものです。PCLK1 を調べるには
pyb.freq()を参照してください。1ビットは、常に 1 tq の同期セグメントと、それに続くビットセグメント 1、ビットセグメント 2 から構成されます。サンプルポイントはビットセグメント 1 が終わった後です。転送ポイントはビットセグメント 2 が終わった後です。ボーレートは 1/ビット時間になります。ビット時間は 1 + BS1 + BS2 にタイムクオンタ tq を掛けたものです。
たとえば PCLK1=42MHz、prescaler=100、sjw=1、bs1=6、bs2=8 の場合、tq の値は 2.38 マイクロ秒になります。ビット時間は 35.7 マイクロ秒で、ボーレートは 28kHz です。
詳細は STM32F405 のデータシートの 680 ページを参照してください。
- CAN.deinit()
CAN バスをオフにします。
- CAN.restart()
設定をリセットせずに、CAN コントローラのソフトウェア的な再起動を強制します。
コントローラが bus-off の状態に入ると、バス上の通信に参加しなくなります。コントローラが自動的に再起動するよう設定されていない場合(
init()を参照)、このメソッドで再起動を起こせます。コントローラは CAN のプロトコルに従って bus-off の状態を抜け、error active の状態に入ります。
- CAN.state()
コントローラの状態を返します。戻り値は次のいずれかです:
CAN.STOPPED-- コントローラは完全にオフでリセットされています。CAN.ERROR_ACTIVE-- コントローラはオンで Error Active の状態です (TEC と REC の両方が 96 未満)。CAN.ERROR_WARNING-- コントローラはオンで Error Warning の状態です (TEC か REC の少なくとも一方が 96 以上)。CAN.ERROR_PASSIVE-- コントローラはオンで Error Passive の状態です (TEC か REC の少なくとも一方が 128 以上)。CAN.BUS_OFF-- コントローラはオンですが、バス上の通信に参加していません (TEC が 255 を超えてあふれました)。
- CAN.info([list])
コントローラのエラー状態と TX/RX バッファに関する情報を取得します。 list を指定する場合は、少なくとも8個の要素を持つリストオブジェクトでなければならず、そこに情報が書き込まれます。指定しない場合は新しいリストが作られて書き込まれます。どちらの場合も、このメソッドの戻り値は値の入ったリストです。
リスト内の値は次のとおりです:
TEC の値
REC の値
コントローラが Error Warning の状態に入った回数 (65535 を超えると 0 に戻ります)
コントローラが Error Passive の状態に入った回数 (65535 を超えると 0 に戻ります)
コントローラが Bus Off の状態に入った回数 (65535 を超えると 0 に戻ります)
送信待ちの TX メッセージの数
fifo 0 で受信待ちの RX メッセージの数
fifo 1 で受信待ちの RX メッセージの数
- CAN.setfilter(bank, mode, fifo, params, *, rtr, extframe=False)
フィルタバンクを設定します:
bank は、設定するクラシック CAN コントローラのフィルタバンク、または CAN FD のフィルタのインデックスです。
mode はフィルタが動作するモードです。下の表を参照してください。
fifo は、このフィルタでメッセージが受け付けられた場合に、そのメッセージを格納する fifo (0 か 1) です。
params はフィルタを定義する値の配列です。配列の内容は mode 引数に依存します。
mode
クラシック CAN コントローラでの params 配列の内容
CAN.LIST16
受け付ける4つの 16 ビット id
CAN.LIST32
受け付ける2つの 32 ビット id
CAN.MASK16
- 2組の 16 ビットの id/マスクの対。例: (1, 3, 4, 4)
- 最初の対 1 と 3 は、ビット 0 = 1 かつビット 1 = 0 のすべての id を受け付けます。2番目の対 4 と 4 は、ビット 2 = 1 のすべての id を受け付けます。
CAN.MASK32
CAN.MASK16 と同様ですが、32 ビットの id/マスクの対が1組だけです。
mode
CAN FD コントローラでの params 配列の内容
CAN.RANGE
受け付ける id の範囲を表す2つの id。
CAN.DUAL
受け付ける2つの id。たとえば (1, 2)
CAN.MASK
1つのフィルタ ID とマスク。たとえば (0x111, 0x7FF)
rtr クラシック CAN コントローラの場合、これはフィルタがリモート送信要求のメッセージを受け付けるかどうかを示す真偽値の配列です。この引数を指定しない場合、すべての要素はデフォルトで
Falseになります。配列の長さは mode 引数に依存します。CAN FD では、この引数は無視されます。
mode
rtr 配列の長さ
CAN.LIST16
4
CAN.LIST32
2
CAN.MASK16
2
CAN.MASK32
1
extframe True にすると、フレームは拡張識別子 (29 ビット) を持ちます。そうでなければ標準識別子 (11 ビット) が使われます。
- CAN.clearfilter(bank, extframe=False)
フィルタバンクをクリアして無効にします:
bank は、クリアするクラシック CAN コントローラのフィルタバンク、または CAN FD のフィルタのインデックスです。
extframe CAN FD コントローラの場合、True なら(extframe=True で設定した)拡張フィルタをクリアし、そうでなければ(extframe=False で設定した)標準識別子のフィルタをクリアします。
- CAN.any(fifo)
FIFO に待機中のメッセージがあれば
Trueを、そうでなければFalseを返します。
- CAN.recv(fifo, list=None, *, timeout=5000)
バス上のデータを受信します:
fifo は受信に使う FIFO を表す整数です
list は戻り値として使う省略可能なリストオブジェクトです
timeout は受信を待機するタイムアウト時間をミリ秒で指定します。
戻り値: 5つの値を含むリスト。
メッセージの id。
メッセージ ID が標準か拡張かを示す真偽値。
メッセージが RTR メッセージかどうかを示す真偽値。
FMI (Filter Match Index) の値。
データを含む配列。
list が
Noneの場合、新しいリストと、データを格納する新しい bytes オブジェクト(リストの5番目の要素)が割り当てられます。list が
Noneでない場合、少なくとも5要素を持つリストオブジェクトでなければなりません。5番目の要素は、bytearray か型 'B' または 'b' の array から作られた memoryview オブジェクトで、この配列は少なくとも8バイトを収められる十分な大きさでなければなりません。リストオブジェクトには上記の最初の4つの戻り値が格納され、memoryview オブジェクトはデータのサイズにその場でリサイズされ、そのデータで埋められます。同じリストと memoryview のオブジェクトは、このメソッドの以降の呼び出しでも再利用でき、ヒープを使わずにデータを受信する方法になります。たとえば:buf = bytearray(8) lst = [0, 0, 0, 0, memoryview(buf)] # 次の呼び出しではヒープメモリを割り当てません can.recv(0, lst)
- CAN.send(data, id, *, timeout=0, rtr=False, extframe=False, fdf=False, brs=False)
バスにメッセージを送信します:
data は送信するデータです(送信する整数、またはバッファオブジェクト)。
id は送信するメッセージの id です。
timeout は送信を待機するタイムアウト時間をミリ秒で指定します。
rtr は、メッセージをリモート送信要求として送るかどうかを指定する真偽値です。 rtr が True の場合、フレームの DLC の欄を埋めるのに data の長さだけが使われ、 data の実際のバイト列は使われません。
extframe True にすると、フレームは拡張識別子 (29 ビット) を持ちます。そうでなければ標準識別子 (11 ビット) が使われます。
fdf CAN FD コントローラの場合、True にするとフレームは FD のフレーム形式になり、最大 64 バイトのデータペイロードをサポートします。
brs CAN FD コントローラの場合、True にするとビットレート切り替えモードが有効になり、データフェーズが異なるビットレートで送信されます。データビットのタイミングの設定パラメータについては
CAN.init()を参照してください。
timeout が 0 の場合、メッセージは3つのハードウェアバッファのいずれかに置かれ、メソッドは直ちに戻ります。3つのバッファがすべて使用中の場合は例外が発生します。timeout が 0 でない場合、メソッドはメッセージが送信されるまで待ちます。指定した時間内にメッセージを送信できない場合は例外が発生します。
戻り値:
None。
- CAN.rxcallback(fifo, fun)
空の fifo にメッセージが受け付けられたときに呼び出される関数を登録します:
fifo は受信する fifo です。
fun は fifo が空でなくなったときに呼び出される関数です。
コールバック関数は2つの引数を取ります。1つ目は can オブジェクト自身、2つ目はコールバックの理由を示す整数です。
理由
0
空の FIFO にメッセージが受け付けられました。
1
FIFO が満杯です
2
FIFO が満杯のためメッセージが失われました
rxcallback の使用例:
def cb0(bus, reason): print('cb0') if reason == 0: print('pending') if reason == 1: print('full') if reason == 2: print('overflow') can = CAN(1, CAN.LOOPBACK) can.rxcallback(0, cb0)
定数
- CAN.STOPPED
- CAN.ERROR_ACTIVE
- CAN.ERROR_WARNING
- CAN.ERROR_PASSIVE
- CAN.BUS_OFF
state()が返す CAN コントローラの取りうる状態です。
- CAN.LIST16
- CAN.MASK16
- CAN.LIST32
- CAN.MASK32
クラシック CAN 向けに
setfilter()で使うフィルタの動作モードです。
- CAN.DUAL
- CAN.RANGE
- CAN.MASK
CAN FD 向けに
setfilter()で使うフィルタの動作モードです。