跳转至

can - can操作库

示例

--[[
错误码介绍
错误码由4byte组成小端格式的uint32
byte3预留无意义
byte2方向,0TX 1RX
byte1类型,0bit 1form 2stuff
byte0位置:
0x03 start of frame
0x02 extended: ID bits 28 - 21, standard:  10 - 3
0x06 extended: ID bits 20 - 18, standard:  2 - 0
0x04 extended: substitute RTR, standard: RTR
0x05 identifier extension
0x07 extended: ID bits 17 - 13
0x0f extended: ID bits 12 - 5
0x0e extended: ID bits 4 - 0
0x0C RTR
0x0D reserved bit 1
0x09 reserved bit 0
0x0b data length code
0x0a data section
0x08 CRC sequence
0x18 CRC delimiter
0x19 ACK slot
0x1b ACK delimiter
0x1a end of frame
0x12 intermission
0x00 unspecified
]]

常量

常量 类型 解释
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.EXT number 扩展帧
can.STD 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
int PBS1, 相位缓冲段1,范围1~8
int PBS2, 相位缓冲段2,范围2~8
int SJW, 同步补偿宽度值,范围1~4,默认2

返回值

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

例子

-- air780EPM参考,不一定适合其他平台,CAN的实际波特率=基础时钟/分频系数/(1+PTS+PBS1+PBS2),详见can.capacity
-- 快速参考,50K及x2,x4,x8,x16都可以用同一个PTS+PBS1+PBS2
-- 快速参考,125K及x2,x4,x8都可以用同一个PTS+PBS1+PBS2
can.timing(0, 50000, 6, 6, 3, 2)
can.timing(0, 100000, 6, 6, 3, 2)
can.timing(0, 400000, 6, 6, 3, 2)
can.timing(0, 125000, 6, 6, 4, 2)
can.timing(0, 250000, 6, 6, 4, 2)
can.timing(0, 1000000, 6, 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位,根据id_type决定,默认值是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 << 3, 0x07) --效果等同于can.node(0, 0x12345678, CAN.EXT)
can.filter(0, false, 0x123 << 21, 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位,根据id_type决定,默认值是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.busOff(id)

CAN总线关闭,此时可以重新进行timing,filter,node等配置

参数

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

返回值

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

例子

can.busOff(0)

can.deinit(id)

CAN完全关闭

参数

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

返回值

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

例子

can.deinit(0)

can.debug(on_off)

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

参数

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

返回值

例子

can.debug(true)

can.capacity(id)

获取CAN时钟特性,包括基础时钟,分频系数范围,CAN的实际波特率=基础时钟/分频系数/(1+PTS+PBS1+PBS2),从时钟特性里能看出对应平台是否能配置出需要的波特率

参数

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

返回值

返回值类型 解释
boolean 成功返回true,失败返回false,如果失败就不用看后面的参数了
int 基础时钟
int 最小分频系数
int 最大分频系数
int 分频系数步进,一般为1

例子

local res, clk, div_min, div_max, div_step = can.capacity(0)