过程数据对象用来传输设备的实时数据,是CANopen中最主要的数据传输方式。
由于PDO的传输不需要应答,且PDO的长度可以小于8个字节,因此传输速度快。
PDO的映射配置流程如下:
下面是配置代码的一部分:
case 3:
DISABLE_TPDO_COBId = 0x80000180 + nodeId; // PDO的COB-ID最高位写1,无效PDO
writeNetworkDictCallBack (d, //CO_Data* d
nodeId, //UNS8 nodeId
0x1800, //UNS16 index
0x01, //UNS8 subindex
4, //UNS8 count
0, //UNS8 dataType
&DISABLE_TPDO_COBId, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 4:
transmitiontype = 0x01; // 设置PDO的传输类型
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1800, //UNS16 index
0x02, //UNS16 index
1, //UNS8 count
uint8, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 5:
transmitiontype = 0x00; // 对映射对象的子索引0写入0,清除原有映射内容
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1A00, //UNS16 index
0x00, //UNS16 index
1, //UNS8 count
uint8, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 6:
transmitiontype = 0x60410010; // 分别写入映射参数子索引 0x01 伺服驱动器的状态字
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1A00, //UNS16 index
0x01, //UNS16 index
4, //UNS8 count
uint32, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 7:
transmitiontype = 0x60610008; // 分别写入映射参数子索引 0x02 伺服驱动器的模式显示
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1A00, //UNS16 index
0x02, //UNS16 index
4, //UNS8 count
uint32, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 8:
transmitiontype = 0x606C0020; // 分别写入映射参数子索引 0x03 伺服驱动器的用户的实际速度反馈
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1A00, //UNS16 index
0x03, //UNS16 index
4, //UNS8 count
uint32, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 9:
transmitiontype = 0x03; // 将上一步骤中写入的映射个数写到映射对象子索引0上
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1A00, //UNS16 index
0x00, //UNS16 index
1, //UNS8 count
uint8, //UNS8 dataType
&transmitiontype, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
case 10:
DISABLE_TPDO_COBId = 0x00000180 + nodeId; // PDO的COB-ID最高位写位0,有效该PDO
writeNetworkDictCallBack (&TestMaster_Data, //CO_Data* d
nodeId, //UNS8 nodeId
0x1800, //UNS16 index
0x01, //UNS16 index
4, //UNS8 count
uint32, //UNS8 dataType
&DISABLE_TPDO_COBId, //void *data
CheckSDOAndContinue, //SDOCallback_t Callback
0); // use block mode
break;
PDO的传输遵循的是生产者消费者模型,即CAN总线网络中生产者产生的TPDO可根据COB-ID由网络上一个或多个消费者RPDO接收,传输模型如下图:
通常设备中,CANopen通信只支持点对点的PDO传输方式。
按照接收与发送的不同,PDO可以分为RPDO和TPDO。PDO由通信参数和映射参数共同决定最终传输的方式及内容。
通常设备默认实现4个RPDO和4个TPDO。
常见的PDO对象列表如下图所示:
PDO的CAN标识符即PDO的COB-ID,包含控制位和标识数据,确定该PDO的总线优先级。
COB-ID位于通信参数的子索引上,最高位决定PDO是否有效。
PDO的COB-ID的最高位为“1”,表明该PDO处于无效状态;
PDO的COB-ID的最高位为“0”,表明该PDO有效,可以进行数据传输;
例如:节点3的,TPDO1在无效状态下COB-ID的值为0x80000183,当COB-ID的值为0x183时表明该PDO处于激活状态,可以进行实时数据传输。
PDO的传输类型在通信参数的子索引0x02上,决定该PDO遵循何种传输方式,
同步传输方式:主要与CAN网络中的同步帧SYNC有关;
异步传输方式:由事件触发传输,包括数据改变触发,周期性事件定时器触发;
针对TPDO设置了禁止时间,在通信参数的子索引0x03上,防止CAN网络被优先级较低的PDO持续占有。该参数的单位100us,设置数值后,同一个TPDO传输间隔不得小于该参数对应的事件。
针对异步传输,传输类型为254或255的TPDO,定义事件计时器,位于通信参数0x1800~0x1803的子索引0x05上。事件计时器也可以认为是一种触发事件,它也会触发相应的TPDO传输。
如果在计时器运行周期内出现了数据改变等其他事件,TPDO也会触发,且事件计时器会被立即复位。
PDO映射参数包含指向PDO需要发送或者接收到的PDO对应的过程数据的指针,包括索引、子索引及映射对象的长度。每一个PDO数据长度最多可达8个字节,可以同时映射一个或者多个对象,但总的不能超过8个字节。子索引0x0记录该PDO具体映射对象的个数,子索引1~8则是映射内容。
PDO映射参数内容定义如下图所示:
索引和子索引共同决定对象在对象字典中的位置,对象长度说明该对象的具体位长:
对象长度 0x08h 8位
对象长度0x10h 16位
对象长度0x20h 32位
0x1400h TPDO1-COB-ID==0x80000183
0x1401h TPDO2-COB-ID==0x80000283
0x1402h TPDO3-COB-ID==0x80000383
0x1403h TPDO4-COB-ID==0x80000483
0x1600h 0x
0x1800h RPDO1-COB-ID==0x80000203
0x1801h RPDO2-COB-ID==0x80000303
0x1802h RPDO3-COB-ID==0x80000403
0x1803h RPDO4-COB-ID==0x80000503
// 下面是实际通过上位机发送SDO指令来配置从站的一个TPDO的实例:
1.配置TPDO1
1)0x603 0x08 0x23 0x00 0x18 0x01 0x83 0x01 0x00 0x80 // 去使能TPDO1
2)0x603 0x08 0x2F 0x00 0x18 0x02 0x01 0x00 0x00 0x00 // 1个有效数据,设置TPDO1的传输类型,SYNC
3)0x603 0x08 0x2F 0x00 0x1A 0x00 0x00 0x00 0x00 0x00 // 对映射对象的子索引0x0写入0;清除原有映射内容
4)0x603 0x08 0x23 0x00 0x1A 0x01 0x10 0x00 0x41 0x60 // 写入映射对象1,0x60410010
5)0x603 0x08 0x23 0x00 0x1A 0x02 0x08 0x00 0x61 0x60 // 写入映射对象2,0x60610008
6)0x603 0x08 0x23 0x00 0x1A 0x03 0x20 0x00 0x6C 0x60 // 写入映射对象3,0x606C0020
7)0x603 0x08 0x2F 0x00 0x1A 0x00 0x03 0x00 0x00 0x00 // 映射对象的子索引0x0写入3,说明有3个映射对象
8)0x603 0x08 0x23 0x00 0x18 0x01 0x83 0x01 0x00 0x00 // 使能TPDO1
2.配置TPDO2
1)0x603 0x08 0x23 0x01 0x18 0x01 0x83 0x02 0x00 0x80 // 去使能TPDO2
2)0x603 0x08 0x2F 0x01 0x18 0x02 0x01 0x00 0x00 0x00 // 1个有效数据,设置TPDO2的传输类型,SYNC
3)0x603 0x08 0x2F 0x01 0x1A 0x00 0x00 0x00 0x00 0x00 // 对映射对象的子索引0x0写入0;清除原有映射内容
4)0x603 0x08 0x23 0x01 0x1A 0x01 0x20 0x00 0x64 0x60 // 写入映射对象1,0x60640020 Position actual value
5)0x603 0x08 0x23 0x01 0x1A 0x02 0x20 0x00 0xFD 0x60 // 写入映射对象2,0x60FD0020 Digital inputs
6)0x603 0x08 0x2F 0x01 0x1A 0x00 0x02 0x00 0x00 0x00 // 映射对象的子索引0x0写入2,说明有2个映射对象
7)0x603 0x08 0x23 0x01 0x18 0x01 0x83 0x02 0x00 0x00 // 使能TPDO2
3.配置RPDO1
1)0x603 0x08 0x23 0x00 0x14 0x01 0x03 0x02 0x00 0x80 // 去使能RPDO1
2)0x603 0x08 0x2F 0x00 0x14 0x02 0x01 0x00 0x00 0x00 // 1个有效数据,设置RPDO1的传输类型,SYNC
3)0x603 0x08 0x2F 0x00 0x16 0x00 0x00 0x00 0x00 0x00 // 对映射对象的子索引0x0写入0;清除原有映射内容
4)0x603 0x08 0x23 0x00 0x16 0x01 0x10 0x00 0x40 0x60 // 写入映射对象1,0x60400010 Control word
5)0x603 0x08 0x23 0x00 0x16 0x02 0x20 0x00 0xFF 0x60 // 写入映射对象2,0x60FF0020 Target velocity
6)0x603 0x08 0x2F 0x00 0x16 0x00 0x02 0x00 0x00 0x00 // 映射对象的子索引0x0写入3,说明有3个映射对象
7)0x603 0x08 0x23 0x00 0x14 0x01 0x83 0x01 0x00 0x00 // 使能RPDO1
4.配置RPDO2
1)0x603 0x08 0x23 0x01 0x14 0x01 0x03 0x03 0x00 0x80 // 去使能RPDO2
2)0x603 0x08 0x2F 0x01 0x14 0x02 0x01 0x00 0x00 0x00 // 1个有效数据,设置RPDO2的传输类型,SYNC
3)0x603 0x08 0x2F 0x01 0x16 0x00 0x00 0x00 0x00 0x00 // 对映射对象的子索引0x0写入0;清除原有映射内容
4)0x603 0x08 0x23 0x01 0x16 0x01 0x20 0x00 0x83 0x60 // 写入映射对象1,0x60830020 Profile acceleration
5)0x603 0x08 0x23 0x01 0x16 0x02 0x20 0x00 0x84 0x60 // 写入映射对象2,0x60840020 Profile deceleration
6)0x603 0x08 0x2F 0x01 0x16 0x00 0x02 0x00 0x00 0x00 // 映射对象的子索引0x0写入2,说明有3个映射对象
7)0x603 0x08 0x23 0x01 0x14 0x01 0x03 0x03 0x00 0x00 // 使能RPDO2
伺服驱动器上电后,使用CAN的上位机调试软件通过发送SDO的方式来配置伺服驱动器,
配置完成后,也可以通过上位机来模拟主站来发送PDO和SYNC同步对象的方式来控制伺服电机的启动、加减速和停止等功能。
下图是上位机需要发送的数据帧的截图:
模拟主站发送的TPDO1为:
COB-ID | DLC | Data |
0x203 | 0x06 | 0x06 0x00 0x2C 0x01 0x00 0x00 |
控制字:0x0006 0x0007 0x000F//控制字根据需要相应发送
目标速度:0x0000012C//300RPM
模拟主站发送的TPDO2为:
COB-ID | DLC | Data |
0x303 | 0x08 | 0x64 0x00 0x00 0x00 0x64 0x00 0x00 0x00 |
加速度:0x00000064// 100ms
减速度:0x00000064//100ms
注意事项:每发送一个PDO后,都需要通过上位机发送一个同步对象到总线上,这样PDO的内容才会被从站更新使用。
同步对象:COB-ID:0x80 DLC:0x00