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 代码块:

init.png

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总线。

参数:
  • mode (int) – 取值为NORMAL、NO_ACKNOWLEDGE或LISTEN_ONLY之一。

  • tx (int) – 用于发送数据的引脚。

  • rx (int) – 用于接收数据的引脚。

  • prescaler (int) – 用于将 CAN 输入时钟分频以生成名义位时间量化值的分频数。

  • sjw (int) – 名义位的时间量化单位中的重同步跳转宽度。

  • bs1 (int) – 定义采样点在名义位时间量化单位中的位置。

  • bs2 (int) – 定义发送点在名义位时间量化单位中的位置。

  • triple_sampling (bool) – 当TWAI控制器采样位时启用三重采样。

时间量化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 代码块:

deinit.png

MicroPython 代码块:

can.deinit()
restart()

在不重置配置的情况下强制软件重启CAN控制器。

如果控制器进入总线关闭状态,它将不再参与总线活动。若控制器未配置自动重启(参见 :meth:`~CAN.init()`),可以通过此方法触发重启,控制器将按照CAN协议离开总线关闭状态并进入错误活动状态。

UiFlow2 代码块:

restart.png

MicroPython 代码块:

can.restart()
state()

返回控制器状态。

返回:

int

  • ``0`` – ``CAN.STOPPED``:控制器完全关闭并复位;

  • ``4`` – ``CAN.BUS_OFF``:控制器仍开启但不再参与总线(TEC溢出超过255);

  • ``5`` – ``CAN.RECOVERING``:控制器正在进行总线恢复。

  • ``6`` – ``CAN.RUNNING``:控制器可以发送并接收消息;

UiFlow2 代码块:

state.png

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 代码块:

info.png

MicroPython 代码块:

info = can.info()
any(fifo)

若FIFO中存在待处理消息则返回``True``,否则返回``False``。

参数:

fifo (int) – FIFO 索引。

返回:

bool

UiFlow2 代码块:

any.png

MicroPython 代码块:

if can.any(0):
    print("Message waiting")
recv(fifo, list=None, *, timeout=5000)

在总线上接收数据。

参数:
  • fifo (int) – fifo为整数,可为任意数值,与pyb.CAN兼容。

  • list (list) – 可选的列表对象,用作返回值。

  • timeout (int) – 等待接收的超时时间(毫秒)。

返回:

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 代码块:

recv1.png

recv2.png

MicroPython 代码块:

can.recv(0)
send(data, id, *, timeout=0, rtr=False, extframe=False)

在总线上发送消息。

参数:
  • data – data为要发送的数据(可以是整数或缓冲对象)。

  • id (int) – id为要发送的消息ID。

  • timeout (int) – timeout为等待发送的超时时间(毫秒)。

  • rtr (bool) – rtr是布尔值,指示是否以远程帧发送消息。若rtr为True,则仅使用data的长度填充帧的DLC字段,data中的字节不会被使用。

  • extframe (bool) – extframe为True时帧使用扩展标识符(29位),否则使用标准标识符(11位)。

当timeout为0时,消息会被放入三个硬件缓冲区之一并立即返回;如果三个缓冲区都在使用,则会抛出异常。timeout非0时,方法会等待消息发送;若在指定时间内无法发送成功则抛出异常。

返回:

None

UiFlow2 代码块:

send.png

MicroPython 代码块:

can.send('message!', 123)
NORMAL
NO_ACKNOWLEDGE
LISTEN_ONLY

在 :meth:`~CAN.init()` 中使用的CAN总线模式。

STOPPED
RUNNING
BUS_OFF
RECOVERING

Possible states of the CAN controller returned from :meth:`~CAN.state()`.