外观
EtherCAT 双轴电机示例
2026-01-29
本示例专门针对一拖二的电机驱动器设计,推荐测试的型号为汇川的 SV630ND。通过创建一个 EtherCAT Master 实例,完成对 EtherCAT 伺服控制器的初始化配置,使伺服电机控制器工作在CSP同步周期位置模式,实现对双轴电机的同时控制。
EtherCAT 双轴电机
硬件连接
需要准备硬件:
- 睿擎工业开发平台支持板卡 1 块(
睿擎派 RC3506) - EtherCAT 一拖二伺服驱动器一套(推荐
汇川 SV630ND) - 串口调试器、jlink 调试各一套
用网线将伺服控制器 IN 口与开发板 ETH 网口连接。伺服电机的电源线和编码器线分别接入电源口和对应的轴连接口,本示例专门针对一拖二电机驱动器设计,支持同时控制两个轴。
创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化设备树

固化 APP

控制命令
| 命令 | 功能描述 | 使用示例 |
|---|---|---|
ect_csp | 启动 EtherCAT 主站服务 | ect_csp |
motor_run | 启动电机运行 | motor_run |
motor_stop | 停止电机运行 | motor_stop |
motor_dir [dir] | 设置电机转动方向(0 或 1) | motor_dir 0 |
核心示例代码
初始化 EtherCAT 主站及配置
- EtherCAT 服务初始化:首先调用
ecat_service_init()函数初始化 EtherCAT 主站服务的核心组件。 - 网络接口配置:指定 EtherCAT 主站使用的网络接口,如 "e1"。
- 主站结构体初始化:通过
ecat_master_init(&csp_master)函数初始化主站结构体。 - 从站配置:为每个从站配置 PDO 映射和同步信息。
ethercat_motor_2asix.c
ecat_service_init();
if (ifname)
{
csp_master.nic0 = ifname;
}
err = ecat_master_init(&csp_master);
if (err)
{
rt_kprintf("ethercat master init failed, err:%d\n", err);
return err;
}
slave_counts = ecat_slavecount(&csp_master);
rt_kprintf("Found slaves count:%d\n", slave_counts);
static ec_slave_config_t slave_cia402_config;
slave_cia402_config.dc_assign_activate = 0x300;
slave_cia402_config.dc_sync[0].cycle_time = csp_master.main_cycletime_us * 1000;
slave_cia402_config.dc_sync[0].shift_time = 500000;
slave_cia402_config.dc_sync[1].cycle_time = 0;
slave_cia402_config.dc_sync[1].shift_time = 0;
slave_cia402_config.pdo_callback = pdo_callback;
slave_cia402_config.sync = slave_syncs;
slave_cia402_config.sync_count = sizeof(slave_syncs) / sizeof(ec_sync_info_t);
for(int i = 0; i < slave_counts; i++)
{
ecat_slave_config(&csp_master, i, &slave_cia402_config);
}
ecat_master_start(&csp_master);PDO 配置
- 双轴 PDO 配置:与单轴电机不同,本示例需要为两个轴分别配置 PDO 条目,轴 1 使用标准地址(如 6060h),轴 2 使用偏移地址(如 6860h)。
- 输出 PDO 配置:分别为两个轴配置输出 PDO 条目,包括模式、控制字、目标位置、目标速度和目标转矩。
- 输入 PDO 配置:分别为两个轴配置输入 PDO 条目,包括错误字、状态字、当前位置、当前速度和当前转矩。
- 同步信息配置:配置从站的同步信息,将两个轴的 PDO 分别映射到输出和输入同步管理器。
ethercat_motor_2asix.c
static ec_pdo_entry_info_t asix1_output_pdo_entries[] = {
{ 0x6060, 0x00, 8 }, // 6060h(mode)
{ 0x6040, 0x00, 16 }, // 6040h(control)
{ 0x607A, 0x00, 32 }, // 607Ah(dest position)
{ 0x60FF, 0x00, 32 }, // 60FFh(dest speed)
{ 0x6071, 0x00, 16 }, // 6071h(dest torque)
};
static ec_pdo_entry_info_t asix1_input_pdo_entries[] = {
{ 0x603F, 0x00, 16 }, // 603Fh(error)
{ 0x6041, 0x00, 16 }, // 6041h(status)
{ 0x6064, 0x00, 32 }, // 6064h(current postion)
{ 0x606C, 0x00, 32 }, // 606Ch(current speed)
{ 0x6077, 0x00, 16 }, // 6077h(current torque)
};
static ec_pdo_entry_info_t asix2_output_pdo_entries[] = {
{ 0x6860, 0x00, 8 }, // 6060h(mode)
{ 0x6840, 0x00, 16 }, // 6040h(control)
{ 0x687A, 0x00, 32 }, // 607Ah(dest position)
{ 0x68FF, 0x00, 32 }, // 60FFh(dest speed)
{ 0x6871, 0x00, 16 }, // 6071h(dest torque)
};
static ec_pdo_entry_info_t asix2_input_pdo_entries[] = {
{ 0x683F, 0x00, 16 }, // 603Fh(error)
{ 0x6841, 0x00, 16 }, // 6041h(status)
{ 0x6864, 0x00, 32 }, // 6064h(current postion)
{ 0x686C, 0x00, 32 }, // 606Ch(current speed)
{ 0x6877, 0x00, 16 }, // 6077h(current torque)
};
ec_pdo_info_t slave_pdos[] = {
{ 0x1600, 5, asix1_output_pdo_entries },
{ 0x1610, 5, asix2_output_pdo_entries },
{ 0x1a00, 5, asix1_input_pdo_entries },
{ 0x1a10, 5, asix2_input_pdo_entries },
};
ec_sync_info_t slave_syncs[] = {
{ 2, EC_DIR_OUTPUT, 2, &slave_pdos[0], EC_WD_DISABLE },
{ 3, EC_DIR_INPUT, 2, &slave_pdos[2], EC_WD_DISABLE },
};PDO 回调函数
- 双轴同步控制:与单轴电机不同,本示例通过循环遍历的方式,同时处理两个轴的 PDO 数据,实现双轴的同步控制。
- 状态机切换:通过
servo_switch_op函数实现两个伺服驱动器的状态机切换。 - 电机控制:根据
servo_run标志同时控制两个电机的启动和停止。 - 位置控制:在 CSP 模式下,根据
servo_dir标志同时设置两个电机的转动方向和目标位置。
ethercat_motor_2asix.c
void pdo_callback(uint16_t slave_index, uint8_t *output, uint8_t *input)
{
struct rpdo_csp *rmap = (struct rpdo_csp *)output;
struct tpdo_csp *tmap = (struct tpdo_csp *)input;
if (servo_run == 0)
{
do {
servo_switch_op(rmap, tmap);
rmap->control_word = 0x2;
rmap++; tmap++;
} while ((uint8_t *)rmap < input);
return;
}
do {
servo_switch_op(rmap, tmap);
if (rmap->control_word == 7) {
rmap->mode_byte = 0x8;
rmap->dest_pos = tmap->cur_pos;
}
if (rmap->control_word == 0xf) {
rmap->dest_pos = tmap->cur_pos;
if (servo_dir == 0) {
rmap->dest_pos -= 1000;
} else {
rmap->dest_pos += 1000;
}
}
rmap++; tmap++;
} while ((uint8_t *)rmap < input);
}状态机切换函数
- 状态检测:通过读取状态字
status_word检测伺服驱动器的当前状态。 - 状态切换:根据不同的状态,设置相应的控制字
control_word,实现状态机的切换。
ethercat_motor_2asix.c
static void servo_switch_op(struct rpdo_csp *rmap, struct tpdo_csp *tmap)
{
int sta;
sta = tmap->status_word & 0x3ff;
if (tmap->status_word & 0x8)
{
rmap->control_word = 0x80;
return;
}
switch (sta)
{
case 0x250:
case 0x270: rmap->control_word = 0x6; break;
case 0x231: rmap->control_word = 0x7; break;
case 0x233: rmap->control_word = 0xf; break;
default: break;
}
}示例运行
初始化 EtherCAT 主站
msh > ect_csp启动电机运行
msh > motor_run改变电机方向
msh > motor_dir 0/1停止电机
msh > motor_stop使用 IDE 调试并运行程序,初始化完 EtherCAT 主站后,在终端输入motor_run 运行电机,可以观察到双轴电机同时旋转。与单轴电机示例不同,本示例通过一次命令即可同时控制两个轴的运行状态,实现双轴的同步运动。EtherCAT 示例运行后,两个电机会按照设定的方向同时旋转。驱动器风扇会开启,面板显示正常运行状态。
在终端输入motor_stop 可以停止电机。
在终端输入motor_dir 0/1 可以改变电机方向。
