【 XMC4800 Relax EtherCAT Kit测评】基于XMC4800平台的Ethercat从站机器人扩展模块
[复制链接]
本帖最后由 tdatd 于 2019-1-29 16:41 编辑
一背景 EtherCAT是倍福公司提出的一种高速实时工业以太网现场总线,倍福公司提供数据链路层和物理层的实现,一般需采用定制的专用芯片。通常需要ETHERCAT主站和从站构成一个ETHERCAT网络。主站的实现方案有x86,arm,fpga等可以实现。目前可以基于windows平台的twincat 进行主站的开发,且twintcat可支持非常多的网卡。或者在linux下实现主站方案,可基于arm或者x86平台,通常需要打实时内核补丁,有德国方案公司提供主站的方案,license大概在10几万美元。或者直接采用倍福的ethercat的PLC作为主站开发。从站方面,目前能提供从站方案的除了倍福的et1100 1200等,还有microchip的lan9252系列,单芯片支持2路ethercat接口,但是需要外部的处理器通过spi接口等进行控制。 我们本项目采用英飞凌的xmc4800系列,单芯片内部集成 arm cortexM4内核的高性能mcu以及ethercat接口,配合dave强大的ide开发环境,可以更方便的进行基于ethercat从站设备的开发。 在机器人领域,目前主要的总线有canopen,ethercat,powlink等。随着工业现场接驳设备的增加,通信数据量的加大,对工业总线的数据吞吐率,实时性,有了更多的需求。通常canopen最高的通信速度只有1Mbps,相比以太网百Mbps的带宽,在总线数据量大的情况下,can总线凸显出了瓶颈。目前ethercat在国内具有很广泛的应用前景。我将实现一个基于XMC4800平台的Ethercat从站机器人IO扩展模块。扩展模块在工业现场链接多个传感器和io输入输入节点,通过ethercat总线,可以保证所有io状态可以实时上传到主控制器,相应更加及时。 二 。实现目标 1.实现ethercat从站通信协议栈; 2.搭建twincat上位机开发系统; 3.通过twincat可以控制从站的输出DOUT; 4.通过twincat可以读取从站的输入DIN;
通常一个总线IO模块需要至少8个输入,8个输入,由于relax板卡的资源,2路按键作为输入,8路led作为了输出进行演示。
三 开发平台 1.mxc4800 relax开发板; 2.vs2010,twincat3.1; 3.网线、micro USB下载线等; 4.dave开发平台; 5.ssc(slave stack code)软件;
四,具体步骤分享。 熟悉板载的资源,网络接口,输入输入管脚,按键 led灯等;
按之前的评测,下载infineon eep软件包,打开dave,导入工程。在工程集成了ssc也就是ethercat的协议栈部分,这个协议栈需要安装ssctool,而这个ssc tool需要加入ETG (ethercat)组织才行,我发了邮件,但是没用响应,只要自行在网上下载了一个。
我们打开xmc4800_relax.xlsx ,对用到的di dout资源进行编辑,在后面,可以通过ssc tool程序生成主站需要用到的配置文件,主站通过配置文件来识别从站的配置。 我安装的ssc tool直接双击 xmc4800_relax.esp可以打开 这个协议栈配置。
点击tool\APPLICATION\IMPORT可以导入mxc4800_relax.xlsx,导入了刚才修改的配置,然后点击project /creat new stack file,配置i生成血站的目录和配置文件的目录。
在xmc4800_relax.c中修改 void APPL_InputMapping(UINT16* pData) { memcpy(pData,&(((UINT16 *)&Button0x6000)[1]),SIZEOF(Button0x6000)-2); }
///////////////////////////////////////////////////////////////////////////////////////// /** \param pData pointer to output process data
\brief This function will copies the outputs from the ESC memory to the local memory to the hardware *//////////////////////////////////////////////////////////////////////////////////////// void APPL_OutputMapping(UINT16* pData) { memcpy(&(((UINT16 *)&LED0x7000)[1]),pData,SIZEOF(LED0x7000)-2); }
还有 /** \brief ECAT_Application (prev. SSC versions "COE_Application") this function calculates and the physical process signals and triggers the input mapping *//////////////////////////////////////////////////////////////////////////////////////// void ECAT_Application(void) { { APPL_Application(); } /* PDO Input mapping is called from the specific trigger ISR */ }
并 实现process_app函数
void APPL_Application(void) { if(LED0x7000.LED1) PORT1->OMR = 0x40000000; else PORT1->OMR = 0x00004000;
if(LED0x7000.LED2) PORT0->OMR = 0x40000000; else PORT0->OMR = 0x00004000;
if(LED0x7000.LED3) PORT3->OMR = 0x40000000; else PORT3->OMR = 0x00004000;
if(LED0x7000.LED4) PORT0->OMR = 0x80000000; else PORT0->OMR = 0x00008000;
if(LED0x7000.LED5) PORT1->OMR = 0x00040000; else PORT1->OMR = 0x00000004;
if(LED0x7000.LED6) PORT3->OMR = 0x20000000; else PORT3->OMR = 0x00002000;
if(LED0x7000.LED7) PORT5->OMR = 0x00080000; else PORT5->OMR = 0x00000008;
if(LED0x7000.LED8) PORT3->OMR = 0x08000000; else PORT3->OMR = 0x00000800;
if(PORT15->IN & PORT15_OUT_P13_Msk) Button0x6000.Button1 = TRUE; else Button0x6000.Button1 = FALSE;
if(PORT15->IN & PORT15_OUT_P12_Msk) Button0x6000.Button2 = TRUE; else Button0x6000.Button2 = FALSE; } 应用realx开发板板载的key和led 模拟基本的din和dout功能。
在main中进行初始化 int main(void) { UINT16 init_result; // Init Result from SSC uint32_t button1pressed = 0, button2pressed = 0; uint32_t * pTmpData = (uint32_t *) &aEepromData[0];
/* Initialize EEPROM */ init_result = XMC_FEE_Init();
if (xmc_fee_sector_info.flash_data_addr == XMC_FEE_EMPTY) { /* first setup, prepare the default config out of the SSC for EEPROM */ XMC_FEE_WriteArray(0U,aEepromData,2040); /* Program the RAM contents to Emulated EEPROM*/ XMC_FEE_UpdateFlashContents(); } else {
/* Read the latest contents from EEPROM * As per this example the data should match the latest written values * (First 0 - 256 bytes = 0xAA and Last (256 to 504)bytes = 0x55) */ XMC_FEE_ReadArray(0U,aEepromData,2040); // reload ECAT config before Init }
EEPROMcont.confdata0 = (uint32_t)* pTmpData++; EEPROMcont.confdata1 = (uint32_t)* pTmpData++; EEPROMcont.confdata2 = (uint32_t)* pTmpData++; EEPROMcont.confdata3 = (uint32_t)* pTmpData++;
#ifdef RELAX ECAT0_Init(&ECAT_0_LQFP144_Relax_V09);
Init_ECAT_Adapt_LED (); Clear_ECAT_Adapt_LED (); Init_Relax_Button(); #else
ECAT0_Init(&ECAT_0_LFABG196_VDB); #endif
ethercat从站主要的处理过程都是在mainLoop里,
while(1) { // remember when button has been pressed if (!XMC_GPIO_GetInput(BUTTON1)) button1pressed = 1; if (!XMC_GPIO_GetInput(BUTTON2)) button2pressed = 1;
// EtherCAT Main loop MainLoop();
// toggle LED1 on release of button1 if (XMC_GPIO_GetInput(BUTTON1) && button1pressed) { button1pressed = 0; XMC_GPIO_ToggleOutput(LED1); } // toggle LED2 on release of button2 if (XMC_GPIO_GetInput(BUTTON2) && button2pressed) { button2pressed = 0; XMC_GPIO_ToggleOutput(LED2); } }
在ecatappl.c中实现mainloop函数
void MainLoop(void) { /*return if initialization not finished */ if(bInitFinished == FALSE) return;
/* FreeRun-Mode: bEscIntEnabled = FALSE, bDcSyncActive = FALSE Synchron-Mode: bEscIntEnabled = TRUE, bDcSyncActive = FALSE DC-Mode: bEscIntEnabled = TRUE, bDcSyncActive = TRUE */ if ( (!bEscIntEnabled || !bEcatFirstOutputsReceived) /* SM-Synchronous, but not SM-event received */ && !bDcSyncActive /* DC-Synchronous */ ) { /* if the application is running in ECAT Synchron Mode the function ECAT_Application is called from the ESC interrupt routine (in mcihw.c or spihw.c), in ECAT Synchron Mode it should be additionally checked, if the SM-event is received at least once (bEcatFirstOutputsReceived = 1), otherwise no interrupt is generated and the function ECAT_Application has to be called here (with interrupts disabled, because the SM-event could be generated while executing ECAT_Application) */ if ( !bEscIntEnabled ) { /* application is running in ECAT FreeRun Mode, first we have to check, if outputs were received */ UINT16 ALEvent = HW_GetALEventRegister(); ALEvent = SWAPWORD(ALEvent);
if ( ALEvent & PROCESS_OUTPUT_EVENT ) { /* set the flag for the state machine behaviour */ bEcatFirstOutputsReceived = TRUE; if ( bEcatOutputUpdateRunning ) { /* update the outputs */ PDO_OutputMapping(); } } else if ( nPdOutputSize == 0 ) { /* if no outputs are transmitted, the watchdog must be reset, when the inputs were read */ if ( ALEvent & PROCESS_INPUT_EVENT ) { /* Outputs were updated, set flag for watchdog monitoring */ bEcatFirstOutputsReceived = TRUE; } } }
DISABLE_ESC_INT(); ECAT_Application();
if ( bEcatInputUpdateRunning ) { /* EtherCAT slave is at least in SAFE-OPERATIONAL, update inputs */ PDO_InputMapping(); } ENABLE_ESC_INT(); }
/* there is no interrupt routine for the hardware timer so check the timer register if the desired cycle elapsed*/ { UINT32 CurTimer = (UINT32)HW_GetTimer();
if(CurTimer>= ECAT_TIMER_INC_P_MS) { ECAT_CheckTimer();
HW_ClearTimer(); } }
/* call EtherCAT functions */ ECAT_Main();
/* call lower prior application part */ COE_Main(); CheckIfEcatError();
}
好了以上编译,ok后下载到开发板中,下面开始主站的配置。
这里需要注意的是工程中的xml配置文件需要复制到TwinCAT3安装目录的配置文件夹下,D:\TwinCAT\3.1\Config\Io\EtherCAT
需要去倍福网站下载twincat3。1版本。注册id后即可下载,安装twincat需要电脑中有vs环境,twincat使用的vs的界面作为壳子,我安装的是vs2010,也是好用的。
在这里我还想请假大家一个问题,我安装的twincat 网卡后, 导致我的win10 64位系统无法正常关机,关机后风扇还在一直转,待机后也无法启动起来,只能强制关机再开启。这个问题困扰了我好久,就差重装系统了,其实也花了好几个小时升级win10到最新,后来才逐渐定位到是twincat兼容网卡导致的问题,有了解的朋友也请指点一下。
打开vs(twincat),点文件、新建、项目,在模板里选择twincat工程
建立twincat工程后,在方案管理器I/O 右键,添加新项:
选择ethercat Master ,ok
双击device,会抬出配置i界面,需要给网卡安装ethercat驱动。在adapter标签下,点compatible devices,会列出系统里的网卡,选中你需要的ethercat网卡后,点击install,通常即可安装完毕。 安装完成后,在adapter标签下,点击search,可以搜索到刚才的主站网卡。点击ok。
在方案管理器device主站,右键,scan,,查找从站设备,
可以看到,scan到一个box 1 ,搜索到了一个从站设备。
现在双击box1,可以看到从站出在preop预操作的状态,可以切换其他标签可以看到发送帧、同步时钟等状态信息。
在twincat中,点击twincat,reload device,从站进入op模式,可以和主站通信,正常工作了,下面通过twincat主站来控制从站的din,dout。
我们在方案管理器里右键点击din,按键模拟输入DIN状态,可以看到twinca显示实时状态信息, 目前还不清楚具体的抖动和延迟,我相信这个应该是在1ms以内的实时数据,这就是ethercat总线的魅力。
在方案管理里 双击 从站,dout 标签。我们映射了8个dout输出端口,在每一个dout上右键,可以写入1或0,来输出dout的状态,
、
对应的开发板的led输出指示状态。:
小结: 通过最近的测评和学习,对英飞凌的xmc4800平台有了初步的认识和了解,配合dave开发环境的强大功能,不得不赞叹现在科技的发展迅速,可以飞速的搭建起基本的框架,而开发人员可集中精力做业务相关部分。单芯片集成ethercat接口和mcu内核的应用中,xmc4800可以有效的降低bom器件的数量,提高集成度,使产品具有更高的竞争力。
本次活动中,得到了eeworld管理员@ okhxyyo和网友的的鼎立支持,一并表示感谢。 年终岁尾,时间紧迫,杂事繁多,测试难免有些仓促和不足,还请多多体谅,ethercat从站是个复杂的工程,谨以这个相对简单的IO扩展模块作为结项报告,期待有大牛可以实现伺服协议等高级功能。 算起来至少也得有1,2个多礼拜的时间玩起来这套demo, 年龄大了头晕目眩写测评,祝大家新春快乐。
|