往死里写——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;      }   }}