原文地址:http://blog.csdn.net/huangxianxinalice/article/details/9363359
- void MainLoop(void)
- {
- /* 当运行在FreeRun-Mode: bEscIntEnabled = FALSE, bDcSyncActive = FALSE
- 当运行在Synchron-Mode: bEscIntEnabled = TRUE, bDcSyncActive = FALSE
- 当运行在DC-Mode: bEscIntEnabled = FALSE, bDcSyncActive = TRUE */
- if ( (!bEscIntEnabled || !bEcatFirstOutputsReceived) /* SM同步方式,但是没有SM事件接收 */
- #if DC_SUPPORTED
- && !bDcSyncActive /* DC同步方式 */
- #endif
- )
- {
- /* 如果应用程序是运行在ECAT同步模式当中,函数ECAT_Application将会在ESC中断里面被调用(在mcihw.c和spihw.c) 在ECAT同步模式当中,它可以被另外得检查,如果SM事件被接受至少一次(bEcatFirstOutputReceived=1),否则,没有中断会产生和函数ECAT_Application将会在这里被调用(中断禁止,因为当执行ECAT_Application的时候,SM事件可以产生)*/
- if ( !bEscIntEnabled )
- {
- /* 应用程序正在运行在ECAT 自由运行模式,首先,我们需要检查是否有输出被接受 */
- UINT16 ALEvent = HW_GetALEventRegister();
- ALEvent = SWAPWORD(ALEvent);
- if ( ALEvent & PROCESS_OUTPUT_EVENT )
- {
- /* 设置标志位给状态机处理 */
- bEcatFirstOutputsReceived = TRUE;
- #if !ESC_SM_WD_SUPPORTED
- /* 重置看门狗计数器 */
- EcatWdCounter = 0;
- #endif
- if ( bEcatOutputUpdateRunning )
- {
- /* 更新输出的状态量 */
- PDO_OutputMapping();
- }
- }
- else if ( nPdOutputSize == 0 )
- {
- /* 如果没有输出被传输,当有输入被读,看门狗需要被重置 */
- if ( ALEvent & PROCESS_INPUT_EVENT )
- {
- /* 输出被更新,设置标志位给看门狗检测 */
- bEcatFirstOutputsReceived = TRUE;
- #if !ESC_SM_WD_SUPPORTED
- /* 重置看门狗的计数器 */
- EcatWdCounter = 0;
- #endif
- }
- }
- }
- #if AL_EVENT_ENABLED
- DISABLE_ESC_INT();
- #endif
- ECAT_Application();
- #if AL_EVENT_ENABLED
- ENABLE_ESC_INT();
- #endif
- }
- #if !ECAT_TIMER_INT
- /* 这里没有中断服务程序来处理硬件定时器,所以,检查定时器的寄存器看是否想要的周期已经过了*/
- {
- UINT32 CurTimer = HW_GetTimer();
- if(CurTimer>= ECAT_TIMER_INC_P_MS)
- {
- ECAT_CheckTimer();
- HW_ClearTimer();
- }
- }
- #endif
- /* 调用EtherCAT函数 */
- ECAT_Main();
- #if COE_SUPPORTED
- /* 调用低优先级的应用程序部分 */
- COE_Main();
- #endif
- CheckIfEcatError();
- #if CiA402_DEVICE
- if(bEcatInputUpdateRunning)
- {
- CiA402_StateMachine();//调用CIA402的处理机,来处理COE,这里没有用到
- }
- #endif
- }
- void PDO_OutputMapping()
- {
- HW_EscReadIsr(((MEM_ADDR *)aPdOutputData), nEscAddrOutputData, nPdOutputSize );
- APPL_OutputMapping((UINT16*) aPdOutputData);
- }
- /
- /**
- \param 指针指向输出处理数据
- \brief 这个函数将拷贝输出从ESC内存到本地内存到硬件
- *////
- void APPL_OutputMapping(Uint16* pData)
- {
- Uint16 j = 0;
- Uint8 *pTmpData = (Uint8 *)pData;// 允许数据处理
- for (j = 0; j < sRxPDOassign.u16SubIndex0; j++)
- {
- switch (sRxPDOassign.aEntries[j])
- {
- /* RxPDO 2 */
- case 0x1601:
- sDOOutputs.LEDs = *pTmpData++;
- break;
- case 0x1602:
- sDO1Outputs.Count = *pTmpData++;
- sDO1Outputs.Cmd = *pTmpData++;
- sDO1Outputs.MotorData = *pTmpData++;
- sDO1Outputs.MotorData |= (*pTmpData++ << 8);
- break;
- }
- }
- }
- void ECAT_Application(void)
- {
- #if CiA402_DEVICE
- /*轴的配置被写,在状态转换从PREOP到SAFEOP=>触发CiA402应用程序,如果设备是在SAFEOP或者OP状态
- (电机控制器的函数只有被触发,如果DC同步被激活和有效的运行模式被设置)*/
- if(bEcatInputUpdateRunning)
- #endif
- {
- APPL_Application();
- }
- if ( bEcatInputUpdateRunning )
- {
- /* EtherCAT 从站是至少在SAFE-OPERATIONAL,更新输入 */
- PDO_InputMapping();
- }
- }
- /
- /**
- \brief 这个函数将被调用从同步的中断程序或者从mainloop当中,如果没有同步被支持
- *////
- void APPL_Application(void)
- {
- Uint8 LED; <span style="white-space:pre"> </span>// 初始化测试数据
- static Uint8 prevState = 55;
- LED = sDOOutputs.LEDs;
- if(LED != prevState)
- set_led(LED);<span style="white-space:pre"> </span>//调用底层程序设置LED
- prevState = LED;
- appState = sDO1Outputs.Cmd;<span style="white-space:pre"> </span>// 设置应用程序的状态
- sDIInputs.switchs = (Uint8)Read_HVS2();
- if(appState == 0)
- appState = sDIInputs.switchs;//special mode to control app state by input switchs!
- sAI1Inputs.info1 = 0x12345678;
- sAI1Inputs.info2 = bsp_read_word(0x10);
- }
- void PDO_InputMapping()
- {
- APPL_InputMapping((UINT16*)aPdInputData);
- HW_EscWriteIsr(((MEM_ADDR *) aPdInputData), nEscAddrInputData, nPdInputSize );
- }
- /
- /**
- \param pData 指针指向输入过程数据
- \brief 这个函数将会拷贝从本地内存到ESC内存到硬件
- *////
- void APPL_InputMapping(Uint16* pData)
- {
- Uint16 j = 0;
- Uint8 *pTmpData = (Uint8 *)pData;
- for (j = 0; j < sTxPDOassign.u16SubIndex0; j++)
- {
- switch (sTxPDOassign.aEntries[j])
- {
- /* TxPDO 1 */
- case 0x1A00:
- *pTmpData++ = sDIInputs.switchs;
- break;
- case 0x1A03: // 注意:可能是不对称的字节接近.
- *pTmpData++ = sAI1Inputs.info1 & 0xFF;
- *pTmpData++ = (sAI1Inputs.info1 & 0xFF00) >> 8;
- *pTmpData++ = (sAI1Inputs.info1 & 0xFF0000) >> 16;
- *pTmpData++ = (sAI1Inputs.info1 & 0xFF000000) >> 24;
- *pTmpData++ = sAI1Inputs.info2 & 0xFF;
- *pTmpData++ = (sAI1Inputs.info2 & 0xFF00) >> 8;
- break;
- }
- }
- }