威海职业学院 孔宪青
三段式状态机在单片机中的实现
威海职业学院 孔宪青
本文提供一种用于单片机的编程方法。通过介绍VHDL中的状态机,本文陈述如何将其应用于单片机中,其阐述的方法是一种优化的实时处理方式,比顺序编程更有效/更具实时性。
状态机;单片机
对于PLD,编程时一般使用状态机,这是一种行之有效的编程方法。状态机是以事件行为为描述核心,并通过状态机体现事件之间的转移机制。由于PLD使用并行宏单元,因此事件都可描述为宏单元组,而事件的关联使用开关门和线路实现,因此说状态机是PLD器件中主要的编程方法。
有限状态机在PLD的应用中有四种类型,分别是一段式、两段式和三段式和多段式。其中多段式状态机对条件描述比较繁琐,而两段式状态机实际就是三段式的精简。因此实际类型就是一段式和三段式两种。其中一段状态机用于描述和顺序时间相关的控制进程,例如对于单总线器件ds1820的控制。但是一段式加深了宏单元深度和综合难度。而标准的三段式状态机对深度和综合都较好。以米勒状态机结构为例,见图1。
图1 米勒状态机
在VHDL中的代码如下:
代码中有三个并行宏单元,相对于顺序描述有更快的实时响应。因此,如果把上述结构使用在单片机上,使用类似的三段式状态机会比单纯的顺序和中断结构有更好的实时性。
单片机由于CPU在同一时间段内只能唯一执行一个任务,因此唯一的方式是把CPU运行时间分为若干时间段分段执行,类似于时钟脉冲CLK。代价是使用一个定时器,定时中断进行状态改变。下面是一段电梯运行的状态机,C代码举例如下:
上面代码中,定时中断服务程序不断检索条件并不断改变状态(使用枚举量定义状态量),使用switch对应VHDL中的进程,复现上图中的“状态改变寄存器逻辑”。同时,输出再使用switch进行状态输出,并提供状态改变的部分条件。这样在一个定时中断中就实现了一个状态机,并把其他不同任务写成状态机的形式,放入定时中断中,就可把顺序的程序结构变为脉冲类型的伪并行逻辑。由于任务都在中断中实现,因此实时性很强。
另外,以上单片机进行状态转移,检索条件改变和输出是最简单的一种,不需要存储上一次的状态量。如果需要把状态存储并保存到下一次状态到来,需要在定时器中断进行保存。例如按键状态机需要进行前后两次按键状态才能转移状态量,则类似于下面的代码情况:
unsigned char past; //past和now是按键前后两次状态,不是状态机状态量
past=now; //按键三段式按键状态机,状态保存
if(key!=0xff)now=0; //由前后两次状态比较得到可用条件
else now=1; //条件可用于状态转移组合逻辑
这种模式应用在定时器多的单片机上更为有效。如果定时器有冗余,则可以开更多的定时器线程,每个线程填入多个状态机,即可满足运行复杂的实时处理情况。通过状态机在单片机上应用,可以把程序结构写成事件触发状态机,这种编程方式为一些任务重、实时强、逻辑复杂的情况提供了一种新的模式和参考。
孔宪青,男,1976年出生,山东省威海人,硕士,讲师,研究方向:单片机应用。