c语言|简单的状态机

描述

不管做什么或者实现什么功能,必定会有实现需求的步骤,简单理解就是在某个状态下做某事,这就很符合C语言面向过程的特点,个人认为面向对象其实是面向过程的封装,封装的好处自然就是符合人的思维,以及便于后续的修改移植工作。

| 简单的状态机

相信读者们刚入门学习单片机的时候,应该比较常使用标志位来触发任务运行,这就是简单的状态机。

 

// 主函数
int main()
{
    int flag = 0;
    while (1)
    {
        if( flag == 0 )
        {
            task_A();
        }
        else if( flag == 1 )
        {
            task_B();
        }
        else if( flag == 2 )
        {
            task_C();
        }
        ......
    }
}

 

往往判断语句太多不利于阅读,那就需要对上面的代码进行优化:

 

// 主函数
int main()
{
    int flag = 0;
    while (1)
    {
        switch (flag)
        {
        case 0x00:
            task_A();
            break;
        case 0x01:
            task_B();
            break;
        case 0x02:
            task_C();
            break;
        ......
        default:
            break;
        }
    }
}

 

| 封装状态机

在项目中使用状态机往往需要封装一下,避免全局变量标志到处飞就不好修改和维护项目,最好的方法就是高内聚低耦合

 

void test(void)
{
    static state;
    if( state == 0 )
    {
        if( !task_A() )
        {
            state = 1;
        }
    }
    else if( state == 1 )
    {
        if( !task_B() )
        {
            state = 2;
        }
    }
    else if( state == 2 )
    {
        if( !task_C() )
        {
            state = 0;
        }
    }
}

int main()
{
    while (1)
    {
        test();
    }
}

 

| 附件

简单写个小demo,加深一下对状态机的理解,这些状态都是面向有限的状态而言。

 

#include "stdio.h"
#include "stdint.h"

typedef struct
{
    uint8_t flag;
}task_struct;

// 触发任务
void task_open(task_struct *task)
{
    if (!task->flag)
    {
        task->flag = !task->flag;
    }
}

// 关闭任务
void task_close(task_struct *task)
{
    if (task->flag)
    {
        task->flag = !task->flag;
    }
}

// 任务初始化
void task_init(void)
{
    /* 初始化 */
    // printf("test init
");
}

// 任务处理
void task_handle(void)
{
    printf("test handle
");
}

// 轮训任务
void task_A(task_struct *task, uint8_t type)
{
    if (!task->flag)
    {
        task_init();
    }
    else
    {
        if (!type)
        {
            /* 单次执行 */
            task_handle();
            /* 关闭任务 */
            task_close(task);
        }
        else
        {
            /* 循环执行 */
            task_handle();
        }
    }
}

int main()
{
    task_struct taskA;
    task_open(&taskA);
    while (1)
    {
        task_A(&taskA, 0);
    }

}

 




审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分