igh ethercat雷赛556步进例程
时间: 2023-09-11 11:05:06 浏览: 187
IGH的EtherCAT通信的实时通信例程,直接编写Makefile来实现编译
以下是使用EtherCAT通信协议的雷塞(Leisai)556步进驱动器的示例程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ecrt.h"
#define REFRESH_RATE 1000 // 刷新率(单位:微秒)
#define PI 3.14159265358979323846
// EtherCAT配置
#define ECAT_TIMEOUT 5000 // 超时时间(单位:毫秒)
#define ECAT_SLAVE 0, 0 // 从站地址
// 雷塞556参数
#define MAX_SPEED 3000 // 最大速度(单位:rpm)
#define MAX_ACC 1000 // 最大加速度(单位:rpm/s)
// 定义PDO映射索引
#define PDO_INPUT_INDEX 0x1601
#define PDO_OUTPUT_INDEX 0x1A02
// 定义PDO映射子索引
#define PDO_INPUT_SUBINDEX_POSITION 0x00
#define PDO_INPUT_SUBINDEX_VELOCITY 0x02
#define PDO_INPUT_SUBINDEX_TORQUE 0x03
#define PDO_OUTPUT_SUBINDEX_CONTROL 0x00
// 定义命令码
#define CMD_SET_POSITION 0x02
#define CMD_SET_VELOCITY 0x03
#define CMD_SET_TORQUE 0x04
#define CMD_SET_BIT 0x06
// 定义状态码
#define STATE_NOT_READY_TO_SWITCH_ON 0x0000
#define STATE_SWITCH_ON_DISABLED 0x0040
#define STATE_READY_TO_SWITCH_ON 0x0021
#define STATE_SWITCHED_ON 0x0023
#define STATE_OPERATION_ENABLED 0x0027
#define STATE_QUICK_STOP_ACTIVE 0x0007
#define STATE_FAULT 0x000F
// 定义常量
#define POSITION_FACTOR (2 * PI / 65536.0) // 位置因子(单位:弧度)
#define VELOCITY_FACTOR (2 * PI / 60.0 / 65536.0) // 速度因子(单位:弧度/秒)
#define TORQUE_FACTOR (2 * PI / 65536.0 / 0.001) // 力矩因子(单位:牛米)
// 定义全局变量
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
static ec_domain_t *domain = NULL;
static ec_domain_state_t domain_state = {};
static ec_slave_config_t *slave = NULL;
static ec_slave_config_state_t slave_state = {};
static uint8_t *domain_pd = NULL;
static ec_pdo_entry_reg_t domain_regs[] = {
{ECAT_SLAVE, PDO_OUTPUT_INDEX, PDO_OUTPUT_SUBINDEX_CONTROL, 16, &control_word},
{ECAT_SLAVE, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_POSITION, 32, &position},
{ECAT_SLAVE, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_VELOCITY, 32, &velocity},
{ECAT_SLAVE, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_TORQUE, 16, &torque},
{}
};
static uint16_t control_word = 0x0000;
static int32_t target_position = 0;
static int32_t actual_position = 0;
static int32_t actual_velocity = 0;
static int16_t actual_torque = 0;
// 定义函数
static void check_domain_state(void);
static void check_slave_config_states(void);
int main(int argc, char *argv[]) {
// 初始化EtherCAT主站
if (ecrt_init() != 0) {
printf("Failed to initialize EtherCAT master!\n");
return -1;
}
// 获取EtherCAT主站
master = ecrt_request_master(0);
if (master == NULL) {
printf("Failed to get EtherCAT master!\n");
return -1;
}
// 发现从站
if (ecrt_master_scan(master, 0) <= 0) {
printf("No EtherCAT slaves found!\n");
return -1;
}
// 获取从站配置
slave = ecrt_master_slave_config(master, ECAT_SLAVE);
if (slave == NULL) {
printf("Failed to get slave configuration!\n");
return -1;
}
// 创建EtherCAT域
domain = ecrt_master_create_domain(master);
if (domain == NULL) {
printf("Failed to create EtherCAT domain!\n");
return -1;
}
// 注册PDO映射
if (ecrt_domain_reg_pdo_entry_list(domain, domain_regs) < 0) {
printf("Failed to register PDO entry list!\n");
return -1;
}
// 计算PDO映射
if (ecrt_master_application_time(master, REFRESH_RATE) != 0) {
printf("Failed to set application time!\n");
return -1;
}
if (ecrt_master_sync_reference_clock(master) != 0) {
printf("Failed to sync reference clock!\n");
return -1;
}
if (ecrt_domain_size(domain) > 0x1000) {
printf("Domain size exceeds 4KB!\n");
return -1;
}
domain_pd = ecrt_domain_data(domain);
// 配置从站
if (ecrt_slave_config_pdos(slave, EC_RT_MODE_3, 1, NULL, NULL) != EC_SUCCESS) {
printf("Failed to configure PDOs!\n");
return -1;
}
// 配置从站状态
if (ecrt_slave_config_map(slave) < 0) {
printf("Failed to configure slave state!\n");
return -1;
}
// 检查主站状态
ecrt_master_receive(master);
check_domain_state();
if (master_state.al_states != 0) {
printf("EtherCAT master is not in the AL state!\n");
return -1;
}
// 检查从站状态
ecrt_master_receive(master);
check_slave_config_states();
if (slave_state.al_state != 0) {
printf("EtherCAT slave is not in the AL state!\n");
return -1;
}
// 初始化从站
control_word = 0x0006; // 将控制字设置为“Switch On + Enable Operation”
ecrt_domain_queue(domain);
ecrt_master_send(master);
ecrt_master_receive(master);
check_domain_state();
if (actual_position != 0) {
printf("Failed to initialize the drive!\n");
return -1;
}
// 设置驱动器参数
control_word = 0x0007; // 将控制字设置为“Switch On + Enable Operation + Quick Stop”
ecrt_domain_queue(domain);
ecrt_master_send(master);
ecrt_master_receive(master);
check_domain_state();
if (actual_position != 0) {
printf("Failed to set drive parameters!\n");
return -1;
}
// 启动驱动器
control_word = 0x000F; // 将控制字设置为“Switch On + Enable Operation + Quick Stop + Enable Interpolated Position Mode”
ecrt_domain_queue(domain);
ecrt_master_send(master);
ecrt_master_receive(master);
check_domain_state();
if (actual_position != 0) {
printf("Failed to start the drive!\n");
return -1;
}
// 循环运行
while (1) {
// 读取当前位置、速度和力矩
ecrt_master_receive(master);
actual_position = *((int32_t *)(domain_pd + ecrt_slave_config_reg_pdo_entry_offset(slave, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_POSITION)));
actual_velocity = *((int32_t *)(domain_pd + ecrt_slave_config_reg_pdo_entry_offset(slave, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_VELOCITY)));
actual_torque = *((int16_t *)(domain_pd + ecrt_slave_config_reg_pdo_entry_offset(slave, PDO_INPUT_INDEX, PDO_INPUT_SUBINDEX_TORQUE)));
// 显示当前状态
switch (control_word & 0x006F) {
case STATE_NOT_READY_TO_SWITCH_ON:
printf("Drive is in the Not Ready to Switch On state.\n");
break;
case STATE_SWITCH_ON_DISABLED:
printf("Drive is in the Switch On Disabled state.\n");
break;
case STATE_READY_TO_SWITCH_ON:
printf("Drive is in the Ready to Switch On state.\n");
break;
case STATE_SWITCHED_ON:
printf("Drive is in the Switched On state.\n");
break;
case STATE_OPERATION_ENABLED:
printf("Drive is in the Operation Enabled state.\n");
break;
case STATE_QUICK_STOP_ACTIVE:
printf("Drive is in the Quick Stop Active state.\n");
break;
case STATE_FAULT:
printf("Drive is in the Fault state.\n");
break;
default:
printf("Drive is in an unknown state.\n");
break;
}
// 设置目标位置
if (control_word & 0x001F == STATE_OPERATION_ENABLED) {
target_position += (int32_t)(MAX_SPEED * REFRESH_RATE / 1000000.0);
if (target_position > 65536) {
target_position -= 65536;
}
*((int32_t *)(domain_pd + ecrt_slave_config_reg_pdo_entry_offset(slave, PDO_OUTPUT_INDEX, PDO_OUTPUT_SUBINDEX_CONTROL))) = CMD_SET_POSITION | (target_position << 8);
}
// 刷新PDO
ecrt_domain_queue(domain);
ecrt_master_send(master);
usleep(REFRESH_RATE);
}
// 停止驱动器
control_word = 0x0007; // 将控制字设置为“Switch On + Enable Operation + Quick Stop”
ecrt_domain_queue(domain);
ecrt_master_send(master);
ecrt_master_receive(master);
check_domain_state();
if (actual_position != 0) {
printf("Failed to stop the drive!\n");
return -1;
}
// 释放EtherCAT主站
ecrt_release_master(master);
master = NULL;
// 结束程序
return 0;
}
static void check_domain_state(void) {
ecrt_master_state(master, &master_state);
ecrt_domain_state(domain, &domain_state);
}
static void check_slave_config_states(void) {
ecrt_slave_config_state(slave, &slave_state);
}
```
这个示例程序使用了EtherCAT通信协议来控制雷塞(Leisai)556步进驱动器。程序中定义了一些常量和全局变量,包括刷新率、PDO映射、命令码、状态码等。程序首先初始化EtherCAT主站,并发现从站。然后,程序创建一个EtherCAT域,并注册PDO映射。接下来,程序配置从站和从站状态,并初始化驱动器。程序循环运行,读取当前位置、速度和力矩,并根据控制字设置目标位置。最后,程序停止驱动器并释放EtherCAT主站。
请注意,这只是一个示例程序,具体实现可能因驱动器型号和应用场景而异。在实际应用中,请根据实际情况进行调整。
阅读全文