跳转至

can - can操作库

以下为关键点梳理

一. 常量定义

(1)CAN 工作模式常量

  • can.MODE_NORMAL:正常工作模式。
  • can.MODE_LISTEN:监听模式(仅接收,不发送)。
  • can.MODE_TEST:自测模式(自收自发)。
  • can.MODE_SLEEP:休眠模式。

(2)CAN 状态常量

  • can.STATE_STOP:停止工作状态。
  • can.STATE_ACTIVE:主动错误状态(一般情况下为该状态)。
  • can.STATE_PASSIVE:被动错误状态(总线上错误较多时进入,但仍可正常收发)。
  • can.STATE_BUSOFF:离线状态(总线错误非常多,不能收发,需手动退出)。
  • can.STATE_LISTEN:监听状态(选择监听模式时进入)。
  • can.STATE_TEST:自收自发状态(选择自测模式时进入)。
  • can.STATE_SLEEP:休眠状态(选择休眠模式时进入)。

(3)回调消息类型常量

  • can.CB_MSG:有新数据写入缓存。
  • can.CB_TX:数据发送完成(需通过 param 判断成功/失败).
  • can.CB_ERR:错误报告(param 为错误码)
  • can.CB_STATE:总线状态变更,后续param参数是新的状态,也可以用 can.state 读出。

(4)帧格式常量

  • can.EXT:扩展帧。
  • can.STD:标准帧。

二. API 函数详解

(1) 初始化与配置

can.init(id, rx_message_cache_max)
  • 功能:初始化 CAN 总线。
  • 参数:

    • id:总线 ID(0 表示 can01 表示 can1,通常默认为 0)。
    • rx_message_cache_max:接收缓存消息数最大值(默认使用平台值)。
    • 返回值:boolean(成功返回 true,失败返回 false)。
    • 示例:
can.init()  -- 默认初始化 can0,使用默认缓存大小
can.timing(id, br, PTS, PBS1, PBS2, SJW)
  • 功能:配置 CAN 总线的波特率及时序参数。
  • 参数:

    • id:总线 ID。
    • br:波特率(默认 1Mbps)。
    • PTS:传播时间段(范围 1~8,默认 5)。
    • PBS1:相位缓冲段 1(范围 1~8,默认 4)。
    • PBS2:相位缓冲段 2(范围 2~8,默认 3)。
    • SJW:同步补偿宽度(范围 1~4,默认 2)。
    • 返回值:boolean
    • 示例:
can.timing(0, 500000, 5, 4, 3, 2)  -- 配置 500kbps 波特率
can.mode(id, mode)
  • 功能:设置 CAN 总线工作模式。
  • 参数:

    • id:总线 ID。
    • mode:模式常量(如 can.MODE_NORMAL)。
    • 返回值:boolean
    • 示例:
can.mode(0, can.MODE_NORMAL)  -- 设置为正常模式
can.filter(id, dual_mode, ACR, AMR)
  • 功能:设置消息过滤规则。
  • 参数:

    • id:总线 ID。
    • dual_mode:是否启用双滤波模式。
    • ACR:接受代码寄存器(过滤 ID 值)。
    • AMR:接受掩码寄存器(掩码值)。
    • 返回值:boolean
    • 注意:具体实现依赖硬件特性。
can.node(id, node_id, id_type)
  • 功能:设置 CAN 节点 ID 及类型。
  • 参数:

    • id:总线 ID。
    • node_id:节点 ID。
    • id_type:ID 类型(can.EXTcan.STD)。
    • 返回值:boolean

(2) 数据收发

can.tx(id, msg_id, id_type, RTR, need_ack, data)
  • 功能:发送 CAN 消息。
  • 参数:

    • id:总线 ID。
    • msg_id:消息 ID。
    • id_type:帧类型(can.EXTcan.STD)。
    • RTR:是否为远程传输请求(true/false)。
    • need_ack:是否需要应答(true/false)。
    • data:数据(数组,如 {0x01, 0x02})。
    • 返回值:无。
    • 示例:
can.tx(0, 0x123, can.STD, **false**, **true**, {0x01, 0x02})
can.rx(id)
  • 功能:接收 CAN 消息。
  • 参数:id(总线 ID)。
  • 返回值:消息数据(如 {id=0x123, data={0x01, 0x02}})。
  • 示例:
local msg = can.rx(0)
log.info("Received Message", msg)

(3) 状态与事件

can.on(id, func)
  • 功能:注册事件回调函数。
  • 参数:

    • id:总线 ID。
    • func:回调函数(参数:id, type, param)。
    • 示例:
