分享

EtherCAT从设备输入输出实现

 beginnow1 2023-12-18 发布于广东

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态。
在这里插入图片描述
至此数字量输入输出模块搭建完毕。

总结

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约