往死里写——mainloop函数
来源:互联网 发布:GABC人工蜂群算法 编辑:程序博客网 时间:2024/06/08 19:10
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; // 初始化测试数据 static Uint8 prevState = 55; LED = sDOOutputs.LEDs; if(LED != prevState) set_led(LED);//调用底层程序设置LED prevState = LED; appState = sDO1Outputs.Cmd;// 设置应用程序的状态 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; } }}