EtherCAT从设备输入输出实现

EtherCAT从站功能

EtherCAT是由德国BECKHOFF公司开发的一种通讯协议,并在2003年成立了ETG工作组,EtherCAT是一个可用于现场级别的超高速I/O,它使用标准的以太网物理层和常规的以太网卡,介质可以为双绞线或光纤,下面将介绍EtherCAT从站常用的数字量IO在通讯协议层的配置与应用,此处不介绍部分算法的实现以及滤波函数的实现。

PDO映射关系

首先我们在实现我们的从站功能时先确定有哪些类型的输入输出,然后再确定输入输出的个数。在此处我们实现8个DI,8个DO。
8个数字量输入我们分别分配索引0x1A00,子索引6000:01~6000:08。如下表所示

索引子索引IEC Type C type size
0x1A006000:01BOOL BOOL0.1
6000:02BOOL BOOL0.1
6000:03BOOL BOOL0.1
6000:04BOOL BOOL0.1
6000:05BOOL BOOL0.1
6000:06BOOL BOOL0.1
6000:07BOOL BOOL0.1
6000:08BOOL BOOL0.1
8个数字量输出我们分别分配索引0x1600,子索引7000:01~7000:08。如下表所示
索引子索引IEC Type C type size
0x16007000:01BOOL BOOL1bit
7000:02BOOL BOOL1bit
7000:03BOOL BOOL1bit
7000:04BOOL BOOL1bit
7000:05BOOL BOOL1bit
7000:06BOOL BOOL1bit
7000:07BOOL BOOL1bit
7000:08BOOL BOOL1bit

数字量DI,DO

对于输入数出模块的增加我们先要修改STM32代码:

STM32 程序修改el9800appl.h

  1. 修改对象0x1A00的数据结构TOBJ1A00;
/** \brief 0x1A00 (Digital input TxPDO) data structure*/
typedef struct OBJ_STRUCT_PACKED_START {
   UINT16   u16SubIndex0; 	         /**< \brief SubIndex 0*/
   UINT32   aEntries[8];			 /**< \brief Entry buffer*/
} OBJ_STRUCT_PACKED_END
TOBJ1A00;
  1. 修改对象0x1600的数据结构体TOBJ1600
/** \brief 0x1600(Digital output RxPDO) data structure*/
typedef struct OBJ_STRUCT_PACKED_START {
   UINT16   u16SubIndex0;           /**< \brief SubIndex 0*/
   UINT32   aEntries[8];            /**< \brief Entry buffer*/
} OBJ_STRUCT_PACKED_END
TOBJ1600;
  1. 在函数PROTO TOBJ1A00 sDITxPDOMap中修改对象0x1A00的变量来处理对象数据
PROTO TOBJ1A00 sDITxPDOMap
 = {8, 
  {0x60000101, 
   0x60000201, 
   0x60000301,
   0x60000401,
   0x60000501, 
   0x60000601, 
   0x60000701, 
   0x60000801, }
   };
  1. 在函数PROTO TOBJ1601 sDORxPDOMap中修改对象0x1600的变量来处理数据
PROTO TOBJ1601 sDORxPDOMap
= {8,
 {0x70000101, 
  0x70000201,
  0x70000301, 
  0x70000401,
  0x70000501, 
  0x70000601, 
  0x70000701, 
  0x70000801, }
  };

5.在结构体OBJCONST TSDOINFOENTRYDESC OBJMEM asEntryDesc0x1A00[] 中修改对象0x1A00的条目的描述

OBJCONST TSDOINFOENTRYDESC	OBJMEM asEntryDesc0x1A00[] = {
  {DEFTYPE_UNSIGNED8, 0x8, ACCESS_READ },
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}};

6.在结构体OBJCONST TSDOINFOENTRYDESC OBJMEM asEntryDesc0x1600[]中修改对象0x1600的条目的描述

OBJCONST TSDOINFOENTRYDESC	OBJMEM asEntryDesc0x1600[] = {
  {DEFTYPE_UNSIGNED8, 0x8, ACCESS_READ },
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
  {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}};

7.修改TOBJ6000的结构体

