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
表示can0
,1
表示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.EXT
或can.STD
)。- 返回值:
boolean
。
(2) 数据收发
can.tx(id, msg_id, id_type, RTR, need_ack, data)
- 功能:发送 CAN 消息。
-
参数:
id
:总线 ID。msg_id
:消息 ID。id_type
:帧类型(can.EXT
或can.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)