基于FPGA的数字密码锁电路设计(含程序)

题目

设计思路

代码设计

题目

(1)4个按键分别设置4位数码管上的显示数字,当按键设置的数字与设置的4位密码一致时,蜂鸣器响,表示锁打开;

(2)具备通过按键手动修改数字密码的功能;

(3)具备按键消抖电路功能;

(4)一定时间内无操作数字显示回到初始状态,数码管显示倒计时。

设计思路

        我们可以用四个同bit位宽的寄存器把密码寄存起来,在按键时不断将现在按键的值与密码的寄存器对比,当所有对应位都相同时,蜂鸣器响,可以用一个标志位表示所有对应位相同,蜂鸣器工作的条件就是标志位给出的。

        由于需要按键手动修改密码,那么数码管显示就有两种状态,一种是修改密码,一种是输入密码。我通过增加一个按键来控制这两种状态,当按下这个按键时进入修改密码阶段,当再次按下时进入输入密码阶段。

        按键消抖部分我之前写过,可以看之前的按键消抖。

        一定时间无操作进入初始状态,我设定这个时间为15秒,保证15秒的刷新时间是实时性,采样前后时刻的对比,当所有按键的前一时刻与后一时刻相同时开始倒计时,不同时重新倒计时,保证回归初始与最后操作之间有15秒间隔。

        我额外增加一个led用来显示修改密码和不修改密码的两种状态,方便区别。

代码设计

密码设计部分

module lock(
    input            clk        ,
    input            rstn       ,
    input            shape_key1 ,
    input            shape_key2 ,
    input            shape_key3 ,
    input            shape_key4 ,
    input            shape_amend,
    output reg [3:0] data1      ,
    output reg [3:0] data2      ,
    output reg [3:0] data3      ,
    output reg [3:0] data4      ,
    output reg [3:0] data5      ,
    output reg [3:0] data6      ,
    output reg       buzzer     ,
    output reg       led             
);
	 
	reg flag1;
	wire [3:0]button1,button2,button3,button4;
	wire button_amend;

button button (
    .clk(clk), 
    .rstn(rstn), 
	.flag1(flag1),
    .shape_key1(shape_key1), 
    .shape_key2(shape_key2), 
    .shape_key3(shape_key3), 
    .shape_key4(shape_key4), 
    .shape_amend(shape_amend), 
    .button1(button1), 
    .button2(button2), 
    .button3(button3), 
    .button4(button4), 
    .button_amend(button_amend)
);
	
	reg [3:0]b1,b2,b3,b4;
	always@(posedge clk)
		begin
			b1<=button1;
			b2<=button2;
			b3<=button3;
			b4<=button4;
		end
	reg m;
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				m<=0;
			else if((button1==0)&&(button2==0)&&(button3==0)&&(button4==0))
				m<=0;        //防止倒计时结束出现第二次倒计时
			else if(((b1==button1)&&(b2==button2)&&(b3==button3)&&(b4==button4)))
				m<=1;        //实时对比密码的输入
			else m<=0;
		end
	
	reg [3:0]chiper1,chiper2,chiper3,chiper4;
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					chiper1<=1;
					chiper2<=2;
					chiper3<=3;
					chiper4<=4;
				end
			else if(button_amend==1)    //修改密码阶段
				begin
					chiper1<=button1;
					chiper2<=button2;
					chiper3<=button3;
					chiper4<=button4;
				end
		end
	
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					data1<=0;
					data2<=0;
					data3<=0;
					data4<=0;
					led<=0;
				end
			else if(button_amend==1)//在修改密码阶段时,显示密码
				begin
					data1<=chiper1;
					data2<=chiper2;
					data3<=chiper3;
					data4<=chiper4;
					led<=0;
				end
			else                    //在输入密码阶段时,显示输入密码
				begin
					data1<=button1;
					data2<=button2;
					data3<=button3;
					data4<=button4;
					led<=1;
				end
		end
	
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					buzzer<=0;
				end
			else if((chiper1==button1)&&(chiper2==button2)&&(chiper3==button3)&&(chiper4==button4)&&(button_amend==0)) //四个按键都与密码寄存器相等,并且不是修改密码状态
				buzzer<=1;        //蜂鸣器高电平响
			else 
				buzzer<=0;        
		end
	
	reg [26:0]cn1;
	reg [3:0]count;
	reg [2:0]m2;
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					cn1<=0;
					flag1<=1;
					count<=1;
					m2<=0;
				end
			else case(m2)    //在case的每个状态增加一个回到初始计数的条件
				0:if(m==1)
					begin
						cn1<=0;
						count<=0;
						m2<=1;
					end
				1:begin
					if(m==0)
						m2<=0;
					else if(cn1>= 100)//49999999  200
						begin
							if(count>=15)    //在15秒计时结束给flag1一个时钟周期的低电平
								begin
									count<=0;
									flag1<=0;
									m2<=2;
								end
							count<=count+1;
							cn1<=0;
						end
					else 
						cn1<=cn1+1;
					end
				2:begin
					if(m==0)
						m2<=0; 
					flag1<=1;
					end
			endcase
		end	
	
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					data5<=0;
					data6<=0;
				end
			else case(count)
				0:begin data6<=0;data5<=0; end
				1:begin data6<=1;data5<=5; end
				2:begin data6<=1;data5<=4; end
				3:begin data6<=1;data5<=3; end
				4:begin data6<=1;data5<=2; end
				5:begin data6<=1;data5<=1; end
				6:begin data6<=1;data5<=0; end
				7:begin data6<=0;data5<=9; end
				8:data5<=8;
				9:data5<=7;
				10:data5<=6;
				11:data5<=5;
				12:data5<=4;
				13:data5<=3;
				14:data5<=2;
				15:data5<=1;
			endcase
		end
	
