按键控制的状态机设计

一 设计要求
1、 按键控制数码管显示,当按下S2时,Q4数码管显示1;再次按下S2,Q4数码管显示2;
2、 第三次按下S2,Q4数码管显示3;第四次按下S2时,Q4数码管显示4.第五次按下S2时Q4又从1开始显示,如此反复。
3、 检测按键按下需要消抖。

二 代码实现

按键控制数码管显示

LIBRARY IEEE;                
USE IEEE.std_logic_1164.ALL;  
USE IEEE.std_logic_unsigned.ALL;
USE IEEE.std_logic_arith.ALL;
ENTITY keykzstate IS
PORT( clk: IN std_logic;sw: IN std_logic;--seg:out std_logic;seven_seg_led: out std_logic_vector(15 DOWNTO 0));
END ENTITY;
ARCHITECTURE behav OF keykzstate IS 
SIGNAL key_rst:	  std_logic;
SIGNAL key_rst_r: std_logic;
SIGNAL key_rst_an:std_logic;
SIGNAL low_sw:	  std_logic;
SIGNAL low_sw_r:  std_logic;
SIGNAL low_sw_an: std_logic;
SIGNAL mtime:integer range 0 TO 9;
SIGNAL cnt:		  std_logic_vector(19 DOWNTO 0);
-- five state
type state_type is (s0, s1, s2, s3, s4);
SIGNAL pre_state, nx_state:state_type; --dingyi xiantai he citai
---------------------------------------------------------
BEGIN 
--seg <= '0';PROCESS(clk)BEGIN if(rising_edge(clk)) thenkey_rst <= sw;end if;END PROCESS;
---------------------------------------------------------PROCESS(clk)beginif(rising_edge(clk)) thenkey_rst_r <= key_rst;end if;END PROCESS;
key_rst_an <= key_rst_r and not key_rst; --xiaodouPROCESS(clk)beginif(rising_edge(clk)) thenif key_rst_an = '0' then cnt <= cnt+1;else cnt <= (others=>'0');end if;end if;END PROCESS;
---------------------------------------------------------PROCESS(clk)beginif(rising_edge(clk)) thenif cnt = "11111111111111111111" thenlow_sw <= sw;else null;end if;end if;END PROCESS;PROCESS(clk)begin if(rising_edge(clk)) thenlow_sw_r <= low_sw;end if;END PROCESS;
low_sw_an <= low_sw_r and not low_sw;
---------------------------------------------------------
-- seq process:create state
seq:PROCESS(clk)
beginif(rising_edge(clk)) thenpre_state <= nx_state;end if;
end process seq;
---------------------------------------------------------
-- com process:create next state and output logic
com:PROCESS(pre_state, low_sw_an)
begincase pre_state is when s0=>mtime <= 0;seven_seg_led <= conv_std_logic_vector(mtime,16);if low_sw_an = '1' then nx_state <= s1;else nx_state <= s0;end if;when s1=> mtime <= 1;seven_seg_led <= conv_std_logic_vector(mtime,16);if low_sw_an = '1' then nx_state <= s2;else nx_state <= s1;end if;when s2=>mtime <= 2;seven_seg_led <= conv_std_logic_vector(mtime,16);			if low_sw_an = '1' then nx_state <= s3;else nx_state <= s2;end if;when s3=>mtime <= 3;seven_seg_led <= conv_std_logic_vector(mtime,16);if low_sw_an = '1' then nx_state <= s4;else nx_state <= s3;end if;when s4=>mtime <= 4;seven_seg_led <= conv_std_logic_vector(mtime,16);if low_sw_an = '1' then nx_state <= s1;else nx_state <= s4;end if;end case;
end process com;
end behav;

八段数码管驱动模块描述(Verilog 描述)

