• C 500uS状态机架构


    main

    int main(void)
    {
        
        InitSys();
        
        SoftwareInit(); 
        
        while (1)
        {            
            if(P500usReq)
            {
                P500usReq = 0;
                P500us();           
            }
            ModbusSlaveProcess(Mb3);
        }
    }

    任务

    #include "Global.h"
    
    /** @brief 500us时间片 */
    INT16U P500usReq = 0;
    
    
    INT8U t500usFlg = 0;
    INT8U t1msFlg = 0;
    INT8U t4ms_1Flg = 0;
    INT8U t4ms_2Flg = 0;
    INT8U t8ms_1Flg = 0;
    INT8U t8ms_2Flg = 0;
    INT8U t20msFlg = 0;
    INT8U t100msFlg = 0;
    INT8U t1sFlg = 0;
    
    
     /**
     * @brief  500us任务
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 500us调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task500us(void)
    {
        t500usFlg ^= 0x01;
    }
    
     /**
     * @brief  1ms任务
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 1ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    
    static void Task1ms(void)
    {     
        t1msFlg ^= 0x01;
        
        UpdInput();                         // 更新数字量输入
        UpdInSig(&IoStt, &Sys);             // 更新输入信号
        
        HoistCtrl(&Sys);                    // 电葫芦控制
        
        UpdOutSig(&IoStt, &Sys);            // 更新输出信号
        UpdOutput();                        // 更新数字量输出
        
        ModbusInvCtrl(&InvModbus);
        
        MotorStt.ia = ((INT16S)AdcResult[0] - 2048) << 13;
        MotorStt.ib = ((INT16S)AdcResult[1] - 2048) << 13;
        MotorStt.ua = ((INT16S)AdcResult[2] - 2048) << 13;
        MotorStt.ub = ((INT16S)AdcResult[3] - 2048) << 13;
        MotorCal(&MotorStt);
    }   
    
     /**
     * @brief  4ms任务1
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 4ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task4ms_sub1(void)
    {
        t4ms_1Flg ^= 0x01;        
    }
    
     /**
     * @brief  4ms任务2
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 4ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task4ms_sub2(void)
    {
        t4ms_2Flg ^= 0x01;
        
    #ifdef RELEASE_MODE
        IWDG_ReloadCounter();           // 喂狗
    #endif
    }
    
     /**
     * @brief  8ms任务1
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 8ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task8ms_sub1(void)
    {     
        t8ms_1Flg ^= 0x01;
    }
    
     /**
     * @brief  8ms任务2
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 8ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task8ms_sub2(void)
    {    
        t8ms_2Flg ^= 0x01;
    }
    
    void Uart2Test(STR_Uart *uart)
    {
        INT8U i = 0;
        uart->tPtr = uart->rPtr;
        uart->txFlg = 1;
        for (i = 0; i < uart->tPtr; i++)
        {
            uart->txBuf[i] = uart->rxBuf[i];
        }
        TxUart(RS2_KIND);
    }
    
    void Uart3Test(STR_Uart *uart)
    {
        INT8U i = 0;
        uart->tPtr = uart->rPtr;
        uart->txFlg = 1;
        for (i = 0; i < uart->tPtr; i++)
        {
            uart->txBuf[i] = uart->rxBuf[i];
        }
        TxUart(RS3_KIND);
    }
    
    void Uart4Test(STR_Uart *uart)
    {
        INT8U i = 0;
        uart->tPtr = uart->rPtr;
        uart->txFlg = 1;
        for (i = 0; i < uart->tPtr; i++)
        {
            uart->txBuf[i] = uart->rxBuf[i];
        }
        TxUart(RS4_KIND);
    }
    
     /**
     * @brief  20ms任务
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 20ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task20ms(void)
    {  
        t20msFlg ^= 0x01;    
        
        RxUart(RS1_KIND, MenuUartHandle);                      // 串口1数据接收及处理,与手操器通讯
        
        ModbusDataUpdate();
        RxUart(RS3_KIND, ModbusUartHandle);                    // 串口3数据接收及处理,Modbus通讯
        RxUart(RS2_KIND, ModbusMasterHandler);
        RxUart(RS4_KIND, Uart4Test);
        UpdAdc();
    }
    
     /**
     * @brief  100ms任务
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 100ms调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task100ms(void)
    {   
        t100msFlg ^= 0x01;
        TerimalUpd();
        TTDisplay();
        SavePos(&Sys);
        EncPulseCal(&Sys.lft.encPos);       
        EncPulseCal(&Sys.smallCar.encPos);    
        EncPulseCal(&Sys.bigCar.encPos);
        UpdWeight(&Weigh);
    }
    
     /**
     * @brief  1s任务
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 调用周期: 1s调用
     *
     * @par  注意:
     *       ● 
    
     */
    static void Task1s(void)
    {   
        t1sFlg ^= 0x01;
        GetCalendarTime(&NowTime);  // 更新RTC时间 
        
        /* 更新时间参数 */
        PaYear = NowTime.year + 2000;
        PaMonth = NowTime.month;
        PaDay = NowTime.date;
        PaHour = NowTime.hour;
        PaMinute = NowTime.minute;
        
        if (INVALID == Sys.run)
        {
            SaveFault(&FaultQ);     // 非运行时记录故障进E2PROM
        }
    }
    
     /**
     * @brief  500us时间片的任务分发器
     * @param  参数名 参数说明    
     * @param  无
     * @retval 无
     * @note ● 分为1个500us、1个1ms、2个4ms任务、2个8ms任务、1个20ms、1个100ms、1个1s任务
    
     *
     * @par  注意:
     *       ● 本分发器对任务进行时间错位调度,避免任务调用重叠,可参见"任务调度周期.jpg","任务调度周期(细化).jpg"
    
     */
    void P500us(void)
    {    
        static INT8U s1msReq = 0;   //用于触发1ms任务标志,每500us累加
        static INT8U s4msReq = 0;   //用于触发4ms任务标志,每1ms累加
        static INT8U s8msReq = 0;   //用于触发8ms任务标志,每4ms累加
        static INT8U s20msReq = 0;  //用于触发20ms任务标志,每4ms累加
        static INT8U s100msReq = 0; //用于触发100ms任务标志,每20ms累加
        static INT8U s1sReq = 0;    //用于触发100ms任务标志,每100ms累加
        Task500us();
            
        if (s1msReq++ & 0x01)
        {
            Task1ms();
        }
        else
        {
            s4msReq++;
            switch (s4msReq)
            {
                case 1:     //触发4ms任务
                {
                    Task4ms_sub1();
                    break;
                }
                case 2:     //出发20ms100ms1s任务
                {
                    s20msReq++;
                    if (0x03 == s20msReq)    //两次20ms任务之间的中点时刻(5次时间片中间值为3次)
                    {
                        s100msReq++;
                        if(0x03 == s100msReq)   //两次100ms任务之间的中点时刻(5次时间片中间值为3次)
                        {
                            s1sReq++;
                            if(s1sReq >= 10)
                            {
                                Task1s();
                                s1sReq = 0x00;
                            }
                        }
                        
                        if(s100msReq >= 5)
                        {
                            Task100ms();
                            s100msReq = 0x00;
                        }
                    }
                    if (s20msReq >= 5)
                    {
                        Task20ms();
                        s20msReq = 0x00;
                    }
                    break;
                }
                case 3:     //触发4ms任务
                {
                    Task4ms_sub2();
                    break;
                }
                default:    //触发2个8ms任务
                {
                    if (s8msReq++ & 0x01)
                    {
                        Task8ms_sub1();
                    }
                    else
                    {
                        Task8ms_sub2();
                    }
                    s4msReq = 0;
                    break;
                }
            }
        }
    }
  • 相关阅读:
    如何选择一家公司?
    教你一招最屌的阅读开源项目的姿势
    我是如何管理我的团队的?
    我面试到底问什么?
    如何正确使用开源项目?
    如何选择开源项目?
    html表格中的tr td th用法
    如何用 Java 实现 Web 应用中的定时任务?
    java定时任务实现的几种方式
    Java 定时任务 & 任务调度
  • 原文地址:https://www.cnblogs.com/jiangzhaowei/p/9805715.html
Copyright © 2020-2023  润新知