一、前言
上一节演示了一些能控制CANopen节点的CAN报文,这些都是节点状态切换命令。值得注意的是,这些节点状态切换命令不一定非要CANopen主站发送,CANopen从站也可以发送这些NMT报文。我们可以在STM32的程序里面编写一段代码,在某些条件下,调用FDCAN底层直接发送CAN报文,控制CANopen网络上的各个CANopen节点(包括节点状态切换命令)。
CANopen节点的状态切换的示意图:
准备好硬件:
1、STM32H743开发板(已经移植CANopen协议)
2、CAN盒子
二、命令
2.1、启动命令0x01
启动命令最常用了,请务必掌握使用。在上一章说到,CANopen节点处于操作状态时,PDO功能才启动。很多同学在调试CANopen节点时忘记这一点,不知道为什么CANopen节点没有发送PDO,也不能接收PDO。还以为PDO的发送参数,PDO的映射对象设置有问题。结果搞了半天才发现CANopen节点的状态不对,最后往CANopen从站发送一条NMT报文就解决了问题(其实就是将CANopen节点的状态切换至Operational,使能PDO功能)。
从下图可以看到,预操作状态与操作状态可以互相切换。
让CAN总线上所有节点进入操作状态。发送的CAN报文格式如下:
- CANID :0x000
- 帧长度:0x02
- 帧类型:数据帧(CANopen协议只会用数据帧,淘汰了远程帧)
- 数据段:0x01,0x00
让某个节点进入操作状态,发送的CAN报文格式如下: - CANID : 0x00
- 帧长度:0x02
- 帧类型:数据帧
- 数据段:0x01,0x05(节点的Node-ID)
2.2、停止命令0x02
在实际工作上,CANopen网络上连接着十几个,甚至可能有数十个CANopen节点。如果我只想关注Node-ID为0x05的节点发出来的CAN报文,其他所有CANopen节点的CAN报文我都不想看到(包括心跳报文)。此时,我可以发出NMT管理报文,先让所有的CANopen节点进入停止状态,CANopen网络上将看不到任何报文。接着,我发送NMT报文复位节点应用层(81h),让CANopen节点(0x05)复位。
其实,针对这种情况,我还有一个终极大招:将其他CANopen节点的电源都关闭,让它们没有办法工作!!
在CANbus总线上发送以下指令:
- CANID : 0x00
- 帧长度:0x02
- 帧类型:数据帧
- 数据段:0x02,0x00(总线上所有节点)
有意思的是,CANopen从站收到该命令后,心跳报文停止了。
2.3、进入预状态0x80
在CANbus总线上发送以下指令,可以让CANopen节点回到预操作状态。此时,CANopen节点的PDO功能被关闭,SDO功能正常使用。
- CANID : 0x00
- 帧长度:0x02
- 帧类型:数据帧
- 数据段:0x80,0x05(Node-ID为0x05的CANopen节点)
2.4、复位节点应用层0x81
“复位节点应用层“非常常用。每一个CANopen节点都有一份对象字典,我们可以通过发送CAN报文去修改某个CANopen节点上的对象字典。万一不小心将对象字典修改错了,CANopen节点出现了奇怪的现场。此时,比如我们想复位这个CANopen从站,让它的对象字典回到初始化的状态。有两种方法可以解决:1、重启CANopen节点的电源,让CANopen节点的系统复位(简单暴力)。2、使用”复位节点应用层“命令,让某个CANopen节点的软件进行复位。
- CANID : 0x00
- 帧长度:0x02
- 帧类型:数据帧
- 数据段:0x81,0x05(Node-ID为0x05的CANopen节点)
2.5、复位节点通讯0x82
跟上面的那些指令的用法类似,同学们自行尝试。