总线上那一堆 ID,到底谁是谁?
CANopen 协议全景,一次讲明白
第一次拿 CAN 分析仪接上一台设备,屏幕上哗啦啦刷出一堆报文。0x000、0x185、0x601、0x705,一秒钟几百条,看着头大。
但这些 ID 其实很有规律,规律搞懂之后,不用查任何手册,扫一眼就知道哪条是谁发的、在干什么。
前面几篇分别讲过 CAN 和 CANopen 的关系、心跳、SDO 和 PDO 的分工。这一篇把它们串成一张完整的图。
一、ID 不是随便编的
CANopen 的报文 ID 是 11 位,但它不是一个整体,而是拆成两段用的。
▲ 功能码加节点号,两段拼成一个 ID
前面一段叫功能码,说明这是哪一类报文。后面一段是节点号,说明是几号设备。两段一加,就是你在抓包软件里看到的那个 ID。
所以 0x185 拆开就是 0x180 加 5,意思是 5 号设备发出来的第一组过程数据。同样,0x605 是主站发给 5 号的参数请求,0x705 是 5 号的心跳。
节点号的范围是 1 到 127,一根总线上不能重号。0 是留给广播用的。
二、一张表看完所有 ID
功能码一共就那么几个,标准里全定死了,这套分配方案叫预定义连接集。
▲ 预定义连接集,对着抓包软件直接查
这张表建议存下来。调试时对着抓包窗口一查,就知道谁是谁。
有个细节值得留意:ID 数值越小,优先级越高。这是 CAN 底层的仲裁规则决定的。看这张表的排序就明白了。网络管理排最前,紧急报文紧随其后,过程数据在中间,参数读写和心跳排后面。
这个安排很合理。设备出故障要立刻报上去,不能被一堆参数读写的报文堵在后面。
顺带说一句,PDO 有四组是因为一帧只能装 8 个字节。伺服要传的东西多,一组装不下就分成好几组,这在讲 SDO 和 PDO 那篇里提过。
三、从站的四种状态
CANopen 的从站不是上电就干活的,它有四种状态,由主站控制切换。
▲ 四种状态,主站一条命令就能切
上电之后自动进入预运行。这个状态下 SDO 能用,所以主站可以往里写参数,但 PDO 还不动,设备不会有任何实际动作。
主站把参数配完,发一条启动命令,从站进入运行状态,PDO 开始周期性收发,设备才真正开始干活。
停止状态用得少,进去之后除了 NMT 和心跳什么都不剩,一般只在需要让某个节点彻底安静下来的时候用。
主站发这些命令用的是 ID 0x000,也就是全表里优先级最高的那个。报文只有两个字节,第一个是命令码,第二个是目标节点号。
第二个字节写 0,这条命令全网所有从站都执行。这是个很实用的做法。主站启动时通常就发一条 0x01 加 0x00,一嗓子让所有设备一起进运行,不用一个个点名。
四、上电到跑起来,报文是这个顺序
把前面几件事串起来,就是一台设备从上电到正常工作的完整过程。
▲ 从上电到 PDO 跑起来,报文的出场顺序
第一条出现的是从站的上电报文,ID 是 0x700 加节点号。数据只有一个字节 0x00,意思是「我上电了,现在在预运行」。主站看到这条,就知道这个节点活了。
接下来是一连串 SDO 来回。主站用 0x600 加节点号发请求,从站用 0x580 加节点号回答。参数一条条写进去,PDO 映射也在这一步配好。
参数配完,主站发一条 NMT 启动命令,ID 0x000。
从这一刻起,PDO 开始出现。0x185、0x205 这类 ID 会按设定的周期不停刷屏,这就是设备正常运行的样子。
心跳则是从预运行开始就一直在后台跳,不管处在哪个状态都不停。
抓包排查的时候,对着这个顺序看最有效。卡在哪一步,问题范围立刻就缩小了:
●连 0x700 那条上电报文都没有,说明节点根本没起来。查供电、查接线、查波特率。
●上电报文有,但 SDO 一直在重发或者报错,说明参数配置有问题。看 SDO 返回的错误码。
●SDO 都过了,但 PDO 一直不出现,说明 NMT 启动命令没发到,或者从站没接受。
●PDO 出现了但数据不对,那是映射配错了,跟通信本身没关系。
五、心跳报文里的那个字节
刚才说上电报文的数据是 0x00。其实心跳报文的那一个字节,一直在告诉你从站当前是什么状态。
心跳里的这个字节 | 从站现在的状态 | 这时候能干什么 |
0x00 | 刚上电报到 | 只发这一次,之后就变心跳了 |
0x7F | 预运行 | SDO 能用,PDO 不动 |
0x05 | 运行 | 全开,PDO 正常收发 |
0x04 | 停止 | 只剩 NMT 和心跳 |
这个设计很省事。主站不需要额外去问,光看心跳就知道每个节点活着没有、以及处在哪个状态。
有个很典型的场景。设备突然不动了,抓包一看心跳还在跳,但那个字节从 0x05 变成了 0x7F。这说明从站自己掉回预运行了,多半是内部报了故障。去看有没有 EMCY 报文就知道原因。
六、参数编号也有分区
设备里所有能读能写的东西都放在对象字典里,用编号索引。这些编号也不是乱排的。
▲ 看编号就知道这个参数归谁管
0x1000 开头这一段管通信,比如心跳时间 1017h、PDO 映射 1600h。通信规则是标准定的,所以这一段各家完全一样。
0x6000 开头这一段是设备行规。伺服驱动器遵守的是 CiA402。所以控制字一定是 6040h,实际位置一定是 6064h,换个品牌也不变。
中间 0x2000 那一段是厂家自己定的。这块最麻烦,各家想怎么定就怎么定,换个牌子完全对不上。做多品牌兼容的时候,通信部分不用改,2000 段的东西基本要重写。
所以看到一个编号,先看它落在哪一段,心里就有数了。6041h 是标准的状态字,2003h 就得翻这家的手册。<o:page></o:page>
七、EDS 文件是干嘛的
厂家会提供一个后缀是 eds 的文件,很多人不知道它有什么用,配置的时候直接跳过。
它其实就是这台设备的对象字典说明书,只不过是机器能读的格式。里面写清楚了这台设备有哪些参数、每个参数是什么类型、能不能读写、默认值是多少、能不能映射进 PDO。
主站软件把它导进去之后,配置界面里就能直接看到参数名和范围,不用你对着纸质手册一个个敲编号。改错了范围它还会提示。
有两件事要注意。一是 EDS 要和固件版本对上,固件升级换了参数,EDS 也得跟着换。二是有些便宜设备给的 EDS 不完整,实际支持的参数比文件里写的多或者少,这种只能靠实际读写去试。
八、几个实际排查的经验
●抓包的时候先按 ID 排序看一遍。这样能立刻知道总线上有几个节点、每个节点在发什么。乱序刷屏是看不出东西的。
●节点号撞车的症状很怪。两台设备用了同一个号,表现是数据时对时错、偶尔丢帧,很难查。接线的时候就要把节点号记清楚,最好贴标签在设备上。
●看到大量重发的 SDO,多半是从站没回应。可能是节点号写错了,也可能是那个参数在当前状态下不让访问。
●EMCY 报文别忽略。它的 ID 是 0x080 加节点号,优先级仅次于 NMT。设备一旦报这个,说明内部出事了,后面的现象大多是它引起的。
●PDO 突然不发了,先看心跳的状态字节。如果掉到 0x7F,那是从站自己退回预运行了,不是通信断了。
●波特率不一致的表现是完全收不到东西,或者满屏错误帧。这个跟节点号无关,是最底层的问题,要先排除。
整个 CANopen 说穿了就三件事。ID 分两段,功能码说明这是什么报文,节点号说明是谁发的。从站有四种状态,主站用 NMT 命令切换。参数都在对象字典里,按编号分区管理。这三件事想明白,抓包窗口里那堆东西就不再是天书了。
下一篇我们讲伺服的增益怎么调、惯量比意味着什么、振动了从哪儿下手。欢迎关注我们,一起把这些看着唬人的技术名词一个个拆明白。
#CANopen #CAN总线 #工业通信 #现场总线 #设备调试鼎时 <o:page></o:page>