7月3日来到实验室,现在算起来刚好又三个月了,一年的四分之一。谈一谈自己的小感悟
刚来看我导师的代码,中间又被我导师提醒。才恍然大悟遇到的第一个小练手竟然是有限状态机算法。
在学习数电时序电路的时候,描述元器件的一种方式是状态转换表与状态转换图。有限状态机是从逻辑学直接导出的,状态机是数字电路的基本设计单元,能接受时钟的时序控制。个人感觉其原理类似。都是从一个状态经过特定条件跳转到另外一个状态。
由于练手项目,已商用。下面我以一个简单的例子为例。阐述一下我的代码及其思路:
在数字电路中最容易见到的就是类似于这样的状态转换图。通过上图可以直到两种情况下存在输出。一是当前状态为111,输入为1;另一种为当前状态为001,输入为1。假设进入111和001的状态必须为如图。即100 -->101 -->110–>111,011–>010–>001这样的状态才为1。这种情况大多应用于读取串口、读取内存的时候,存在着协议,必须顺序读入的情况。以串口为例,在单片机中串口的读取过程中容易出现不及时。解决方法是增加缓存,将读取到的数据存放在buff中,之后再访问buff。因此需定义一个数组作为buff。之前在微信公众账号上看到有人写了一个队列作为buff。其原理类似。
其中main文件
#include "stc8.h"
#include "MSG_DATA.H"
#include "BSP_Uart.h"
#include "TEST.h"
void main(void)
{
Data_Init(); //数据初始化
Time0_Step(); //定时器初始化
COM1_Step(0); //Uart1初始化 ,其中波特率为9600
EA=1;
Uart3sendstr("init ok");
while(1)
{
Get_MSG(); //抓包
if(bFlag_MSGisOK==1)
{
HandleMSG(); //数据处理
bFlag_MSGisOK=0;
}
}
}
其中抓包程序
#include "test.h"
#include "bsp_uart.h"
//
//Fuction:void Uart_SaveTo_RxBuf(BYTE rx_data)
//Description:存储在buff中
//Parameter:rx_data存储的内容
//return:无
/
void Uart_SaveTo_RxBuf(BYTE rx_data)
{
if(Uart_Rx_WRpt<=Uart_Rx_size)
{
Uart_Rx_buf[Uart_Rx_WRpt++]=rx_data;
}
}
//Fuction:Uart_RxBuf_Clr()
//Description:清空BUFF
//Parameter:无
//return:无
///
void Uart_RxBuf_Clr(void)
{
Uart_Rx_WRpt = 0;
}
//Fuction:void Get_MSG()
//Description:抓包
//Parameter:无
//return:无
///
void Get_MSG()
{
BYTE rx_data;
if(index_WR != index_RD)
{
rx_data = Uart_In_buf[index_RD];
index_RD =(index_RD+1)%2048;
if(mode) //mode Ñ¡ÔñËıßÐÎ
{
switch(State)
{
case 0:
if((rx_data == 4)||(rx_data == 3)
{
if(rx_data == 4)
{
State = 1;
Uart_RxBuf_Clr();
Uart_SaveTo_RxBuf(rx_data);
}
else
{
mode = 0;
State = 1;
Uart_RxBuf_Clr();
Uart_SaveTo_RxBuf(rx_data);
}
break;
}
case 1:
if(rx_data == 5)
{
State = 2;
Uart_SaveTo_RxBuf(rx_data);
}
else
{
State = 0;
Uart_RxBuf_Clr();
}
break;
case 2:
if(rx_data == 6)
{
State = 3;
Uart_SaveTo_RxBuf(rx_data);
}
else
{
State = 0;
Uart_RxBuf_Clr();
}
break;
case 3:
if(rx_data == 7)
{
State = 3;
Uart_SaveTo_RxBuf(rx_data);
bFlag_MSGisOK = 1;
}
else
{
State = 0;
Uart_RxBuf_Clr();
}
break;
default:
State = 0;
Uart_RxBuf_Clr();
}
}//if(mode)
else
{
switch(State)
{
case 0:
if((rx_data == 4)||(rx_data == 3)
{
if(rx_data == 3)
{
State = 1;
Uart_RxBuf_Clr();
Uart_SaveTo_RxBuf(rx_data);
}
else
{
mode = 1;
State = 1;
Uart_RxBuf_Clr();
Uart_SaveTo_RxBuf(rx_data);
}
break;
}
case 1:
if(rx_data == 2)
{
State = 2;
Uart_SaveTo_RxBuf(rx_data);
}
else
{
State = 0;
Uart_RxBuf_Clr();
}
break;
case 2:
{
if(rx_data == 1)
{
State = 0;
Uart_SaveTo_RxBuf(rx_data);
bFlag_MSGisOK = 1;
}
else
{
State = 0;
Uart_RxBuf_Clr();
}
}
break;
default:
State = 0;
Uart_RxBuf_Clr();
}
}
}
其中串口中断处理程序
void Uart1_Task() interrupt 4 using 1
{
BYTE data c;
ES=0;
if(RI)
{
c=SBUF;
Uart_In_buf[index_WR] = c;
index_WR++;
index_WR = index_WR %2048;
RI=0;
}
ES=1;
}
本人水平有限,如有错误,欢迎指出。