一个简单例子,跑马灯,说明:
1.如何定义一个状态机
2.如何声明一个状态机
3.如何调度一个状态机
4.如何声明状态机的一个状态,可以跨文件使用
5.如何声明状态机的一个状态,只能本文件使用
6.如何实现状态机状态入口处理
7.如果实现状态机状态延时
8.如何实现状态机状态跳转
#include "proj_incs.h"
VS_CreateNull(X); //定义一个状态机X,初始化为NULL
//如果需要定义一个状态机初始一个状态,用VS_Create,如VS_Create(X,A),表示定义一个状态机X,初始状态为(A).
//如果初始为双名状态,则用VS2_Create,如如VS_Create(X,A,B);表示定义一个状态机X,初始状态为(A,B).
VSH_Extern(X,A); //声明状态机X的状态(A),此状态(A)可以跨文件使用.
//声明外部单名状态用VSH_Extern,声明外部双名状态用VSH2_Extern
//声明本地单名状态用VSH_Local,如VSH_Local(X,A);表示声明状态机X的状态(A),只能在本文件使用,不能跨文件使用
//声明本地双名状态用VSH2_Local,如VSH2_Local(X,A,B);表示声明状态机X的状态(A,B),只能在本文件使用,不能跨文件使用
VSH2_Extern(X,B,1); //声明状态机X的外部双名状态用(B,1),状态(B,1)在另外的文件中实现,这里用VSH2_Extern
int main()
{
PORTB = 0x00;
DDRB = _BV(0)|_BV(1)|_BV(2);
HS_TicksInit(); //节拍初始化,
__enable_interrupt(); //开中断
VS_Goto(X,A); //状态机X跳转到状态A,状态A作为状态机X的第一次运行状态
//跳转到单名状态用VS_Goto,跳转到双名状态用VS2_Goto
while(1)
{
while(VS_Sched(X)); //状态机X调度
//VS_Sched(X)返回值可以作为休眠参考值,为0表示没有状态运行,可以休眠,非0表示有状态在运行,不休眠
SleepIdle(); //休眠处理
/*
这里也可以写成:
if(!VS_Sched(X))
{
SleepIdle();
}
*/
}
}
#include "proj_incs.h"
#define LED_A IO_BIT_ALIAS(&PORTB,0) //LED_A,IO口位域别名
#define LED_B_1 IO_BIT_ALIAS(&PORTB,1) //LED_B_1,IO口位域别名
#define LED_B_2 IO_BIT_ALIAS(&PORTB,2) //LED_B_2,IO口位域别名
VS_Extern(X); //声明一个装态机X
VSH2_Extern(X,B,1); //声明装态机X的一个状态(B,1)
VSH_Implement(X,A) //状态机X状态(A)实现
{
if(VS_GetAndClearEnterStateFlag(X)) //如果状态机由Goto进入,表示状态机入口
{
LED_B_2=0; //LED_B_2熄灭
LED_A=1; //LED_A点亮
}
/*
状态机由Goto进入,使用
if(VS_GetAndClearEnterStateFlag(X))
{
}
这里仅仅是由Goto进入,不一定是由其他状态跳转而来,也可能是自己跳转到自己.
如果需要在由其他状态跳转而来的入口处理,用
if(VS_GetAndClearNewStateFlag(X))
{
}
*/
VS2_StartDelay(X,VTMR_NUM_VS_X_DELAY,1000); //状态机延时1000ms
//状态机可以延时,需要设置 UTIL_VSTA_USE_VTMR为1,在util_config.h里.
//状态机延时是在状态退出后,状态机不运行任何状态,直到延时时间到,再运行状态机
//这里的VS2_StartDelay与下面的VS2_Goto执行顺序并不重要.
//这里VTMR_NUM_VS_X_DELAY表示一个util_virtual_timer的一个序号
//util_virtual_timer的序号最大值必须小于UTIL_VTMR_MAX_COUNT,在util_config.h里.
VS2_Goto(X,B,1); //状态机X跳转到(B,1)
//跳转到双名状态用VS2_Goto,跳转到用单名状态VS_Goto
return ;
//通常,调用VS_Goto或VS2_Goto后,紧接着就是函数返回.函数返回后,下一次进行状态机调度的时候,就会运行Goto的目的状态.
}
#include "proj_incs.h"
#define LED_A IO_BIT_ALIAS(&PORTB,0) //LED_A,IO口位域别名
#define LED_B_1 IO_BIT_ALIAS(&PORTB,1) //LED_B_1,IO口位域别名
#define LED_B_2 IO_BIT_ALIAS(&PORTB,2) //LED_B_2,IO口位域别名
VS_Extern(X); //声明一个装态机X
VSH_Extern(X,A); //声明装态机X的一个状态(A)
VSH2_Extern(X,B,1); //声明装态机X的一个状态(B,1)
VSH2_Extern(X,B,2); //声明装态机X的一个状态(B,2)
VSH2_Implement(X,B,1) //状态机X状态(B,1)实现
{
if(VS_GetAndClearEnterStateFlag(X)) //如果状态机由Goto进入,表示状态机入口
{
LED_A=0; //LED_A熄灭
LED_B_1=1; //LED_B_1点亮
}
VS2_StartDelay(X,VTMR_NUM_VS_X_DELAY,1000); //状态机延时1000ms
VS2_Goto(X,B,2); //状态机X跳转到(B,2)
return ;
}
VSH2_Implement(X,B,2) //状态机X状态(B,2)实现
{
if(VS_GetAndClearEnterStateFlag(X)) //如果状态机由Goto进入,表示状态机入口
{
LED_B_1=0; //LED_B_1熄灭
LED_B_2=1; //LED_B_2点亮
}
VS_StartDelay(X,VTMR_NUM_VS_X_DELAY,1000); //状态机延时1000ms
VS_Goto(X,A); //状态机X跳转到(A)
return ;
} |