时间:2023-06-14 | 栏目:控制/MCU | 点击:次
不管做什么或者实现什么功能,必定会有实现需求的步骤,简单理解就是在某个状态下做某事,这就很符合C语言面向过程的特点,个人认为面向对象其实是面向过程的封装,封装的好处自然就是符合人的思维,以及便于后续的修改移植工作。
| 简单的状态机
相信读者们刚入门学习单片机的时候,应该比较常使用标志位来触发任务运行,这就是简单的状态机。
//主函数
intmain()
{
intflag=0;
while(1)
{
if(flag==0)
{
task_A();
}
elseif(flag==1)
{
task_B();
}
elseif(flag==2)
{
task_C();
}
......
}
}
往往判断语句太多不利于阅读,那就需要对上面的代码进行优化:
//主函数
intmain()
{
intflag=0;
while(1)
{
switch(flag)
{
case0x00:
task_A();
break;
case0x01:
task_B();
break;
case0x02:
task_C();
break;
......
default:
break;
}
}
}
|封装状态机
在项目中使用状态机往往需要封装一下,避免全局变量标志到处飞就不好修改和维护项目,最好的方法就是高内聚低耦合。
voidtest(void)
{
staticstate;
if(state==0)
{
if(!task_A())
{
state=1;
}
}
elseif(state==1)
{
if(!task_B())
{
state=2;
}
}
elseif(state==2)
{
if(!task_C())
{
state=0;
}
}
}
intmain()
{
while(1)
{
test();
}
}
|附件
简单写个小demo,加深一下对状态机的理解,这些状态都是面向有限的状态而言。
#include"stdio.h"
#include"stdint.h"
typedefstruct
{
uint8_tflag;
}task_struct;
//触发任务
voidtask_open(task_struct*task)
{
if(!task->flag)
{
task->flag=!task->flag;
}
}
//关闭任务
voidtask_close(task_struct*task)
{
if(task->flag)
{
task->flag=!task->flag;
}
}
//任务初始化
voidtask_init(void)
{
/*初始化*/
//printf("testinit
");
}
//任务处理
voidtask_handle(void)
{
printf("testhandle
");
}
//轮训任务
voidtask_A(task_struct*task,uint8_ttype)
{
if(!task->flag)
{
task_init();
}
else
{
if(!type)
{
/*单次执行*/
task_handle();
/*关闭任务*/
task_close(task);
}
else
{
/*循环执行*/
task_handle();
}
}
}
intmain()
{
task_structtaskA;
task_open(&taskA);
while(1)
{
task_A(&taskA,0);
}
}
审核编辑:刘清