2023年1月29日开始启动


原理图依旧三板斧,DGND+AGND是重点,PCB中常规的4层布线,规则过孔16mil/8mil
PCB在打样中,现在分析Ethecat源码,用的是开源项目SOEM

通讯原理如同一列火车,到达站点IN和OUT数据,每个站点都有一个时间点,用DC技术来同步,数据中有几个重要的概念
PDO:过程对象数据,用来传输实时短帧数据
SDO:服务对象数据,配置和获得节点的配置参数
运行状态:如下4种,正常顺序1234执行
init:上电的初始状态,可以读取从站的设备信息和做一些准备进入pre-op初始化的配置
pre-op:配置好FMMU的映射
safe-op:主要把pdo中的数据设置的从站中,确认从站是否会报错,判断DC同步
OP:就可以对伺服进行运动控制

伺服电机驱动状态机,程序中的控制字(已经深底),无视这个5,只是防止水印遮住重要部分

用了canopen中的DS402的状态字,简单分析一下就是上电后bit0打开,让参数可以设置,然后使能操作


读取状态较多,不一一分析,具体见下面解释
RTSO(准备开启)
值=“ 1”:控制器处于“准备接通”状态(取决于其他位,请参见以下位掩码)
SO(打开)
值=“ 1”:控制器处于“打开”状态(取决于其他位,请参见以下位掩码)
OE(已启用操作)
值=“ 1”:控制器处于“操作启用”状态(取决于其他位,请参见以下位掩码)
FAULT
故障错误发生
VE (Voltage Enabled)
施加电压
QS (Quick Stop)
值=“ 0”:控制器处于“快速停止”状态(取决于其他位,请参见以下位掩码)
SOD (Switched On Disabled)
值=“ 1”:控制器处于“已禁用开机”状态(取决于其他位,请参见以下内容)
位掩码)
WARN (Warning)
值=“ 1”:警告
SYNC (synchronization)
值=“ 1”:控制器与现场总线同步; 值=“ 0”:控制器与现场总线不同步
REM (Remote)
远程(该位的值始终为“ 1”)
TARG
达到目标
ILA (Internal Limit Reached)
超出内部限位
OMS (Operation Mode Specific)
含义取决于所选的操作模式
CLA (Closed Loop Available)
值=“ 1”:自动设置成功并且看到编码器索引:可能闭环模式
切换的条件

2023年4月9日一直svn630伺服驱动器的程序
之前是理论部分,现在进行实战,用的是soem库

配置部分用sdo,这里列举了写入齿轮比。参考pdf SV630N系列伺服用户手册-CN-B08
注意,我这里都用csp模式:![]()


这段wkc = ec_receive_processdata(EC_TIMEOUTRET);
是放在定时器中,定时接受处理数据
wkc = ec_receive_processdata(EC_TIMEOUTRET);
仿照ecat_delta_0421_read_write,自己写一个(copy,换个名称而已)

void ecat_inova_sv630n_read_write(struct ecx_contextt_t *context, uint16 slave)
{
ecat_inova_sv630n_in* indata = NULL;
ecat_inova_sv630n_out* outdata = NULL;
ecat_inova_sv630n_data_t *hal_data = (ecat_inova_sv630n_data_t *)(context->slavelist[slave].hal_data);
indata = (ecat_inova_sv630n_in*)(context->slavelist[slave].inputs);
outdata = (ecat_inova_sv630n_out*)(context->slavelist[slave].outputs);
if(context->slavelist[slave].islost == TRUE)
{
//hal_data->control = 0x0;
//hal_data->csp_startup_step = 0;
}
switch(hal_data->csp_startup_step)
{
case 1:
hal_data->servo_on = 0;
hal_data->cmdpos_raw = indata->CurrentPosition;
hal_data->control = 0x06;
if(indata->StatusWord == 0x0631 || indata->StatusWord == 0x0231
|| indata->StatusWord == 0x1631)
{
hal_data->csp_startup_step = 2;
}
break;
case 2:
hal_data->control = 0x07;
if(indata->StatusWord == 0x233
|| indata->StatusWord == 0x1633)
hal_data->csp_startup_step=3;
break;
case 3:
hal_data->control = 0x0f;
if(indata->StatusWord == 0x1637
||indata->StatusWord == 0x1633)
hal_data->csp_startup_step = 4;
break;
case 4:
hal_data->control = 0x1f;
hal_data->servo_on = 1;
hal_data->cmdpos_raw_temp = 0;
hal_data->csp_pos_delay++;
if(hal_data->csp_pos_delay <= 600)
{
hal_data->cmdpos_raw = indata->CurrentPosition + 60;
}
else
{
hal_data->csp_pos_delay = 0;
//hal_data->cmdpos_raw = 0;
}
break;
default:
hal_data->csp_startup_step = 1;
hal_data->control = 0x03;
break;
}
outdata->ControlWord = hal_data->control;
outdata->TargetPos = hal_data->cmdpos_raw; //indata->CurrentPosition + 60000;
//printf("CP=%d, TP=%d \n\r", indata->CurrentPosition, outdata->TargetPos);
//outdata->TargetMode = 0x8;
hal_data->currpos_raw = indata->CurrentPosition;
}
解释如下:
indata 和outdata,是往伺服驱动器中读取和写入的数据,
hal_data是具体的值,switch case 是之前理论中的 1初始 -》 2预准备 -》3安全运行 -》4运行
hal_data结构体如下,当然,这个结构体是我自己加的,为通讯参数,

这里就是pdo(pdo是预设的(映射后加快访问速度,类似dma,点对点匹配),svn630中汇川已经给出来了,sdo是可以单独控制,类似非点对点gpio)
同样的indata和outdata也是如此


注意的点,因为是不断的发送,一次中断只能对应一个slave,所以要区分开数据
,
所以在queue_all中分布的是如此x1,x2,x1,x2,x1,x2这样的点
本文深入探讨了EtherCAT伺服驱动的实现原理与编程实践,详细分析了EtherCAT通讯原理及状态机控制流程,并通过SVN630伺服驱动器的实际案例讲解了PDO与SDO的应用。
2290

被折叠的 条评论
为什么被折叠?



