IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 状态机练习 -> 正文阅读

[嵌入式]状态机练习

前言

实现一个测试过程,该过程包括启动准备状态、启动测试、停止测试、查询测试结果、显示测试结果、测试结束返回初始化6个状态;用时间来控制该过程,90秒内完成该过程;

一、什么是状态机

现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed 。

状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。例如,根据自动门的运行规则,我们可以抽象出下面这么一个图。
在这里插入图片描述

自动门有两个状态,open 和 closed ,closed 状态下,如果读取开门信号,那么状态就会切换为 open 。open 状态下如果读取关门信号,状态就会切换为 closed 。

状态机的全称是有限状态自动机,自动两个字也是包含重要含义的。给定一个状态机,同时给定它的当前状态以及输入,那么输出状态时可以明确的运算出来的。例如对于自动门,给定初始状态 closed ,给定输入“开门”,那么下一个状态时可以运算出来的。

这样状态机的基本定义我们就介绍完毕了。重复一下:状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。

二、代码实现

1.计时器模块

module timer_cont(
	input  clk,   //50M时钟                        
	input  rst_n, //复位信号
	
	output reg sec_15//15s           
);

parameter MAX_NUM = 30'd749_999_999;//最大数15s,750_000_000-1次
reg [29:0] cnt_15;//计数寄存器

//15s计时器
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_15 <= 30'd0;
	end
	else if(cnt_15 == MAX_NUM)begin
		cnt_15 <= 30'd0;	
	end
	else begin
		cnt_15 <= cnt_15 + 1'd1;
	end
end

//15s脉冲信号
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		sec_15 <= 1'b0;
	end
	else if(cnt_15 == MAX_NUM)begin
		sec_15 <= 1'b1;
	end
	else begin
		sec_15 <= 1'b0;
	end
end


endmodule

2.状态机模块

module fsm(
	input                  clk,
	input                  rst_n,
	input  wire 		   sec_15
);

reg [2:0] cstate;               //现态
reg [2:0] nstate;               //次态

//状态划分
parameter S0 = 0;//启动准备状态
parameter S1 = 1;//启动测试
parameter S2 = 2;//停止测试
parameter S3 = 3;//查询测试结果
parameter S4 = 4;//显示测试结果
parameter S5 = 5;//初始化

//第一段:现态跟随次态
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cstate <= S5;//复位键被按下,当前状态设置为初始化
	else
		cstate <= nstate;          //下一次状态赋值给当前状态
end
		
