zoukankan      html  css  js  c++  java
  • 基于时间系统的状态机

    1根据各任务的周期执行时间确定轮询间隔,注意(轮询时间间隔只能比任务执行时间稍长,但一定不能断)

    2 用一个定时器,基准定时为各任务的最小公倍数;软件计数器累加从而触发各任务标志(对任务进行字节编码)

    3主函数中分别操作:Toggle_Task();//设置各标志,这里可以是非时间触发的事件

                               slect_task();//对任务标志进行字节解码:指针函数指向不同的具体函数

                              如果不是空函数(状态陷阱)就用指针函数调用各具体函数。

    注意:

    1 状态机编程思想要贯彻整个设计,即分层状态机,每个状态又分成各子状态。

    2 各状态函数中的状态指示要用静态变量,即便被中断断开,下次还可以接着之前的状态继续进行。要注意异步事件时的现场保护。

    3基于时间片和异步事件的任务触发要仔细分析优先级,对多事件触发如何处理(可以做变通方法。)

    int main(void)
    {
        初始化。。。
        while(1)
        {
            switch(i)
            {
                 case 0:if(TaskFlag.Flag0 == 1) Task0();break;
                 case 1:if(TaskFlag.Flag1 == 1) Task1();break;
                 case 2:if(TaskFlag.Flag2 == 1) Task2();break;
                 case 3:if(TaskFlag.Flag3 == 1) Task3();break;
                 case 4:if(TaskFlag.Flag4 == 1) Task4();break;
                 case 5:if(TaskFlag.Flag5 == 1) Task5();break;
                 default: i = 0;break;
            }
            if((++i)>=Task_Num) i = 0;
        }
    }

    void TIM3_IRQHandler(void) //TIM3 中断
    {
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查 TIM3 更新中断发生与否
        {
            TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除 TIM3 更新中断标志  
            CTimer++;//系统时间累加
            TaskFlag.Flag0 = 1;
        }
    }

    void Task0(void)
    {
        TaskFlag.Flag0 = 0;
        if((CTimer & BITMAK_TASK1) == 0x01)//20ms 任务1
        {
            TaskFlag.Flag1= 1;           
        }

      f((CTimer & BITMAK_TASK2) == 0x02)//20ms 任务1
        {
            TaskFlag.Flag2= 1;           
        }

       。。。

    }

    =========================架构2=============================

    #define        VOID_FUNC            ((void *)0) 

    #typedef     void pFunc_type(void)

    pFunc_type present_task =VOID_FUNC;

    typedef union  TASKFLAG_BITS{
            Uint8    taskall;
            struct{
            Uint16    task0:1;
            Uint16    task1:1;
            Uint16    task2:1;
            Uint16    task3:1;
            Uint16    task4:1;
            Uint16    task5:1;
            Uint16    task6:1;
            Uint16    task7:1       
            }Flag;
    }TaskFlag_Bits,*TaskFlag_Bits_Pt;  

    TaskFlag_Bits TaskFlag;

    int main(void)
    {
        初始化。。。
        while(1)
        {

      Task_Trigger();//任务触发
            Task_Select();
            if (present_task != VOID_FUNC)
                present_task();
        }

    }

    void Task_Trigger(void)

    {

      /*至少有一个初始引导条件*/

      if(某个条件具备)/*时间到或者异步事件触发*/

       { 

        Taskflag.Flag.task1=1;

            }

          if(某个条件具备)

       {   

             Taskflag.Flag.task2=1;

            }

           。。。。。

    }

    void Task_Select(void)

    {

      if (Taskflag.Flag.task0)
         {
            present_task = Task0;
            return;
        }

       if (Taskflag.Flag.task1)
         {
            present_task = Task1;
            return;
        }

      ....

        present_task = VOID_FUNC;/*缺省*/

    }

  • 相关阅读:
    opencv::Laplance算子
    opencv::Sobel算子
    Win10小娜关闭或删除进程
    python练习六十九:urllib爬取练习
    python模块之json
    导入json文件报错,TypeError expected string or buffer
    宝塔面板简单介绍
    复制虚拟机出现”适配器 的mac地址在保留地址范围内‘’
    Windows无法启动 VMware Workstation server服务解决方法
    navicat premiun连接mysql数据库报错,错误代码:1251
  • 原文地址:https://www.cnblogs.com/jieruishu/p/6774880.html
Copyright © 2011-2022 走看看