基于FPGA的数字密码锁

这篇具有很好参考价值的文章主要介绍了基于FPGA的数字密码锁。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于FPGA的数字密码锁

顶层文件

module lock (
  input clk,//时钟
  input rst_n,//复位
  input [3:0] number_in,//输入
  input key_open1,
  input key_lock1,
  // input key_reset1,
  output                  beep,//蜂鸣器
  output                  lock_flag,//锁标志位
  output [3:0] dtube_cs_n,	//7段数码管位选信号
  output [7:0] dtube_data	//7段数码管段选信号
);

wire [1:0] keyin;
wire [1:0] keyout;

assign keyin={key_lock1,key_open1};
assign {key_lock,key_open}=keyout;

debounce_button u_debounce_button(
  .clk       (clk       ),
  .rst       (rst_n     ),
  .key       (keyin     ),
  .key_pulse (keyout    )
);

wire [15:0] display_num;

wire beep1;


fsm u_fsm(
  .clk         (clk         ),
  .rst_n       (rst_n       ),
  .number_in   (number_in   ),
  .key_open_reset    (key_open    ),
  .key_lock    (key_lock    ),
  // .key_reset   (key_reset   ),
  .beep        (beep1       ),
  .display_num (display_num ),
  .lock_flag   (lock_flag   )
);

seg7 u_seg7(
  .clk         (clk         ),
  .rst_n       (rst_n       ),
  .display_num (display_num ),
  .dtube_cs_n  (dtube_cs_n  ),
  .dtube_data  (dtube_data  )
);



beep_ctr u_beep_ctr(
  .clk   (clk   ),
  .rst_n (rst_n ),
  .beep1 (beep1 ),
  .beep  (beep  )
);







  
endmodule

状态机模块

module fsm (
  input                      clk,
  input                      rst_n,
  input          [3:0]       number_in,
  input                      key_open_reset,
  input                      key_lock,
  // input                      key_open_reset,
  output                  beep,
  output         [15:0]      display_num,
  output         reg         lock_flag
);

localparam							//一共五个状态,使用Gray码提高翻转效率
		LOCK 	 = 3'b000,
		OPEN_PRE = 3'b001,
		OPEN = 3'b011,
		RESET_PRE = 3'b010,
		RESET = 3'b110;

//数码管显示 0~F 对应段选输出
parameter 	NUM0 	= 4'h0,//c0,
            NUM1 	= 4'h1,//f9,
            NUM2 	= 4'h2,//a4,
            NUM3 	= 4'h3,//b0,
            NUM4 	= 4'h4,//99,
            NUM5 	= 4'h5,//92,
            NUM6 	= 4'h6,//82,
            NUM7 	= 4'h7,//F8,
            NUM8 	= 4'h8,//80,
            NUM9 	= 4'h9,//90,
            NUMA 	= 4'hA,//88,
            NUMB 	= 4'hB,//83,
            NUMC 	= 4'hC,//c6,
            NUMD 	= 4'hD,//a1,
            NUME 	= 4'hE,//86,
            NUMF 	= 4'hF;//8e;
            

  reg [2:0] state;			//下一拍执行状态


  //密码储存
  reg [3:0] mima;
  reg reset_mima_flag;
  reg merroy;





reg beep1;
reg beep2;
assign beep=beep2;