can.on(0, function(id, type, param)
  **if** type == can.CB_MSG then
    log.info("New Message", param)
  elseif type == can.CB_ERR then
    log.error("Error", param)
  end
end)
can.state(id)
  • 功能:获取当前总线状态。
  • 参数:id
  • 返回值:状态常量(如 can.STATE_ACTIVE)。
can.stop(id)
  • 功能:停止指定总线。
  • 参数:id
can.reset(id)
  • 功能:重置总线(恢复默认配置)。
  • 参数:id
can.deinit(id)
  • 功能:反初始化总线。
  • 参数:id
can.debug(on_off)
  • 功能:启用/禁用调试信息输出。
  • 参数:on_off(布尔值)。

三. 使用建议与注意事项

1. 初始化顺序:

can.init()          -- 初始化
can.timing(...)     -- 配置波特率
can.mode(...)       -- 设置模式
can.filter(...)     -- 配置过滤器
can.on(...)         -- 注册回调

2. 消息发送与接收:

  • 使用 can.tx 发送消息,确保参数正确。

  • 通过 can.rx 拉取消息,或在回调中处理 can.CB_MSG

3. 状态监控:

  • 定期检查 can.state,处理离线状态(can.STATE_BUSOFF)。

  • 错误回调 can.CB_ERR 需记录 param 错误码。 4. 调试与性能:

  • 启用 can.debug(true) 输出底层日志。

  • 接收缓存 rx_message_cache_max 需根据需求调整,避免消息丢失。


四. 示例代码

-- 初始化并配置 CAN 总线
can.init()
can.timing(0, 500000, 5, 4, 3, 2)  -- 500kbps 波特率
can.mode(0, can.MODE_NORMAL)

-- 注册回调
can.on(0, **function**(id, type, param)
  **if** **type** == **can**.**CB_MSG** **then**
    **log**.**info**("Received:", param)
  **elseif** **type** == **can**.**CB_ERR** **then**
    **log**.**error**("Error:", param)
  **end**
**end**)

-- 发送标准帧
**can**.**tx**(0, 0x123, can.STD, **false**, **true**, {0x01, 0x02})

-- 获取当前状态
**local** **currentState** = **can**.**state**(0)
**log**.**info**("Current State:", currentState)

五. 常见问题

  • Q:如何解决 can.STATE_BUSOFF 离线状态?

    • 需先调用 can.reset(id) 恢复总线,再重新初始化配置。
    • Q:如何确保消息发送成功?

    • 通过 can.CB_TX 回调判断发送结果,或检查返回值(若 API 支持)。

    • Q:如何处理高频率消息接收?

    • 增大 rx_message_cache_max,或在回调中及时处理消息。


以下为详细说明

常量

常量 类型 解释
can.MODE_NORMAL number 正常工作模式
can.MODE_LISTEN number 监听模式
can.MODE_TEST number 自测模式
can.MODE_SLEEP number 休眠模式
can.STATE_STOP number 停止工作状态
can.STATE_ACTIVE number 主动错误状态,一般都是这个状态
can.STATE_PASSIVE number 被动错误状态,总线上错误多会进入这个状态,但是还能正常收发
can.STATE_BUSOFF number 离线状态,总线上错误非常多会进入这个状态,不能收发,需要手动退出
can.STATE_LISTEN number 监听状态,选择监听模式时进入这个状态
can.STATE_TEST number 自收自发状态,选择自测模式时进入这个状态
can.STATE_SLEEP number 休眠状态,选择休眠模式时进入这个状态
can.CB_MSG number 回调消息类型,有新数据写入缓存
can.CB_TX number 回调消息类型,数据发送结束,需要根据后续param确定发送成功还是失败
can.CB_ERR number 回调消息类型,有错误报告,后续param是错误码
can.CB_STATE number 回调消息类型,总线状态变更,后续param是新的状态,也可以用can.state读出
can.STATE_TEST number 自收自发状态,选择自测模式时进入这个状态
can.STATE_SLEEP number 休眠状态,选择休眠模式时进入这个状态

can.init(id, rx_message_cache_max)

CAN总线初始化

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
int rx_message_cache_max,接收缓存消息数的最大值,写0或者留空则使用平台默认值

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.init()

can.on(id, func)

注册CAN事件回调

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
function 回调方法

返回值

返回值类型 解释
nil 无返回值

例子

can.on(1, function(id, type, param)
    log.info("can", id, type, param)
end)

can.timing(id, br, PTS, PBS1, PBS2, SJW)

