Ethercat的stm32f407的数控机床项目(pcb实战+源码)只做主站

本文深入探讨了EtherCAT伺服驱动的实现原理与编程实践,详细分析了EtherCAT通讯原理及状态机控制流程,并通过SVN630伺服驱动器的实际案例讲解了PDO与SDO的应用。

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”:自动设置成功并且看到编码器索引:可能闭环模式

切换的条件

状态迁移part1

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这样的点

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小都爱吃小橘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值