endmodule

按键消抖部分https://blog.csdn.net/m0_59487432/article/details/124872245?spm=1001.2014.3001.5501

动态显示部分https://blog.csdn.net/m0_59487432/article/details/124891256?spm=1001.2014.3001.5501

顶层模块部分

module top(
    input        clk    ,
    input        rstn   ,
    input        key1   ,
    input        key2   ,
    input        key3   ,
    input        key4   ,
    input        amend  ,
    output [7:0] seg    ,
    output [5:0] sel    ,
    output       led    ,
    output       buzzer  
);//完整代码在QQ群文件689408654

wire shape_key1;
wire shape_key2;
wire shape_key3;
wire shape_key4;   //消抖后的四个密码波形
wire shape_amend;  //消抖后的修改按键波形
shake_top shake_top_u(
    .clk          (clk        ), 
    .rstn         (rstn       ), 
    .key1         (key1       ), 
    .key2         (key2       ), 
    .key3         (key3       ), 
    .key4         (key4       ), 
    .amend        (amend      ), 
    .shape_key1   (shape_key1 ), 
    .shape_key2   (shape_key2 ), 
    .shape_key3   (shape_key3 ), 
    .shape_key4   (shape_key4 ), 
    .shape_amend  (shape_amend)
);
wire [3:0] data1;
wire [3:0] data2;
wire [3:0] data3;
wire [3:0] data4;
wire [3:0] data5;
wire [3:0] data6;//数码管各个位码值
lock lock_u(
    .clk         (clk         ), 
    .rstn        (rstn        ), 
    .shape_key1  (shape_key1  ), 
    .shape_key2  (shape_key2  ), 
    .shape_key3  (shape_key3  ), 
    .shape_key4  (shape_key4  ), 
    .shape_amend (shape_amend ), 
    .data1       (data1       ), 
    .data2       (data2       ), 
    .data3       (data3       ), 
    .data4       (data4       ), 
    .data5       (data5       ),
    .data6       (data6       ),
    .buzzer      (buzzer      ),
    .led         (led         )
);	 
digital digital_u(
    .clk  (clk  ), 
    .rstn (rstn ), 
    .data1(data1), 
    .data2(data2), 
    .data3(data3), 
    .data4(data4), 
    .data5(data5),
    .data6(data6), 
    .seg  (seg  ), 
    .sel  (sel  )
);
endmodule

你可能感兴趣的:(FPGA,数码管动态扫描,数字密码锁,fpga开发)