EtherCAT从站添加RxPDO步骤

环境

工具:TwinCAT3软件、倍福CX2033控制器、AX5800开发板采用STM32F407芯片!

采用MCU来作为从站,控制器作为主站!

EtherCAT的移植暂时不写,直接将添加PDO步骤!在板子原有代码下进行修改!

首先查看一下原有的设备以及PDO信息:TwinCAT3软件添加XML文件,连接控制器,扫描IO,写入EEprom后可以看到以下信息!

我在原有基础上又添加了PDO_WJ,包含三个通道分别是CH1、CH 2、CH 3;

具体修改如下:

一、XML修改

首先,我添加的三个通道分别是USINT类型的占8bit大小!直接根据原有的文档进行修改!

原来的SM2大小为6;

给改后为10字节;10=6+8bit(CH1)+8bit(CH 2)+8bit(CH 3)+8bit(对齐2字节补充的8位)

继续修改,添加7012object对象,可以仿照7010以及1601去修改和添加我们的变量!!!

这里的<BitSize>为144,计算过程就是索引8位+对齐补充8位+32位地址*4=144;分析一下SubIndex 001的<DefaultData>08011270含义,其中1270表示0x7012对象、01表示子索引01、08表示0x08=8bit数据类型;SubIndex 004的<DefaultData>08000000,就是凑够两字节对齐补充的8位数据。

 二、MCU程序修改

找到el9800appl.h文件进行修改!

仿照TOBJ1601结构体编写TOBJ1602,注意内部的aEntries[]的成员个数问题,我这里有CH1、CH2、CH3和对其补充的空8位,所以一共四个成员!

依次往下修改,原先的aEntries成员为1,因为新添加了1602,所以改成aEntries[2];

 我们仿照原先定义的TOBJ7010、TOBJ7011结构体,再去定义TOBJ7012结构体

 仿照1601对象,去添加1602object对象

 在1601下面添加

#ifdef _OBJD_
/**
* \addtogroup PdoMappingObjects PDO Mapping Objects
* @{
*/
/**
 * \brief Object 0x1602(Digital output RxPDO) entry descriptions
 * 
 * SubIndex 0 : read only<br>
 * SubIndex x : read only<br>
 *  (x > 0)
 */
OBJCONST TSDOINFOENTRYDESC	OBJMEM asEntryDesc0x1602[] = {
   {DEFTYPE_UNSIGNED8, 0x3, ACCESS_READ },
   {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},
   {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ},  
   {DEFTYPE_UNSIGNED32, 0x20, ACCESS_READ}
   };

/** 
 * \brief Object 0x1601 (Digital output RxPDO) name
 *
 * In this example no specific entry name is defined ("SubIndex xxx" is used)
 */
OBJCONST UCHAR OBJMEM aName0x1602[] = "AO RxPDO-Map\000\377";
#endif //#ifdef _OBJD_

/**
 * \brief Object 0x1602 (Digital output RxPDO) variable to handle object data
 * 
 */
PROTO TOBJ1602 sAORxPDOMap
#ifdef _EVALBOARD_
 = {4, {0x70120108, 0x70120208, 0x70120308, 0x08}}
#endif
;
/** @}*/

把1C12里面的值仿照1C13改为= {0x02, {0x1601,0x1602}}

 仿照7010去写7012映射