always @(posedge clk or negedge rst_n) begin//状态转移
  
  if(!rst_n)state <= LOCK;
  else if (cnt == 32'h1dcd6500) begin
    state <= LOCK;
  end
  else if(beep2)
  state<=LOCK;
  else 
  case (state)
    LOCK: 
      if (number_in == mima && key_open_reset)
        state <= OPEN_PRE;
      else if (key_open_reset)
        state <= LOCK;
      else 
        state <= LOCK;
    OPEN_PRE:
      if (number_in == mima && key_open_reset)
        state <= OPEN;
      else if (key_lock)
        state <= LOCK;
      else 
        state <= OPEN;
    OPEN: 
      if (key_open_reset)
        state <= RESET_PRE;
      else if (key_lock)
        state <= LOCK;
      else 
        state <= state;
    RESET_PRE:
      if (key_open_reset)
        state <= RESET;
      else if (key_lock)
        state <= LOCK;
      else 
        state <= state;
    RESET:
      if (key_open_reset)
        state <= OPEN;
      else if (key_lock)
        state <= LOCK;
      else 
        state <= state;
    default: state <= state;
  endcase
end


reg jilu_key;
reg jilu_key1;

always @(posedge clk or negedge rst_n) begin//输出
  if (rst_n == 0) begin
    lock_flag = 0;
    reset_mima_flag = 0;
    merroy = 0;
	 jilu_key=0;
  end
  else if (state == OPEN) begin
    lock_flag = 1;
  end
  else if (state == RESET) begin
    reset_mima_flag = 1;
    merroy = 1;
  end
  else if (state == LOCK) begin
    lock_flag = 0;
    reset_mima_flag = 0;
  end
  else if (key_lock|key_open_reset)
  jilu_key=1;
  
end

always @(posedge clk or negedge rst_n)begin
if(!rst_n)jilu_key1<=0;
else if(jilu_key&(!jilu_key1))beep1<=1;
else beep1<=0;
end
  //定时10s
reg [31:0] cnt;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)cnt<=0;
else if(cnt==32'd500000000)cnt<=0;
else if(beep1)cnt<=cnt+1;
else cnt<=cnt;

end

always@(posedge clk or negedge rst_n)begin
if(!rst_n)beep2<=0;
else if(cnt==32'd499999999)beep2<=1;
else beep2<=beep2;


end

always @(*) begin//密码控制
  if (!merroy) begin
    mima <= 4'b1010;
  end
  else if (reset_mima_flag) begin
    mima <= number_in;
  end
  else begin
    mima <= mima;
  end
end





//数码管显示译码
wire [3:0] qian;
wire [3:0] bai;
wire [3:0] shi;
wire [3:0] ge;

assign qian = number_in[3]?NUM1:NUM0;
assign bai = number_in[2]?NUM1:NUM0;
assign shi = number_in[1]?NUM1:NUM0;
assign ge = number_in[0]?NUM1:NUM0;

assign display_num ={qian,bai,shi,ge};
  
endmodule

数码管动态显示模块

//reg [15:0] display_num;

  



module seg7(
			input clk,		//时钟信号,50MHz
			input rst_n,	//复位信号,低电平有效
			input[15:0] display_num,	//数码管显示数据,[15:12]--数码管千位,[11:8]--数码管百位,[7:4]--数码管十位,[3:0]--数码管个位
			output reg[3:0] dtube_cs_n,	//7段数码管位选信号
			output reg[7:0] dtube_data	//7段数码管段选信号(包括小数点为8段)
		);
 
//-------------------------------------------------
//参数定义
 
//数码管显示 0~F 对应段选输出
parameter 	NUM0 	= 8'h3f,//c0,
			NUM1 	= 8'h06,//f9,
			NUM2 	= 8'h5b,//a4,
			NUM3 	= 8'h4f,//b0,
			NUM4 	= 8'h66,//99,
			NUM5 	= 8'h6d,//92,
			NUM6 	= 8'h7d,//82,
			NUM7 	= 8'h07,//F8,
			NUM8 	= 8'h12,//80,
			NUM9 	= 8'h6f,//90,
			NUMA 	= 8'h77,//88,
			NUMB 	= 8'h7c,//83,
			NUMC 	= 8'h39,//c6,
			NUMD 	= 8'h5e,//a1,
			NUME 	= 8'h38,//86,
			NUMF 	= 8'h71,//8e;
			NDOT	= 8'h80;	//小数点显示
 
//数码管位选 0~3 对应输出
parameter	CSN		= 4'b1111,
			CS0		= 4'b1110,
			CS1		= 4'b1101,
			CS2		= 4'b1011,
			CS3		= 4'b0111;
 
//-------------------------------------------------
//分时显示数据控制单元
reg[3:0] current_display_num;	//当前显示数据
reg[7:0] div_cnt;	//分时计数器
 
	//分时计数器
always @(posedge clk or negedge rst_n)
	if(!rst_n) div_cnt <= 8'd0;
	else div_cnt <= div_cnt+1'b1;
 
	//显示数据
always @(posedge clk or negedge rst_n)
	if(!rst_n) current_display_num <= 4'h0;
	else begin
		case(div_cnt)
			8'hff: current_display_num <= display_num[3:0];
			8'h3f: current_display_num <= display_num[7:4];
			8'h7f: current_display_num <= display_num[11:8];
			8'hbf: current_display_num <= display_num[15:12];
			default: ;
		endcase
	end
		
	//段选数据译码
always @(posedge clk or negedge rst_n)
	if(!rst_n) dtube_data <= NUM0;
	else begin
		case(current_display_num) 
			4'h0: dtube_data <= NUM0;
			4'h1: dtube_data <= NUM1;
			4'h2: dtube_data <= NUM2;
			4'h3: dtube_data <= NUM3;
			4'h4: dtube_data <= NUM4;
			4'h5: dtube_data <= NUM5;
			4'h6: dtube_data <= NUM6;
			4'h7: dtube_data <= NUM7;
			4'h8: dtube_data <= NUM8;
			4'h9: dtube_data <= NUM9;
			4'ha: dtube_data <= NUMA;
			4'hb: dtube_data <= NUMB;
			4'hc: dtube_data <= NUMC;
			4'hd: dtube_data <= NUMD;
			4'he: dtube_data <= NUME;
			4'hf: dtube_data <= NUMF;
			default: ;
		endcase
	end
 
	//位选译码
always @(posedge clk or negedge rst_n)
	if(!rst_n) dtube_cs_n <= CSN;
	else begin
		case(div_cnt[7:6])
			2'b00: dtube_cs_n <= CS0;
			2'b01: dtube_cs_n <= CS1;
			2'b10: dtube_cs_n <= CS2;
			2'b11: dtube_cs_n <= CS3;
			default:  dtube_cs_n <= CSN;
		endcase
	end
	
 
endmodule
 

 

蜂鸣器模块

module beep_ctr(

input clk,
input rst_n,
input beep1,
output reg beep
);




reg[19:0] cnt;		//20位计数器
 
	//cnt计数器进行0-999999的循环计数,即ext_clk_25m时钟的1000000分频,对应cnt一个周期为25Hz
always @(posedge clk or negedge rst_n)	
	if(!rst_n) cnt <= 20'd0;
	else if(cnt < 20'd999_99) cnt <= cnt+1'b1;
	else cnt <= 20'd0;

always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        beep <= 0;
		  
		  end
    else if(cnt < 20'd500_00 && beep1)
        beep <= ~beep;
    else
        beep <= 1'b0;


endmodule
  

按键消抖模块

// ********************************************************************
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
// ********************************************************************
// File name    : debounce.v
// Module name  : debounce
// Author       : STEP
// Description  : 
// Web          : www.stepfpga.com
// 
// --------------------------------------------------------------------
// Code Revision History : 
// --------------------------------------------------------------------
// Version: |Mod. Date:   |Changes Made:
// V1.0     |2017/03/02   |Initial ver
// --------------------------------------------------------------------
// Module Function:按键消抖
 
module debounce_button (clk,rst,key,key_pulse);
 
        parameter       N  =  2;                      //要消除的按键的数量
 
	input             clk;
        input             rst;
        input 	[N-1:0]   key;                        //输入的按键					
	output  [N-1:0]   key_pulse;                  //按键动作产生的脉冲	
 
        reg     [N-1:0]   key_rst_pre;                //定义一个寄存器型变量存储上一个触发时的按键值
        reg     [N-1:0]   key_rst;                    //定义一个寄存器变量储存储当前时刻触发的按键值
 
        wire    [N-1:0]   key_edge;                   //检测到按键由高到低变化是产生一个高脉冲
 
        //利用非阻塞赋值特点,将两个时钟触发时按键状态存储在两个寄存器变量中
        always @(posedge clk  or  negedge rst)
          begin
             if (!rst) begin
                 key_rst <= {N{1'b1}};                //初始化时给key_rst赋值全为1,{}中表示N个1
                 key_rst_pre <= {N{1'b1}};
             end
             else begin
                 key_rst <= key;                     //第一个时钟上升沿触发之后key的值赋给key_rst,同时key_rst的值赋给key_rst_pre
                 key_rst_pre <= key_rst;             //非阻塞赋值。相当于经过两个时钟触发,key_rst存储的是当前时刻key的值,key_rst_pre存储的是前一个时钟的key的值
             end    
           end
 
        assign  key_edge = key_rst_pre & (~key_rst);//脉冲边沿检测。当key检测到下降沿时,key_edge产生一个时钟周期的高电平
 
        reg	[3:0]	  cnt;                       //产生延时所用的计数器,系统时钟50MHz,要延时20ms左右时间,至少需要20位计数器     
 
        //产生20ms延时,当检测到key_edge有效是计数器清零开始计数
        always @(posedge clk or negedge rst)
           begin
             if(!rst)
                cnt <= 4'h0;
             else if(key_edge)
                cnt <= 4'h0;
             else
                cnt <= cnt + 1'h1;
             end  
 
        reg     [N-1:0]   key_sec_pre;                //延时后检测电平寄存器变量
        reg     [N-1:0]   key_sec;                    
 
 
        //延时后检测key,如果按键状态变低产生一个时钟的高脉冲。如果按键状态是高的话说明按键无效
        always @(posedge clk  or  negedge rst)
          begin
             if (!rst) 
                 key_sec <= {N{1'b1}};                
             else if (cnt==4'hf)
                 key_sec <= key;  
          end
       always @(posedge clk  or  negedge rst)
          begin
             if (!rst)
                 key_sec_pre <= {N{1'b1}};
             else                   
                 key_sec_pre <= key_sec;             
         end      
       assign  key_pulse = key_sec_pre & (~key_sec);     
 
endmodule



testbench
到此结束,如有问题请留言评论文章来源地址https://www.toymoban.com/news/detail-765815.html

到了这里,关于基于FPGA的数字密码锁的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的电子密码锁设计论文(含视频代码仿真)

    写在前面:本设计仅供学习参考,不保证正确,免费分享,恳请关注一下 源码来自大佬:http://t.csdn.cn/Oxtcg 稍作改动 实物演示视频:基于FPGA的电子密码锁,Verilog HDL语言实现_哔哩哔哩_bilibili 基于FPGA的电子密码锁设计 摘要 基于FPGA的电子密码锁已经是现代生活中经常用到的工

    2024年02月08日
    浏览(52)
  • 基于FPGA的通用电子密码锁VHDL代码Quartus仿真

    名称:基于FPGA的通用电子密码锁VHDL代码Quartus仿真(文末获取) 软件:Quartus 语言:VHDL 代码功能: 电子密码锁要求 (1)如果按下数字键,第-个数字会从显示器的最右端开始显示,此后每新按一个数字时,显示器上的数字必须左移一格,以便将新的数字显示出来。 (2)假如要更

    2024年03月22日
    浏览(49)
  • 基于FPGA的电子密码锁的设计VHDL代码Quartus仿真

    名称:基于FPGA的电子密码锁的设计VHDL代码Quartus仿真(文末获取) 软件:Quartus 语言:VHDL 代码功能: 电子密码锁的设计 设计任务:     1.密码输入:每按下一个数字键,就输入一个数值,并在显示器上显示该数值,同时将先前输入的数据依次左移一位;     2.密码清除:按

    2024年03月14日
    浏览(57)
  • 微机课设 | 基于STC15单片机的简易数字密码锁设计

    在日常的生活和工作中,住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。若使用传统的机械式钥匙开锁,人们常需携带多把钥匙, 使用极不方便, 且钥匙丢失后安全性即大打折扣。在安全技术防范领域,具有防盗报警功能的

    2024年02月04日
    浏览(57)
  • EDA课设(数字系统设计)--数字密码锁

    目录 1,注意 2,可能遇到的问题 3,题目描述 4,实现前期准备 5,实现代码 6,引脚设置 7,部分验证 该博客是根据自己的课设报告写的,所以大家不要抄袭,仅用作给大家提供实现思路以及一些经验,希望大家根据我写的东西,理解关键的代码,较为熟练的掌握VHDL语言的语

    2024年02月08日
    浏览(40)
  • 西电微原课设——矩阵式键盘数字密码锁设计

    一、课程设计目的 掌握微机系统总线与各芯片管脚连接方法,提高接口扩展硬件电路连接能力。 初步掌握键盘扫描,密码修改和计时报警程序的编写方法。 掌握通过矩阵式键盘扫描实现密码锁功能的设计思路和实现方法。 二、课程设计内容 根据设定好的密码,采用4x4矩阵

    2024年02月13日
    浏览(77)
  • 【AT89C52单片机项目】数字密码锁设计

    实验目的 使用单片机设计数字密码锁。 实验仪器 一套STC89C52RC开发板套件,包括STC89C52RC开发板,以及USB烧录线。 设计要求 1、有设置密码、开锁工作模式; 2、可以每次都设置密码,也可以设置一次密码多次使用。 实验原理 本实验所需要的主要硬件电路介绍 1)、矩阵按键

    2024年02月07日
    浏览(43)
  • 基于单片机智能电子密码锁设计

    ** 单片机设计介绍,基于单片机智能电子密码锁设计   基于单片机的智能电子密码锁设计是一种利用单片机(如Arduino、Raspberry Pi等)和相关电子元件来实现的电子密码锁系统。下面是一个基本设计的介绍: 系统组成: 单片机模块:负责控制和处理密码输入、验证和锁控制

    2024年02月03日
    浏览(61)
  • 基于单片机的电子密码锁设计

    1.设计任务 利用AT89C51单片机为核心控制元件,设计一个简易的电子密码锁,可设置四位密码,输入错误三次,报警灯亮起(红灯亮起),输入正确,绿灯闪烁三次。可通过LCD显示屏查看密码,并可通过特殊键位清除密码。 本系统由AT89C51单片机系统(主要是AT89C51单片机最小系

    2024年02月02日
    浏览(46)
  • 基于51单片机的密码锁设计

    电子密码锁设计,以AT89C51为主控,晶振电路和复位电路共同组成最小系统,使得单片机可以正常运行。矩阵按键作为输入模块,输入密码,LCD1602作为显示设备,显示输入的密码和提示语句,AT24C02作为EEPROM存储器,使用LED模拟“锁”,表示锁的开启和关闭状态。系统掉电后,

    2024年02月11日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包