CAN总线配置时序

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
int br, 波特率, 默认1Mbps
int PTS, 传播时间段, 范围1~8,默认5
int PBS1, 相位缓冲段1,范围1~8,默认4
int PBS2, 相位缓冲段2,范围2~8,默认3
int SJW, 同步补偿宽度值,范围1~4,默认2

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.timing(0, 1000000, 5, 4, 3, 2)
can.timing(0, 650000, 9, 6, 4, 2)
can.timing(0, 500000, 5, 4, 3, 2)
can.timing(0, 250000, 5, 4, 3, 2)
can.timing(0, 125000, 5, 4, 3, 2)
can.timing(0, 100000, 5, 4, 3, 2)
can.timing(0, 50000, 9, 6, 4, 2)
can.timing(0, 25000, 9, 6, 4, 2)

can.mode(id, mode)

CAN总线设置工作模式

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
int mode, 见MODE_XXX,默认是MODE_NORMAL

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.mode(0, CAN.MODE_NORMAL)

can.node(id, node_id, id_type)

CAN总线设置节点ID,这是一种简易的过滤规则,只接收和ID完全匹配的消息,和can.filter选择一个使用

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
int node_id, 节点ID, 标准格式11位或者扩展格式29位,根据is_extend_id决定,默认值是0x1fffffff,id值越小,优先级越高
int id_type,ID类型,填1或者CAN.EXT为扩展格式,填0或者CAN.STD为标准格式

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.node(0, 0x12345678, CAN.EXT)
can.node(0, 0x123, CAN.STD)

can.filter(id, dual_mode, ACR, AMR)

CAN总线设置接收过滤模式,当can.node不满足需求时才使用这个,和can.node选择一个使用,过滤模式比较复杂,请参考SJA1000的Pelican模式下滤波

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
boolean dual_mode, 是否是双过滤模式,true是,false不是,默认是false
int ACR, 接收代码寄存器值,必须写0xnnnnnnnn这样的格式,大端格式赋值到4个ACR寄存器上,默认值是0
int AMR, 接收屏蔽寄存器值,必须写0xnnnnnnnn这样的格式,大端格式赋值到4个AMR寄存器上,对应bit写0表示需要检测,写1表示不检测,默认是0xffffffff,不过滤全接收

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.filter(0, false, 0x12345678, 0x07) --效果等同于can.node(0, 0x12345678, CAN.EXT)
can.filter(0, false, 0x123, 0x0001fffff) --效果等同于can.node(0, 0x123, CAN.STD)

can.state(id)

CAN工作状态

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条

返回值

返回值类型 解释
int 返回值见STATE_XXX

例子

can.state(0)

can.tx(id, msg_id, id_type, RTR, need_ack, data)

CAN发送一条消息

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条
int msg_id, 节点ID, 标准格式11位或者扩展格式29位,根据is_extend_id决定,默认值是0x1fffffff,id值越小,优先级越高
int id_type, ID类型,填1或者CAN.EXT为扩展格式,填0或者CAN.STD为标准格式
boolean RTR, 是否是双过滤模式,true是,false不是,默认是false
boolean need_ack,是否需要应答,true是,false不需要,默认是true
string/zbuff data, 需要发送的数据, 如果是zbuff会从指针起始位置开始发送,最多发送8字节

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.tx(id, 0x12345678, CAN.EXT, false, true, "\x00\x01\x02\x03\0x04\x05\0x6\x07")

can.rx(id)

从缓存里读出一条消息

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条

返回值

返回值类型 解释
boolean 是否读出数据,true读出,false没有读出,缓存已经空了,或者id不对
int 消息ID
int ID类型,1或者CAN.EXT为扩展格式,0或者CAN.STD为标准格式
boolean 是否是遥控帧,true是,false不是
string 数据

例子

local succ, id, type, rtr, data = can.rx(0)

can.stop(id)

立刻停止当前的发送

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.stop(0)

can.reset(id)

CAN总线复位,一般用于从总线关闭状态恢复成主动错误

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.reset(0)

can.deinit(id)

CAN完全关闭

参数

传入值类型 解释
int id, 如果只有一条总线写0或者留空, 有多条的,can0写0,can1写1, 如此类推, 一般情况只有1条

返回值

返回值类型 解释
boolean 成功返回true,失败返回false

例子

can.state(0)

can.debug(on_off)

CAN debug开关,打开后有更详细的打印

参数

传入值类型 解释
boolean true打开,false关闭
return nil

返回值

例子

can.debug(true)