1、有限状态机

(1)常说的状态机是指有限状态机 FSM(Finite State Machine)。FSM 指有有限个状态(一般是一个状态变量的值)。

(2)机器在接收到外部输入的信号后,会综合考虑当前自己的状态和用户输入的信息。然后机器做出一个动作,跳转到另外一个状态。

(3)状态机的3个关键点:当前状态、外部输入、下一个状态。

2、两种状态机

Moore 型状态机

  • 相对简单,输出只与当前的状态有关(与输入信号状态无关)
  • 此时输入信号也不是完全没用,他的作用是用作 激励作用

Mealy 型状态机

  • 输出不只和当前状态有关,还与输入信号有关。
  • 综合考虑两个情况:当前状态、输入值。

举例:冰、水、水蒸气 + 火(外部输入)

  • 自己当前状态是冰 + 外部输入是火 ----> 下一个状态就会变成 水
  • 自己当前状态是水 + 外部输入是火----> 下一个状态就会变成 水蒸气
  • 自己当前状态是水蒸气 + 外部输入是火----> 下一个状态就 还是水蒸气

3、状态机的主要用途

电路设计、FPGA程序设计、软件设计

(1)电路设计、FPGA程序设计、里面涉及了大量的状态机原理。

(2)软件设计(框架类型的设计,譬如操作系统的 GUI 系统,一般称为消息机制)

4、C 语言实现一个简单的状态机

题目:开锁状态机

功能描述:用户连续输入正确的密码则会开锁,如果密码输入过程出现错误,则锁会退回到初始状态重新计入密码。即用户只需要连续输入正确的密码即可开锁(输入错误不用撤销、也不用删除)

题目分析:用户密码输入错误、状态机会自动将锁置为初始状态。

#include <stdio.h>

// 1、给状态机定义有限个状态集
typedef enum
{
	STATE1,    
    STATE2,  
    STATE3,  
    STATE4,  
    STATE5,  
    STATE6,
    STATE7,    
}STATE;

int main(void)
{
    int num = 0;
    // current_sate 记录状态机的当前状态,初始为 STATE1 
    // 用户每输入一个正确的密码,current_sate 就走一步 ,一直到 STATE6 后锁就开了
    // 用户只要写错一个密码,current_sate 就会回退为 STATE1 
    STATE current_sate = STATE1;  // 状态机的初始状态为 STATE1
    
    // 2、实现一个用户循环输入密码的循环
    printf("请输入密码,直到密码正确开锁 \n");
    
    while(1) // 输入正确之后,break 跳出去
    {
        scanf("%d",&num);
        printf("num = %d \n",num);
         // 3、处理用户的本次输入
        switch(current_sate)
        {
            case STATE1:
                if(num == 1)
                {
                    current_sate = STATE2; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;
          
            case STATE2:
                if(num == 2)
                {
                    current_sate = STATE3; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;
           
            case STATE3:
                if(num == 3)
                {
                    current_sate = STATE4; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;
                
             case STATE4:
                if(num == 4)
                {
                    current_sate = STATE5; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;
             
            case STATE5:
                if(num == 5)
                {
                    current_sate = STATE6; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;
             
            case STATE6:
                if(num == 6)
                {
                    current_sate = STATE7; 
                }
                else
                {
                     current_sate = STATE1; 
                }
                 break;    
        }
        
        if(current_sate == STATE7)
        {
            printf("密码输入正确,锁开了\n");
            break;
        }
    }
    
    return 0;
}