CAN
CAN目前仅支持ESP32系列上的经典CAN控制器。在物理层,CAN总线由RX和TX两条线路组成。请注意,要将M5Stack设备连接到CAN总线,必须使用CAN收发器将MCU的CAN逻辑信号转换为总线所需的正确电压电平。
详细示例请参阅:unit.CANUnit
API参考
CAN
- class hardware.CAN(bus, mode, tx, rx, prescaler=32, sjw=3, bs1=15, bs2=4, triple_sampling=False)
在指定总线上构造一个CAN对象。
- 参数:
bus (int) – 必须为0。
mode (int) – 取值为NORMAL、NO_ACKNOWLEDGE或LISTEN_ONLY之一。
tx (int) – 用于发送数据的引脚。
rx (int) – 用于接收数据的引脚。
prescaler (int) – 将CAN输入时钟分频以生成名义位时间量化值的分频数,经典CAN取值范围为1到1024。
sjw (int) – 名义位的时间量化单位中的重同步跳转宽度,经典CAN取值范围为1到4。
bs1 (int) – 定义名义位中采样点在时间量化单位中的位置,经典CAN取值范围为1到16。
bs2 (int) – 定义名义位中发送点在时间量化单位中的位置,经典CAN取值范围为1到8。
triple_sampling (bool) – 当TWAI控制器采样位时启用三重采样。
UiFlow2 代码块:

MicroPython 代码块:
from hardware import CAN can = CAN(0, CAN.NORMAL, 0, 0, 25000)
- init(mode, tx, rx, prescaler=32, sjw=3, bs1=15, bs2=4, triple_sampling=False)
使用给定参数初始化CAN总线。
- 参数:
时间量化tq是 CAN 总线的基本时间单位,tq等于 CAN 预分频值除以 APB_CLK 时钟源(通常为80 MHz)。
单个位由同步段组成,该段始终为1个tq,之后依次为位段1和位段2。采样点位于位段1结束后,发送点位于位段2结束后。波特率为1/位时间,其中位时间为(1 + BS1 + BS2)乘以时间量化tq。
例如,当APB_CLK=80MHz、prescaler=32、sjw=3、bs1=15、bs2=4时,tq为0.4微秒,位时间为8微秒,波特率为125kHz。
更多信息请参阅ESP32技术参考手册。
MicroPython 代码块:
can.init(CAN.NORMAL, 0, 0, 25000)
- deinit()
关闭CAN总线。
UiFlow2 代码块:

MicroPython 代码块:
can.deinit()
- restart()
在不重置配置的情况下强制软件重启CAN控制器。
如果控制器进入总线关闭状态,它将不再参与总线活动。若控制器未配置自动重启(参见 :meth:`~CAN.init()`),可以通过此方法触发重启,控制器将按照CAN协议离开总线关闭状态并进入错误活动状态。
UiFlow2 代码块:

MicroPython 代码块:
can.restart()
- state()
返回控制器状态。
- 返回:
int
``0`` – ``CAN.STOPPED``:控制器完全关闭并复位;
``4`` – ``CAN.BUS_OFF``:控制器仍开启但不再参与总线(TEC溢出超过255);
``5`` – ``CAN.RECOVERING``:控制器正在进行总线恢复。
``6`` – ``CAN.RUNNING``:控制器可以发送并接收消息;
UiFlow2 代码块:

MicroPython 代码块:
status = can.state()
- info([list])
获取控制器的错误状态以及 TX 和 RX 缓冲区信息。
- 参数:
list (list) – 可选列表对象,至少包含8个元素。
- 返回:
list
列表中的值包括:
TEC 值
REC 值
控制器进入错误警告状态的次数(暂不使用,与pyb.CAN兼容)。
控制器进入错误被动状态的次数(暂不使用,与pyb.CAN兼容)。
控制器进入总线关闭状态的次数(暂不使用,与pyb.CAN兼容)。
待发送消息数量
待接收消息数量
fifo 1中的待接收消息数量(暂不使用,与pyb.CAN兼容)。
UiFlow2 代码块:

MicroPython 代码块:
info = can.info()
- any(fifo)
若FIFO中存在待处理消息则返回``True``,否则返回``False``。
- 参数:
fifo (int) – FIFO 索引。
- 返回:
bool
UiFlow2 代码块:

MicroPython 代码块:
if can.any(0): print("Message waiting")
- recv(fifo, list=None, *, timeout=5000)
在总线上接收数据。
- 参数:
- 返回:
tuple
返回值:包含5个元素的元组。
消息 ID。
布尔值,指示消息 ID为标准帧或扩展帧。
布尔值,指示消息是否为RTR消息。
FMI(滤波匹配索引)值。
包含数据的数组。
如果 list 为``None``,将分配一个新的元组以及一个新的bytes对象(作为元组的第五个元素)来存放数据。
如果 list 不是``None``,则它应是包含至少5个元素的列表。第五个元素必须是由bytearray或类型为’B’或’b’的array创建的memoryview对象,并且该数组至少能容纳8个字节。列表会填充前四个返回值,而memoryview会就地调整到数据长度并写入数据。同一列表和memoryview可以在后续调用中复用,从而避免使用堆内存。例如:
buf = bytearray(8) lst = [0, 0, 0, 0, memoryview(buf)] # No heap memory is allocated in the following call can.recv(0, lst)
UiFlow2 代码块:


MicroPython 代码块:
can.recv(0)
- send(data, id, *, timeout=0, rtr=False, extframe=False)
在总线上发送消息。
- 参数:
当timeout为0时,消息会被放入三个硬件缓冲区之一并立即返回;如果三个缓冲区都在使用,则会抛出异常。timeout非0时,方法会等待消息发送;若在指定时间内无法发送成功则抛出异常。
- 返回:
None
UiFlow2 代码块:

MicroPython 代码块:
can.send('message!', 123)