北邮小学期简易密码锁实验报告

简易智能密码锁实验报告

                               

一、   实验要求:

设计并实现一个数字密码锁,密码锁有四位数字密码和一个确认开锁按键,密码输入正确,密码锁打开,密码输入错误进行警示。

基本要求:

1、密码设置:通过键盘进行4 位数字密码设定输入,在数码管上显示所输入数字。通过密码设置确定键(BTN 键)进行锁定。

2、开锁:在闭锁状态下,可以输入密码开锁,且每输入一位密码,在数码管上显示“-”,提示已输入密码的位数。输入四位核对密码后,按“开锁”键,若密码正确则系统开锁,若密码错误系统仍然处于闭锁状态,并用蜂鸣器或led 闪烁报警。

3、在开锁状态下,可以通过密码复位键(BTN 键)来清除密码,恢复初始密码“0000”。

闭锁状态下不能清除密码。

4、用点阵显示开锁和闭锁状态。

提高要求:

1、输入密码数字由右向左依次显示,即:每输入一数字显示在最右边的数码管上,同时将先前输入的所有数字向左移动一位。

2、密码锁的密码位数(4~6 位)可调。

二、   系统设计:

1、设计思路:在数字电路设计中,自顶向下设计方法的主要思想是对数字系统进行划分,将复杂的设计原理简化为相对简单的模块设计,不同的模块用来完成数字系统中某一部分的具体功能。

           总体思路:

 

    

 

2、     改密码状态总体框图:

Btn7(set)       状态转移图:

 

三、   仿真波形及波形分析

1、     键盘输入模块

                                     图3-1 键盘输入仿真

   

     在上图中,clkjp时钟控制jpcat,jpcat控制kbout从0111到1110变换,然后手动控制kbin来模拟键盘的案件,从jpout就能看到的键入的数字。

2、     防抖

                        图3-2 防抖仿真

上图中可以看见,btn1只在上升沿才有用,而clear会持续到一个周期的最后才会完毕。

3、     状态转移

图3-3 状态转移模块仿真

如上图所示,

开始,按下set=1,set1=1,setmode=1,进入设置密码状态。

然后,jpout连续输入2和6,改了密码,然后btn2=1代表按下了确定键,lockmode变成1,setmode变成0,状态从设定状态变成锁定状态。

再之后,ipout输入2和6,再次btn2=1(按下确定键),lockmode变成0,状态从锁定状态变成开锁状态。

整个就实现了一个循环。

四、   源程序

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

entity mms is

port (clk : in std_logic;

      set:in std_logic;

      btn1,btn2,btnloc:in std_logic;

      smgzf: out std_logic_vector(6 downto 0);

      smgcatout:out std_logic_vector(5 downto 0);

      kbin:  in  std_logic_vector(3 downto 0);

      kbout: buffer std_logic_vector(3 downto 0);

      dzrow,dzcolr,dzcolg: out std_logic_vector(7 downto 0);

      fmq: out std_logic

      );

end mms;

architecture behave of mms is

     signal clkjp: std_logic;

     signal clksmg: std_logic;

     signal clkdz: std_logic;

     signal clkfd: std_logic;

     signal clkfm: std_logic;

     signal jpcat: integer range 0 to 3;

     signal smgcat:integer range 0 to 5;

     signal dzcat:integer range 0 to 7;

     signal tmp1: integer range 0 to 99999;--jp

     signal tmp2: integer range 0 to 999;--dz

     signal tmp3: integer range 0 to 999;--smg

     signal tmp4: integer range 0 to 2499999;--fd

     signal tmp5: integer range 0 to 20;--alarm time

     signal tmpdo: integer range 0 to 97655;--alarm time

     signal jpout:integer range 0 to 10;

     signal alarm:std_logic;  

     signal m1y,m2y,m3y,m4y:std_logic_vector(6 downto 0);

     signal m1,m2,m3,m4,mm1,mm2,mm3,mm4: integer range 0 to 9;

     signal wei:integer range 0 to 3;

     signal kwei:integer range 0 to 4; 

     signal setmode:std_logic;

     signal set1:std_logic;

     signal lockmode:std_logic;

     signal clear:  std_logic;

     signal sure: std_logic;

     signal lock: std_logic;

     signal noise:std_logic;

     signal beep:std_logic;

    

begin

    