/** \brief 0x6000 (Digital input object) data structure*/
typedef struct OBJ_STRUCT_PACKED_START {
   UINT16   u16SubIndex0; /**< \brief SubIndex 0*/
   BOOLEAN(bSwitch1); /**< \brief Switch 1*/
   BOOLEAN(bSwitch2); /**< \brief Switch 2*/
   BOOLEAN(bSwitch3); /**< \brief Switch 3*/
   BOOLEAN(bSwitch4); /**< \brief Switch 4*/
   BOOLEAN(bSwitch5); /**< \brief Switch 5*/
   BOOLEAN(bSwitch6); /**< \brief Switch 6*/
   BOOLEAN(bSwitch7); /**< \brief Switch 7*/
   BOOLEAN(bSwitch8); /**< \brief Switch 8*/
   UINT8(SubIndex008) 
} OBJ_STRUCT_PACKED_END
TOBJ6000;

8.修改TOBJ7000的结构体

/** \brief 0x7000 (Digital output object) data structure*/
typedef struct OBJ_STRUCT_PACKED_START {
   UINT16   u16SubIndex0; /**< \brief SubIndex 0*/
   BOOLEAN(bLED1); /**< \brief LED 1*/
   BOOLEAN(bLED2); /**< \brief LED 2*/
   BOOLEAN(bLED3); /**< \brief LED 3*/
   BOOLEAN(bLED4); /**< \brief LED 4*/
   BOOLEAN(bLED5); /**< \brief LED 5*/
   BOOLEAN(bLED6); /**< \brief LED 6*/
   BOOLEAN(bLED7); /**< \brief LED 7*/
   BOOLEAN(bLED8); /**< \brief LED 8*/
   UINT8(SubIndex008) 
} OBJ_STRUCT_PACKED_END
TOBJ7000;

9.修改函数OBJCONST TSDOINFOENTRYDESC OBJMEM asEntryDesc0x6000[]

OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0x6000[] = {
   {DEFTYPE_UNSIGNED8, 0x8, ACCESS_READ }, /* Subindex 000 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 001: Switch 1 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 002: Switch 2 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 003: Switch 3 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 004: Switch 4 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 005: Switch 5 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 006: Switch 6 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 007: Switch 7 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_TXPDOMAPPING}, /* SubIndex 008: Switch 8 */
}; 

10.修改函数OBJCONST TSDOINFOENTRYDESC OBJMEM asEntryDesc0x7000[]

OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0x7000[] = {
   {DEFTYPE_UNSIGNED8, 0x8, ACCESS_READ }, /* Subindex 000 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 001: LED 1 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 002: LED 2 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 003: LED 3 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 004: LED 4 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 005: LED 5 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 006: LED 6 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 007: LED 7 */
   {DEFTYPE_BOOLEAN, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 008: LED 8 */
};

11.修改OBJCONST UCHAR OBJMEM aName0x6000[]

OBJCONST UCHAR OBJMEM aName0x6000[]= {
						/* 0  */  "DI Inputs" "\000"
						/* 1  */  "Switch 1" "\000"\
						/* 2  */  "Switch 2" "\000"\
						/* 3  */  "Switch 3" "\000"\
						/* 4  */  "Switch 4" "\000"\
						/* 5  */  "Switch 5" "\000"\
						/* 6  */  "Switch 6" "\000"\
						/* 7  */  "Switch 7" "\000"\
						/* 8  */  "Switch 8" "\000"\
						\377"
						};

12.修改OBJCONST UCHAR OBJMEM aName0x7000[]

OBJCONST UCHAR OBJMEM aName0x7010[] = {
						/* 0  */  "DO Outputs\000
						/* 1  */  "LED 1"   "\000"\
						/* 1  */  "LED 2"   "\000"\
						/* 1  */  "LED 3"   "\000"\
						/* 1  */  "LED 4"   "\000"\
						/* 1  */  "LED 5"   "\000"\
						/* 1  */  "LED 6"   "\000"\
						/* 1  */  "LED 7"   "\000"\
						/* 1  */  "LED 8"   "\000"\
						\377"
       					 };

13.修改PROTO TOBJ6000 sDIInputs

PROTO TOBJ6000 sDIInputs= {
	 8, 
	 0x00, 
	 0x00, 
	 0x00, 
	 0x00, 
	 0x00, 
	 0x00, 
	 0x00, 
	 0x00};

14.修改PROTO TOBJ7000 sDOOutputs

PROTO TOBJ7000 sDOOutputs= {
	 8, 
     0x00, 
     0x00, 
     0x00, 
     0x00, 
     0x00, 
     0x00, 
     0x00, 
     0x00};

STM32程序需要修改el9800appl.c文件的函数

1.修改函数void APPL_InputMapping(UINT16* pData)。

void APPL_InputMapping (UINT16* pData /*pointer to input process data*/)
{
  UINT16 j;
  UINT8 *pTmpData = (UINT8 *)pData;
  for (j = 0; j < sTxPDOassign.u16SubIndex0; j++) 
  {
    switch (sTxPDOassign.aEntries[j])
     {
      case 0x1A00:
        bsp_analog_input_update();
        memcpy(pTmpData, &_TOBJ6000.SubIndex008, sizeof(_TOBJ6000.SubIndex008));
        pTmpData += sizeof(_TOBJ6000.SubIndex008);
    }
  }
}

2.修改函数void APPL_OutputMapping(UINT16* pData)。

void APPL_OutputMapping (UINT16 * pData /*pointer to output process data*/)
{
  UINT16 j = 0;
  UINT8 *pTmpData = (UINT8 *)pData;

  for (j = 0; j < sRxPDOassign.u16SubIndex0; j++) {
    switch (sRxPDOassign.aEntries[j]) {
      case 0x1600:
        memcpy(&_TOBJ7000.SubIndex008, pTmpData, sizeof(_TOBJ7000.SubIndex008));
        pTmpData += sizeof(_TOBJ7000.SubIndex008);
    }
  }
}

XML文件修改

1.增加变量对应于输入映射索引0x1A00
增加变量对应于输出映射索引0x1A00的,需要修改DT1A00的数据类型。
1)修改DT1A00数据类型
利用Altova XMLSpy 2013软件打开需要修改的xml文件,之后依次点击“网格”→“EtherCATInfo”→“Descriptions”→“Devices”→“Device”→“Profile”→“Dictionary”→“DataTypes”→“DataType”找到DT1A00,点击“SubItem”,修改其内容如图所示SubIdx需要按照顺序递增,Name名称不能出现重复。Bitoffs是上一个SubItem的Bitsize与Bitoffs之和。
在这里插入图片描述
2)修改0x1A00的参数
利用Altova XMLSpy 2013软件打开需要修改的xml文件,之后依次点击“网格”→“EtherCATInfo”→“Descriptions”→“Devices”→“Device”→“Profile”→“Dictionary”→“DataTypes”→“Object”找到0x1A00修改其参数,此处的name,我们定义为DI TxPDO-Map,Type定义为上面修改好的数据类型DT1A00,BitSize按照数据类型大小填写,点击“Info”→“SubItem”修改其参数,Name不可以重复,Info内容为其默认数据,也就是对应子索引的地址值,修改结果如图所示
在这里插入图片描述

2.修改对应子索引0x6000的数据类型及对象
由于索引0x1A00将TxPDO的数据映射到0x6000中,因此要修改0x6000的数据类型和对象
1)同样按照修改DT1A00的方式打开xml文件,依次操作,找到DT6000,修改其内容,修改方式按照DT1A00,修改结果如下图所示,子索引值不可重复,name值不可以重复
在这里插入图片描述
2)同样按照修改0x1A00的方式找到0x6000,name命名为“DI Input”,type为上面定义的“DT6000”size为DT6000的size,点击“Info”→“SubItem”修改其参数,name不可以重复,Info信息为其默认值。修改结果如下图所示
在这里插入图片描述
3.增加变量对应于输出映射索引0x1600
其修改方式按照0x1A00的方式修改,此处不再一一赘述。修改结果详见下图
1)DT1600
在这里插入图片描述2)0x1600

在这里插入图片描述
4.修改对应子索引0x7000的数据类型及对象
其修改方式按照0x6000的方式修改,此处不再一一赘述。修改结果详见下图
1)DT7000
在这里插入图片描述
2)0x7000
在这里插入图片描述
5.修改TxPDO
利用Altova XMLSpy 2013软件打开需要修改的xml文件,之后依次点击“网格”→“EtherCATInfo”→“Descriptions”→“Devices”→“Device”→“TxPDO”
其中对象Fixed,配置为“ture”,Mandatory配置为“ture”SM配置为“3”Index配置为0x1A00,Name可自由配置,合理即可,此处我们命名为“DI TxPDO-Map”Entry填写其子索引,Index配置为“#x6000”SubIndex配置为“1-8”BitLen配置为1,name可自由配置,合理即可,此处我们配置为"witch1-8"DataTy配置为“BOOL”下图是配置好的TxPDO