module seg(clk,rst_n,en,idis_data,ds_stcp,ds_shcp,ds_data);
input clk;	//25M??????
input rst_n;	//??????????
input en;
input [15:0] idis_data ;
output ds_stcp;		//74HC595????????????????????????
output ds_shcp;		//74HC595?????????????????????
output ds_data;		//74HC595???????//????? 0~F ??????
parameter 	SEG_NUM0 	= 8'hc0,SEG_NUM1 	= 8'hf9,SEG_NUM2 	= 8'ha4,SEG_NUM3 	= 8'hb0,SEG_NUM4 	= 8'h99,SEG_NUM5 	= 8'h92,SEG_NUM6 	= 8'h82,SEG_NUM7 	= 8'hF8,SEG_NUM8 	= 8'h80,SEG_NUM9 	= 8'h90,SEG_NUMA 	= 8'h88,SEG_NUMB 	= 8'h83,SEG_NUMC 	= 8'hc6,SEG_NUMD 	= 8'ha1,SEG_NUME 	= 8'h86,SEG_NUMF 	= 8'h8e;
//????? 0~7????
parameter	SEG_WE0		= 8'b1111_1110,SEG_WE1		= 8'b1111_1101,SEG_WE2		= 8'b1111_1011,SEG_WE3		= 8'b1111_0111;//	SEG_WE4		= 8'b1110_1111,//	SEG_WE5		= 8'b1101_1111,//	SEG_WE6		= 8'b1011_1111,//	SEG_WE7		= 8'b0111_1111;
wire en;
reg clk_div_2;
reg clk1;
always@(en)  //use enable siganl to break the module 
beginif (en==1)clk1<=clk;else clk1<=clk1;
endalways@(posedge clk1 or negedge rst_n)if(!rst_n)clk_div_2<=1'b0;else clk_div_2<=~clk_div_2;
//-------------------------------------------------
reg[3:0] seg_num;	//??????
reg[7:0] seg_duan;	//7???????????????8??
reg[7:0] seg_wei;	//7????????reg[7:0] cnt_4;		//?????
always @(posedge clk_div_2 or negedge rst_n)if(!rst_n) cnt_4 <= 8'd0;else cnt_4 <= cnt_4+1'b1;
always @(posedge clk_div_2 or negedge rst_n)if(!rst_n) seg_num <= 8'h00;else case(cnt_4[7:6])2'b00: seg_num <= idis_data[3:0];2'b01: seg_num <= idis_data[7:4];2'b10: seg_num <= idis_data[11:8];2'b11: seg_num <= idis_data[15:12];default:  ;endcase
reg flag;
always @(posedge clk_div_2 or negedge rst_n)if(!rst_n) begin seg_duan <= 8'hff;//	flag<=1'b0;end //else if(flag) begin seg_duan<=8'hff;//			flag<=~flag;//	endelsecase(seg_num) 4'h0: seg_duan <= SEG_NUM0;4'h1: seg_duan <= SEG_NUM1;4'h2: seg_duan <= SEG_NUM2;4'h3: seg_duan <= SEG_NUM3;4'h4: seg_duan <= SEG_NUM4;4'h5: seg_duan <= SEG_NUM5;4'h6: seg_duan <= SEG_NUM6;4'h7: seg_duan <= SEG_NUM7;4'h8: seg_duan <= SEG_NUM8;4'h9: seg_duan <= SEG_NUM9;4'ha: seg_duan <= SEG_NUMA;4'hb: seg_duan <= SEG_NUMB;4'hc: seg_duan <= SEG_NUMC;4'hd: seg_duan <= SEG_NUMD;4'he: seg_duan <= SEG_NUME;4'hf: seg_duan <= SEG_NUMF;default:	 ;endcase//????
always @(cnt_4[7:6])case(cnt_4[7:6])2'b00: seg_wei <= SEG_WE0;2'b01: seg_wei <= SEG_WE1;2'b10: seg_wei <= SEG_WE2;2'b11: seg_wei <= SEG_WE3;default:  seg_wei <= 8'b0000_0000;endcase
//-------------------------------------------------
//74HC95????			
reg ds_stcpr;	//74HC595????????????????????????
reg ds_shcpr;	//74HC595?????????????????????
reg ds_datar;	//74HC595???????
always @(posedge clk_div_2 or negedge rst_n)			if(!rst_n) ds_shcpr <= 1'b0;else if((cnt_4 > 8'h02 && cnt_4 <= 8'h22) || (cnt_4 > 8'h24 && cnt_4 <= 8'h44)|| (cnt_4 > 8'h46 && cnt_4 <= 8'h66) || (cnt_4 > 8'h68 && cnt_4 <= 8'h88)|| (cnt_4 > 8'h90 && cnt_4 <= 8'hb0) || (cnt_4 > 8'hb2 && cnt_4 <= 8'hd2)|| (cnt_4 > 8'hd4 && cnt_4 <= 8'hf4)) ds_shcpr <= ~ds_shcpr;else ds_shcpr<=1'b0;			
always @(posedge clk_div_2 or negedge rst_n)			if(!rst_n) ds_datar <= 1'b0;else case(cnt_4)8'h02,8'h46,8'h90,8'hd4: ds_datar <= seg_duan[7];8'h04,8'h48,8'h92,8'hd6: ds_datar <= seg_duan[6];8'h06,8'h4a,8'h94,8'hd8: ds_datar <= seg_duan[5];8'h08,8'h4c,8'h96,8'hda: ds_datar <= seg_duan[4];8'h0a,8'h4e,8'h98,8'hdc: ds_datar <= seg_duan[3];8'h0c,8'h50,8'h9a,8'hde: ds_datar <= seg_duan[2];8'h0e,8'h52,8'h9c,8'he0: ds_datar <= seg_duan[1];8'h10,8'h54,8'h9e,8'he2: ds_datar <= seg_duan[0];8'h12,8'h56,8'ha0,8'he4: ds_datar <= seg_wei[0];8'h14,8'h58,8'ha2,8'he6: ds_datar <= seg_wei[1];8'h16,8'h5a,8'ha4,8'he8: ds_datar <= seg_wei[2];8'h18,8'h5c,8'ha6,8'hea: ds_datar <= seg_wei[3];8'h1a,8'h5e,8'ha8,8'hec: ds_datar <= seg_wei[4];8'h1c,8'h60,8'haa,8'hee: ds_datar <= seg_wei[5];8'h1e,8'h62,8'hac,8'hf0: ds_datar <= seg_wei[6];8'h20,8'h64,8'hae,8'hf2: ds_datar <= seg_wei[7];8'h24,8'h68,8'hb2,: ds_datar <= 1;8'h26,8'h6a,8'hb4,: ds_datar <= 1;8'h28,8'h6c,8'hb6,: ds_datar <= 1;8'h2a,8'h6e,8'hb8,: ds_datar <= 1;8'h2c,8'h70,8'hba,: ds_datar <= 1;8'h2e,8'h72,8'hbc,: ds_datar <= 1;8'h30,8'h74,8'hbe,: ds_datar <= 1;8'h32,8'h76,8'hc0,: ds_datar <= 1;8'h34,8'h78,8'hc2,: ds_datar <= 1;8'h36,8'h7a,8'hc4,: ds_datar <= 1;8'h38,8'h7c,8'hc6,: ds_datar <= 1;8'h3a,8'h7e,8'hc8,: ds_datar <=	1;8'h3c,8'h80,8'hca,: ds_datar <= 1;8'h3e,8'h82,8'hcc,: ds_datar <= 1;8'h40,8'h84,8'hce,: ds_datar <= 1;8'h42,8'h86,8'hd0,: ds_datar <= 1;			default: ds_datar <= seg_duan[0];endcase
always @(posedge clk1 or negedge rst_n)			if(!rst_n) ds_stcpr <= 1'b0;else if((cnt_4 == 8'h02) || (cnt_4 == 8'h23) || (cnt_4 == 8'h45) || (cnt_4 == 8'h67) || (cnt_4 == 8'h89)|| (cnt_4 == 8'hb1)|| (cnt_4 == 8'hd3)) ds_stcpr <= 1'b0;else if((cnt_4 == 8'h22) || (cnt_4 == 8'h44) || (cnt_4 == 8'h66) || (cnt_4 == 8'h88) || (cnt_4 == 8'hb0)|| (cnt_4 == 8'hd2)|| (cnt_4 == 8'hf4)) ds_stcpr <= 1'b1;wire ds_stcp = ds_stcpr;
wire ds_shcp = ds_shcpr;
wire ds_data = ds_datar;			
endmodule

三 整机电路图在这里插入图片描述
四 仿真结果
在这里插入图片描述
五 实验结果
(a) 第0次按下SW2
在这里插入图片描述
(b) 第1次按下SW2
在这里插入图片描述
© 第2次按下SW2
在这里插入图片描述
(d) 第3次按下SW2
在这里插入图片描述
(e) 第4次按下SW2
在这里插入图片描述
(f) 第5次按下SW2
在这里插入图片描述
(g) 第6次按下SW2
在这里插入图片描述
(h) 第7次按下SW2
在这里插入图片描述
(i) 第8次按下SW2
在这里插入图片描述
分析图 9(a)到(i)可以知道,实验设计的电路符合如下要求:
按键控制数码管显示,当按下S2时,Q4数码管显示1;再次按下S2,Q4数码管显示2;第三次按下S2,Q4数码管显示3;第四次按下S2时,Q4数码管显示4.第五次按下S2时Q4又从1开始显示,如此反复。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部