//第二段:组合逻辑,阻塞赋值
always@(*)begin
	if(!rst_n)
		begin
			nstate = S5;
		end
	else
		case(cstate)
			S5: begin
								if(sec_15 == 1'b1)       
									nstate = S0;
								else
									nstate = nstate;
							end
			S0: begin
								if(sec_15 == 1'b1)
									nstate = S1;
								else
									nstate = nstate;
							end
			S1: begin
								if(sec_15 == 1'b1)
									nstate = S2;
								else
									nstate = nstate;
							end
			S2: begin
								if(sec_15 == 1'b1)
									nstate = S3;
								else
									nstate = nstate;
							end
			S3: begin
								if(sec_15 == 1'b1)
									nstate = S4;
								else
									nstate = nstate;
							end
			S4: begin
								if(sec_15 == 1'b1)
									nstate = S5;
								else
									nstate = nstate;
							end
			default:    nstate = S5;
      endcase
end
endmodule

3.顶层模块

module top(
	input  clk,
	input  rst_n
);

wire sec_15;

//实例化计时器模块
timer_cont inst_timer_cont(
.clk    (clk   ),                 
.rst_n  (rst_n ),
                     
.sec_15 (sec_15)         
);

//实例化状态机模块
fsm inst_fsm(
.clk    (clk   ),                
.rst_n  (rst_n ),
.sec_15 (sec_15)               
);              
endmodule

三、原理图

在这里插入图片描述

四、检测10010串的状态机

1、设计思路

我们可以利用两个按键来表示输入1和0,当完成前一个状态后进入下一个状态。如果在输入过程中输错一个,那么会回到初始状态。当全部输入成功后,4个led灯会闪烁一段时间,之后回到初始状态。
在这里插入图片描述

2、代码实现

1、按键消抖模块

module key_debounce(
	input 		clk,
	input			rst_n,	
	input 		key,
	
	output		key_value, //按键稳定信号
	output		flag		  //抖动结束标识(0表示未结束,1表示结束)
	
);

parameter TIME_20MS = 20'd1_000_000; //20ms

reg [19:0] cnt_20ms;
reg key_value_r;
reg flag_r;
reg key_reg; //保存前一次取的key值


always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		cnt_20ms <= 20'd0;
		key_reg  <= 1'b1;
	end
	else begin
		key_reg <= key;
		if(key_reg == 1'b1 && key == 1'b0)
			cnt_20ms <= TIME_20MS;
		else if(cnt_20ms <= 20'd0)
			cnt_20ms <= 20'd0;
		else
			cnt_20ms <= cnt_20ms -20'd1;
	end
end


always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		flag_r <= 1'b0;
	else if(cnt_20ms == 20'd1)
		flag_r <= 1'b1;
	else
		flag_r <= 1'b0;
end
assign flag = flag_r;


always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		key_value_r <= 1'b1;
	else if(cnt_20ms == 20'd1)
		key_value_r <= ~key;
	else
		key_value_r <= key_value_r;
		
end

assign key_value = key_value_r;

endmodule

2、状态机模块

module fsm(
	input                  clk,
	input                  rst_n,
	input           [1:0]  key,
	
	output   wire   [3:0]  led
);
parameter MAX_TIME   = 26'd49_999_999;//1s
parameter TIME_200MS = 24'd9_999_999; //200ms 

reg [2:0] cstate;               //现态
reg [2:0] nstate;               //次态
parameter S0 = 0;//初始状态
parameter S1 = 1;//1状态
parameter S2 = 2;//10状态
parameter S3 = 3;//100状态
parameter S4 = 4;//1001状态
parameter S5 = 5;//10010状态

reg [3:0] 	led_r;
reg [25:0] 	cnt_1s;
reg [23:0]	cnt_200ms;

//1s计数器
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt_1s <= 26'd0;
	else if(cnt_1s == MAX_TIME)
		cnt_1s <= 26'd0;
	else
		cnt_1s <= cnt_1s + 26'd1;
end

//200ms计数器
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cnt_200ms <= 24'd0;
	else if(cnt_200ms == TIME_200MS)
		cnt_200ms <= 24'd0;
	else
		cnt_200ms <= cnt_200ms + 24'd1;
end
//第一段
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		cstate <= S0;
	else 
		cstate <= nstate;
end

//状态切换模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
		begin
			nstate <= S0;
		end
	else
		case(cstate)
			S0: begin
								if(key[1] )           
									nstate <= S1;
								else if(key[0])
									nstate <= S0;
								else
									nstate <= nstate;
							end
			S1: begin
								if(key[0] )
									nstate <= S2;
								else if(key[1])            
									nstate <= S0;
								else
									nstate <= nstate;
							end
			S2: begin
								if(key[0] )
									nstate <= S3;
								else if(key[1])            
									nstate <= S0;
								else
									nstate <= nstate;
							end
			S3: begin
								if(key[1] )
									nstate <= S4;
								else if(key[0] )
									nstate <= S0;
								else
									nstate <= nstate;
							end
			S4: begin
								if(key[0] )
									nstate <= S5;
								else if(key[1] )
									nstate <= S0;
								else
									nstate <= nstate;
							end
			S5:	begin
								if(cnt_1s == MAX_TIME)
									nstate <= S0;
								else
									nstate <= S5;
				end
								
			default:   nstate <= S0; 
      endcase
end

//第三段:跟随状态输出
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)
	 led_r <=4'b0000;
	else
		case(cstate)
			S5:begin
			 if(cnt_200ms == TIME_200MS)
					led_r <= ~led_r;
				else 
					led_r <= led_r;
			end
			default:	led_r <= 4'b0000;
		endcase
end

assign led = led_r;

endmodule
				

3、顶层模块

module top(
	input wire        clk,
	input wire 		   rst_n,
	input wire  [1:0] key,
	
	output wire [3:0] led
);
wire [1:0] flag;
wire [1:0] key_value;

//例化按键KEY0
key_debounce inst_key_debounce(
.clk      (clk         ),
.rst_n    (rst_n       ),
.key      (key[0]      ),
		
.flag     (flag[0]     ),               
.key_value(key_value[0])         
);

//例化按键KEY1
key_debounce inst_key_debounce1(
.clk      (clk         ),
.rst_n    (rst_n       ),
.key      (key[1]      ),
		
.flag     (flag[1]     ),              
.key_value(key_value[1])          
);

//例化状态机
fsm(
.clk  (clk         ),
.rst_n(rst_n       ),
.key  ({key_value[1]&&flag[1],key_value[0]&&flag[0]}),
	     	
.led  (led)
);
endmodule

3、原理图

在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:53:52  更:2022-05-09 12:54:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/22 2:49:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码