fangdou:process(clk)  

    begin

    if(clk'event and clk='1')then

     if (tmp4=2499999) then

      tmp4<=0;clkfd<=not clkfd;

     else

      tmp4<=tmp4+1;

     end if;

    end if;

   end process;     

    

shezhi:process(set,sure) 

    begin

     if(clkfd'event and clkfd='1')then

       if(set='1')then   --set进入改密码状态

        set1<='1';

        end if;

       if(sure='1')then 

        set1<='0';

        end if;

     end if;

     end process;

    

qingling:process(btn1)

    begin

     if(clkfd'event and clkfd='1')then

       if(btn1='1')then        --clear为清零键

        clear<='1';

       else clear<='0';

        end if;

      end if;

   end process;

queding:process(btn2)

    begin

     if(clkfd'event and clkfd='1')then

       if(btn2='1')then

        sure<='1';     --sure为btn5(确定键)

       else sure<='0';

        end if;

      end if;

   end process;

  

suoding:process(btnloc)

    begin

     if(clkfd'event and clkfd='1')then

       if(btnloc='1')then   --lock为锁定键

        lock<='1';

       else lock<='0';

        end if;

      end if;

   end process;

suoyou:process(jpout)

begin

if(clkfd'event and clkfd='1')then

       alarm<='0';       

       if(lockmode='1')then         --在锁定状态

          wei<=0;

          if(jpout/=10)then  --按了键

             if(kwei=3)then mm4<=jpout;kwei<=kwei+1;

             elsif(kwei=2)then mm3<=jpout;kwei<=kwei+1;

             elsif(kwei=1)then mm2<=jpout;kwei<=kwei+1;   

             elsif(kwei=0)then mm1<=jpout;kwei<=kwei+1;        

             end if;

          end if; 

          if(sure='1')then    --进入判断密码的状态

             if((mm1=m1)and(mm2=m2)and(mm3=m3)and(mm4=m4)and(kwei=4))then lockmode<='0';alarm<='0';

             else kwei<=0;alarm<='1';   

             end if;

          end if; 

       else    --在开锁状态

          kwei<=0;

          if((lock='1'))then   --进入锁定状态

             lockmode<='1';setmode<='0';alarm<='0';

          else

             if(set1='1')then setmode<='1'; --进入改密码状态

             else setmode<='0';

             end if;

          end if;  

          if(clear='1') then   --密码直接清零然后锁定

             m1<=0;m2<=0;m3<=0;m4<=0;mm1<=0;mm2<=0;mm3<=0;mm4<=0;

             wei<=0;kwei<=0;alarm<='0';setmode<='0';lockmode<='1';

          elsif(setmode='1')then

             if(jpout/=10)then  --如有输入

               if(wei=0)then m1<=jpout;wei<=wei+1;mm1<=jpout;

               elsif(wei=1)then m2<=jpout;wei<=wei+1;mm2<=jpout;

               elsif(wei=2)then m3<=jpout;wei<=wei+1;mm3<=jpout;

               elsif(wei=3)then m4<=jpout;wei<=0;mm4<=jpout;

               end if;

             end if;

             if(sure='1')then lockmode<='1';setmode<='0';alarm<='0'; --如果按了清零

             end if;

          end if;

       end if;

end if;

end process;

       

jianpan1:process(clk)

    begin

    if(clk'event and clk='1')then

      if (tmp1=99999) then

      tmp1<=0;clkjp<=not clkjp;

      else

      tmp1<=tmp1+1;

     end if;

    end if;

   end process; 

jianpan2:process(clkjp)

    begin

     if(clkjp'event and clkjp='1')then

      if (jpcat=3)then

       jpcat<=0;

      else

       jpcat<=jpcat+1;

      end if;

     end if;

    end process;  

jianpan3:process(jpcat)

    begin

     case jpcat is

     when 0=>kbout<="0111";

     when 1=>kbout<="1011";

     when 2=>kbout<="1101";

     when 3=>kbout<="1110";

     end case;

    end process; 

jianpan4:process(jpcat)

    begin

        if((kbout="0111")and(kbin="0111"))then jpout<=0;

     elsif((kbout="0111")and(kbin="1011"))then jpout<=4;

     elsif((kbout="0111")and(kbin="1101"))then jpout<=8;

     elsif((kbout="1011")and(kbin="0111"))then jpout<=1;

     elsif((kbout="1011")and(kbin="1011"))then jpout<=5;

     elsif((kbout="1011")and(kbin="1101"))then jpout<=9;

     elsif((kbout="1101")and(kbin="0111"))then jpout<=2;

     elsif((kbout="1101")and(kbin="1011"))then jpout<=6;

     elsif((kbout="1110")and(kbin="0111"))then jpout<=3;

     elsif((kbout="1110")and(kbin="1011"))then jpout<=7;

     else jpout<=10;

       end if;

    end process;

  

mimafuzhi1:process(m1)

     begin

       case m1 is

       when 0=>m1y<="1111110";

       when 1=>m1y<="0110000";

       when 2=>m1y<="1101101";

       when 3=>m1y<="1111001";

       when 4=>m1y<="0110011";

       when 5=>m1y<="1011011";

       when 6=>m1y<="1011111";

       when 7=>m1y<="1110000";

       when 8=>m1y<="1111111";

       when 9=>m1y<="1111011";

        end case;

      end process;

mimafuzhi2:process(m2)

     begin

       case m2 is

       when 0=>m2y<="1111110";

       when 1=>m2y<="0110000";

       when 2=>m2y<="1101101";

       when 3=>m2y<="1111001";

       when 4=>m2y<="0110011";

       when 5=>m2y<="1011011";

       when 6=>m2y<="1011111";

       when 7=>m2y<="1110000";

       when 8=>m2y<="1111111";

       when 9=>m2y<="1111011";

        end case;

      end process;

mimafuzhi3:process(m3)

     begin

       case m3 is

       when 0=>m3y<="1111110";

       when 1=>m3y<="0110000";

       when 2=>m3y<="1101101";

       when 3=>m3y<="1111001";

       when 4=>m3y<="0110011";

       when 5=>m3y<="1011011";

       when 6=>m3y<="1011111";

       when 7=>m3y<="1110000";

       when 8=>m3y<="1111111";

       when 9=>m3y<="1111011";

        end case;

      end process;

mimafuzhi4:process(m4)

     begin

       case m4 is

       when 0=>m4y<="1111110";

       when 1=>m4y<="0110000";

       when 2=>m4y<="1101101";

       when 3=>m4y<="1111001";

       when 4=>m4y<="0110011";

       when 5=>m4y<="1011011";

       when 6=>m4y<="1011111";

       when 7=>m4y<="1110000";

       when 8=>m4y<="1111111";

       when 9=>m4y<="1111011";

        end case;

end process;

shumaguan1:process(clk)        --分出数码管的频率

    begin

    if(clk'event and clk='1')then

     if (tmp3=999) then

      tmp3<=0;clksmg<=not clksmg;

     else

      tmp3<=tmp3+1;

     end if;

    end if;

   end process;    

shumaguan2:process(clksmg)   --数码管按位扫描

    begin

     if(clksmg'event and clksmg='1')then

      if (smgcat=5)then

       smgcat<=0;

      else

       smgcat<=smgcat+1;

      end if;

     end if;

    end process;  

shumaguan3:process(setmode,lockmode,smgcat)   --数码管按位扫描出的数字

    begin

     if(setmode='1')then

      case smgcat is

       when 0=>smgcatout<="110111";smgzf<=m1y;

       when 1=>smgcatout<="111011";smgzf<=m2y;

       when 2=>smgcatout<="111101";smgzf<=m3y;

       when 3=>smgcatout<="111110";smgzf<=m4y;

       when 4=>smgcatout<="111111";

       when 5=>smgcatout<="111111";

       end case;

     elsif(lockmode='0')then

       case smgcat is

       when 0=>smgcatout<="110111";smgzf<=m1y;

       when 1=>smgcatout<="111011";smgzf<=m2y;

       when 2=>smgcatout<="111101";smgzf<=m3y;

       when 3=>smgcatout<="111110";smgzf<=m4y;

       when 4=>smgcatout<="111111";

       when 5=>smgcatout<="111111";

       end case;

      else

       smgzf<="0000001";

       if (kwei=1)then smgcatout<="111110";

       elsif (kwei=2)then smgcatout<="111100";

       elsif (kwei=3)then smgcatout<="111000";

       elsif (kwei=4)then smgcatout<="110000";

       else smgcatout<="111111";

       end if;

      end if;

     end process;

                

dianzhen1:process(clk)

    begin

    if(clk'event and clk='1')then

     if (tmp2=999) then

      tmp2<=0;clkdz<=not clkdz;

     else

      tmp2<=tmp2+1;

     end if;

    end if;

   end process;  

dianzhen2:process(clkdz)

    begin

     if(clkdz'event and clkdz='1')then

      if (dzcat=7)then

       dzcat<=0;

      else

       dzcat<=dzcat+1;

      end if;

     end if;

    end process;       

dianzhen3:process(lockmode,clkdz)

  begin

   if(lockmode='0')then

     case dzcat is--√

       when 0=>dzrow<="01111111";dzcolr<="00000000";dzcolg<="11111111";

       when 1=>dzrow<="10111111";dzcolr<="00000000";dzcolg<="11111111";

       when 2=>dzrow<="11011111";dzcolr<="00000000";dzcolg<="01100110";

       when 3=>dzrow<="11101111";dzcolr<="00000000";dzcolg<="11111111";

       when 4=>dzrow<="11110111";dzcolr<="00000000";dzcolg<="11111111";

       when 5=>dzrow<="11111011";dzcolr<="00000000";dzcolg<="01100110";

       when 6=>dzrow<="11111101";dzcolr<="00000000";dzcolg<="01100110";

       when 7=>dzrow<="11111110";dzcolr<="00000000";dzcolg<="11000110";

      end case;

   else

     case dzcat is--X

       when 0=>dzrow<="01111111";dzcolr<="10111111";dzcolg<="00000000";

       when 1=>dzrow<="10111111";dzcolr<="00001001";dzcolg<="00000000";

       when 2=>dzrow<="11011111";dzcolr<="10111101";dzcolg<="00000000";

       when 3=>dzrow<="11101111";dzcolr<="10001001";dzcolg<="00000000";

       when 4=>dzrow<="11110111";dzcolr<="10101001";dzcolg<="00000000";

       when 5=>dzrow<="11111011";dzcolr<="10001001";dzcolg<="00000000";

       when 6=>dzrow<="11111101";dzcolr<="10011011";dzcolg<="00000000";

       when 7=>dzrow<="11111110";dzcolr<="10001001";dzcolg<="00000000";

      end case;

    end if;

 end process;       

  

fmq1:process(alarm)

begin

   if(alarm='1')then

     if(clkfd'event and clkfd='1')then

       if(tmp5=2)then

       tmp5<=0;noise<='0';

       else tmp5<=tmp5+1;noise<='1';

       end if;

     end if;

   else noise<='0';

   end if;

end process;   

fmq2:process(clk)

begin

  if(clk'event and clk='1')then

     if (tmpdo=97655) then

     tmpdo<=0;clkfm<=not clkfm;

     else

     tmpdo<=tmpdo+1;

     end if;

   end if;

end process;

fmq3:process(noise)

  begin

    if(noise='1')then

      if(clkfm'event and clkfm='1')then

      beep<=not beep;

      end if;

    else beep<='0';

    end if;

 end process;

fmq4:process(beep)

begin

    fmq<=beep;

end process;

   

 end behave;

  

五、   功能说明及资源利用

1、   功能说明

     本人设计的这个简易密码锁有五个基本状态,启动程序时在开锁状态,按下btn7进入修改密码的状态,修改密码之后按下btn5进入闭锁状态,再之后直接输入验证密码,按下btn5确定后,进入验证密码的状态,如果不正确,蜂鸣器响并进入闭锁状态,若正确就回到开锁状态,这样形成一个循环。

2、   资源利用

逻辑单元利用26%,管脚用了51个。

图5-1

图5-2

图5-3

六、   故障及问题分析

在最开始编代码的时候对4*4键盘的输入不是很了解,导致长时间卡在这个地方,后来我上网查了一下这方面的资料,深刻了解了这个按键的原理之后,将kbout设置为buffer,意思就是一个process读取它的时候另外一个process也在赋值,这样就解决了这个输入问题。

   在最后研究蜂鸣器的时候发现在修改密码的时候也会叫,寻找原因发现我之前写的蜂鸣器叫的条件是原始密码和验证密码不一样就叫,在修改密码状态就改变了原始密码,导致蜂鸣器启动,解决办法是加了一个控制变量愉快解决。

七、   总结和结论

在这个历时一个月的数电实验期间,我去了六七次实验室,每次写一点点改进一点点才写成了最后的这个简易密码锁,现在感觉收获了很多,首先是对整个vhdl语言的理解和简易的一些装置的理解更加深刻了,其次是让自己的独立思考和解决问题的能力增强了。在实践中寻找问题,在解决问题的过程中进步是我这一个月的一种状态,感谢数电实验给我这个机会。

相关推荐