在这里插入图片描述
6.修改RxPDO
利用Altova XMLSpy 2013软件打开需要修改的xml文件,之后依次点击“网格”→“EtherCATInfo”→“Descriptions”→“Devices”→“Device”→“RxPDO”
其中对象Fixed,配置为“ture”,Mandatory配置为“ture”SM配置为“2”Index配置为0x1600,Name可自由配置,合理即可,此处我们命名为“DO RxPDO-Map”Entry填写其子索引,Index配置为“#x7000”SubIndex配置为“1-8”BitLen配置为1,name可自由配置,合理即可,此处我们配置为"LED1-8"DataTy配置为“BOOL”下图是配置好的RxPDO
在这里插入图片描述
此时所有要修改的内容均已修改完成。将编译成功的STM32代码下发到CPU,将编译成功的XML文件通过EtherCATCfg.exe或EEPROM Programmer.exe或其他软件烧写到从站控制器Eeprom中,此处介绍利用EtherCATCfg.exe烧写方案。

XML文件烧写

EtherCATCfg.exe软件是Beckhoff公司提供的一个用于从站测试的软件,其功能齐全,某些情况下可能存在问题,但作为一个测试软件,其功能已经非常齐全了。有关于eeprom文件烧写的方案介绍如下。
在桌面找到EtherCATCfg.exe图标,单击鼠标右键→打开文件所在位置→打开EtherCAT文件夹,将刚才编写成功的xml文件复制到此文件夹下,关闭文件夹,此时双击鼠标左键打开EtherCATCfg.软件,通过网线将电脑与EtherCAT从站模块连接到一起,按照图示操作,
在这里插入图片描述
1.依次点击“确定”→“OK”→“是”→“是”→“是”此时已经扫描到从站模块,如图中标注所示。
在这里插入图片描述
在这里插入图片描述
2.点击模块“EtherCAT”→“Advanced Setting···”找到Write E2PROM,打开,
在这里插入图片描述
3.选择刚才修改好的XML文件,单击“OK”即可烧写到E2PROM
在这里插入图片描述
待此窗口有自动弹出后,表示E2PROM烧写完毕,重启EtherCATCfg及开发板,按照步骤1操作,即可扫描到设备,此时我们可以在“online”栏中看到此设备处于OP态。
在这里插入图片描述
至此数字量输入输出模块搭建完毕。

总结

本文章根据本人工作内容编写,可能存在某些不正确的地方,仅供参考。

  • 10
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EtherCAT(以太CAT)是一种用于实时控制系统的高性能工业以太网通讯协议。EtherCAT总线系统由一个主站和多个从站组成,从站的设计是其中的一个重要方面。 从站是连接到EtherCAT总线上的设备,它们通过总线与主站进行通信和数据交换。从站的设计需要考虑以下几个方面: 1. 通信接口:从站需要具备与EtherCAT总线相连接的物理接口,如EtherCAT接口芯片或模块。这些接口负责处理信号的发送和接收,以及与总线上其他设备的通信。 2. 数据处理:从站需要能够处理从主站发送过来的指令和数据,并根据需要做出响应。为了实现这一点,从站通常会包含处理器、存储器和各种输入输出接口。 3. 实时性能:EtherCAT是一种实时通信协议,因此从站的设计需要具备高度的实时性能。从站需要能够在同一周期内及时地响应主站的指令,并实现数据的传输和处理。 4. 网络拓扑:EtherCAT总线通常采用线性的、基于时钟同步的拓扑结构。因此,从站设计需要根据具体的网络拓扑结构进行调整,确保数据在各个从站之间的传输和同步。 5. 电源供给:从站需要有稳定的电源供给以保证正常运行。通常,从站会通过总线上的供电线路来获取电源。 综上所述,EtherCAT从站设计涉及到通信接口、数据处理、实时性能、网络拓扑和电源供给等多个方面。通过合理设计和选择硬件和软件组件,可以实现高性能和可靠的EtherCAT从站系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值