/***************++++++++++添加修改部分1+++++++++++**************/
/**
 * \brief Object 0x7012 (Digital output object) entry descriptions
 *
 * SubIndex 0 : read only<br>
 * SubIndex x : (One description for each led) read only and RxPdo mappable<br>
 *  (x > 0)
*/
#ifdef _OBJD_
OBJCONST TSDOINFOENTRYDESC    OBJMEM asEntryDesc0x7012[] = {
   {DEFTYPE_UNSIGNED8, 0x8, ACCESS_READ }, /* Subindex 000 */
   {DEFTYPE_UNSIGNED8, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 001: CH 1 */
   {DEFTYPE_UNSIGNED8, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 002: CH 2 */
   {DEFTYPE_UNSIGNED8, 0x01, ACCESS_READ | OBJACCESS_RXPDOMAPPING}, /* SubIndex 003: CH 3 */
   {0x0000, 0x08, 0}
   }; /* Subindex 008 for align */


/**
 * \brief 0x6000 (Digital input object) object and entry names
 */
OBJCONST UCHAR OBJMEM aName0x7012[] = "PDO_WJ\000CH 1\000CH 2\000CH 3\000\000\377";
#endif //#ifdef _OBJD_

/**
 * \brief 0x6020 (Analog input object) variable to handle object data
 * 
 */
PROTO TOBJ7012 PDO_WJ
#ifdef _EVALBOARD_
= {3, 0x00, 0x00, 0x00, 0}
#endif
;
/** @}*/
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

 最后找到OBJMEM ApplicationObjDic[]数组进行添加1602和7012成员内容。

 el9800appl.c文件修改

找到el9800appl.c文件下找到void APPL_OutputMapping(UINT16* pData)函数,这是我们接收主机发送数据的函数。

 进行修改后:

void APPL_OutputMapping(UINT16* pData)
{
	    UINT16 j = 0;
    UINT16 *pTmpData = (UINT16 *)pData;

    /* we go through all entries of the RxPDO Assign object to get the assigned RxPDOs */
    for (j = 0; j < sRxPDOassign.u16SubIndex0; j++)
    {
        switch (sRxPDOassign.aEntries[j])
        {
        /* RxPDO 2 */
        case 0x1601:
            ((UINT16 *) &sDOOutputs)[1] = SWAPWORD(*pTmpData++);//LED数据
			((UINT16 *) &Var0x7011)[0] = SWAPWORD(*pTmpData++);//Var0x7011低16位数据
			((UINT16 *) &Var0x7011)[1] = SWAPWORD(*pTmpData++);//Var0x7011高16位数据
//						test1 =  SWAPWORD(*pTmpData++);
            break;
		case 0x1602: 
					((UINT16 *) &PDO_WJ)[1] =  SWAPWORD(*pTmpData++);//CH1低八位、CH2高八位
					((UINT16 *) &PDO_WJ)[2] =  SWAPWORD(*pTmpData++);//CH3
//					test2=  SWAPWORD(*pTmpData++);
			break;
        }
    }
}

 下图的函数void APPL_Application(void),我们用来处理接收的数据!!

/////////////////////////////////////////////////////////////////////////////////////////
/**
\brief    This function will called from the synchronisation ISR 
            or from the mainloop if no synchronisation is supported
*////////////////////////////////////////////////////////////////////////////////////////
uint8_t Ch_buff[3]={0};
void APPL_Application(void)
{
	Ch_buff[0]=	PDO_WJ.CH_1;
	Ch_buff[1]=	PDO_WJ.CH_2;
	Ch_buff[2]=	PDO_WJ.CH_3;//这里我新添加的数组去接收Ch通道的值
		
	GPIO_WriteBit(GPIOB, GPIO_Pin_1, (BitAction)sDOOutputs.bLED1);
	GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction)sDOOutputs.bLED2);
	GPIO_WriteBit(GPIOC, GPIO_Pin_5, (BitAction)sDOOutputs.bLED3);
	GPIO_WriteBit(GPIOC, GPIO_Pin_4, (BitAction)sDOOutputs.bLED4);
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)sDOOutputs.bLED5);
	GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)sDOOutputs.bLED6);
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)sDOOutputs.bLED7);
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)sDOOutputs.bLED8);	
	
	sDIInputs.bSwitch1    = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3);
  sDIInputs.bSwitch2    = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2);
	sDIInputs.bSwitch3    = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1);
  sDIInputs.bSwitch4    = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
	sDIInputs.bSwitch5    = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_5);
  sDIInputs.bSwitch6    = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4);
	sDIInputs.bSwitch7    = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3);
  sDIInputs.bSwitch8    = GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2);

}

三、调试

打开TwinCAT3软件连接控制器和从站设备!进行写数据,观察现象!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值