过程数据对象PDO
PDO一般用于实时数据更新;其分为接收PDO(RxPDO)和发送PDO(TxPDO),前者的数据流方向是主站到从站,TxPDO是从站到主站。
PDO功能支持同步周期的刷新方式,也支持非周期性的更新方式。当主站选择为分布式时钟同步模式时,PDO将同步周期更新;如果选择自由运行模式,那么PDO数据的更新是非周期性的。
过程数据可以包含多个PDO映射数据对象,COE协议使用数据对象0x1C10-0x1C2F定义相应的SM通道的PDO映射对象列表,以TxPDO为例,输出通道使用SM2通道,由对象数据0x1C12定义PDO分配,如下图所示,
PDO映射
通过PDO映射,可实现映射对象的实时传输。PDO映射内容的格式如下表,
表1 PDO映射内容的格式
位 | 31~16 | 15~8 | 7~0 |
内容 | 映射内容的索引 | 映射内容的子索引 | 位长(16进制) |
例子 | 6040h | 00h | 10h |
一款Ethercat驱动器的默认PDO映射(与XML文件一致),如下表所示,
PDO映射对象索引 | PDO映射对象子索引 | 映射内容 | 映射内容名称 |
RXPDO1 1600h | 01h | 60400010 | 控制字 |
02h | 607a0020 | 目标位置 |
03h | 60b80020 | 探针功能 |
RXPDO2 1601h | 01h | 60400010 | 控制字 |
02h | 60ff0020 | 目标速度 |
03h | 60b20010 | 转矩前馈 |
RXPDO3 1602h | 01h | 60400010 | 控制字 |
02h | 60710010 | 目标转矩 |
03h | 60870020 | 转矩变量率 |
RXPDO4 1603h | 01h | 60400010 | 控制字 |
02h | 60980008 | 原点方法 |
03h | 60990120 | 原点速度(快) |
04h | 60990220 | 原点速度(慢) |
05h | 609a0020 | 原点加减速 |
06h | 607c0020 | 原点偏移 |
07h | 60600008 | 操作模式 |
TXPDO1 1A00h | 01h | 603f0000 | 错误码 |
02h | 60410000 | 状态字 |
03h | 60610000 | 显示操作模式 |
04h | 60640000 | 实际位置 |
05h | 60b90020 | 探针状态 |
06h | 60ba0020 | 探针1上升沿位置 |
07h | 60fd0020 | 数字输入 |
TXPDO2 1A01h | 暂无默认映射 |
PDO动态映射设置过程
下面的配置PDO映射例子代码,第一步与最后一步没有。
设置PDO映射表示例代码
static int drive_write8(uint16 slave, uint16 index, uint8 subindex, uint8 value){int wkc;wkc = ec_SDOwrite(slave, index, subindex, FALSE, sizeof(value), &value, EC_TIMEOUTRXM);return wkc;}static int drive_write16(uint16 slave, uint16 index, uint8 subindex, uint16 value){int wkc;wkc = ec_SDOwrite(slave, index, subindex, FALSE, sizeof(value), &value, EC_TIMEOUTRXM);return wkc;}static int drive_write32(uint16 slave, uint16 index, uint8 subindex, int32 value){int wkc;wkc = ec_SDOwrite(slave, index, subindex, FALSE, sizeof(value), &value, EC_TIMEOUTRXM);return wkc;}// 该函数用于设置PDO映射表int drive_setup(uint16 slave){int wkc = 0;printf("Drive setup\n");wkc += drive_write16(slave, 0x1C12, 0, 0);wkc += drive_write16(slave, 0x1C13, 0, 0);wkc += drive_write16(slave, 0x1A00, 0, 0);wkc += drive_write32(slave, 0x1A00, 1, 0x60410010); // Statuswordwkc += drive_write32(slave, 0x1A00, 2, 0x60640020); // Position actual valuewkc += drive_write32(slave, 0x1A00, 3, 0x606C0020); // Velocity actual valuewkc += drive_write32(slave, 0x1A00, 4, 0x60770010); // Torque actual valuewkc += drive_write32(slave, 0x1A00, 5, 0x60610008); // Modes of operation displaywkc += drive_write32(slave, 0x1A00, 6, 0x230A0020); // 2nd Poswkc += drive_write8(slave, 0x1A00, 0, 6);wkc += drive_write8(slave, 0x1600, 0, 0);wkc += drive_write32(slave, 0x1600, 1, 0x60400010); // Controlwordwkc += drive_write32(slave, 0x1600, 2, 0x60710010); // Target torquewkc += drive_write32(slave, 0x1600, 3, 0x607A0020); // Target positionwkc += drive_write32(slave, 0x1600, 4, 0x60FF0020); // Target velocitywkc += drive_write32(slave, 0x1600, 5, 0x60600008); // Modes of operation displaywkc += drive_write32(slave, 0x1600, 6, 0x60B20010); // Torque offsetwkc += drive_write8(slave, 0x1600, 0, 6);wkc += drive_write16(slave, 0x1C12, 1, 0x1600);wkc += drive_write8(slave, 0x1C12, 0, 1);wkc += drive_write16(slave, 0x1C13, 1, 0x1A00);wkc += drive_write8(slave, 0x1C13, 0, 1);strncpy(ec_slave[slave].name, "Drive", EC_MAXNAME);if (wkc != 22){printf("Drive %d setup failed\nwkc: %d\n", slave, wkc);return -1;}elseprintf("Drive %d setup succeed.\n", slave);return 0;}