找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6132|回复: 1
收起左侧

用单片机数码管和矩阵按键实现密码锁功能 附原理图+源程序

[复制链接]
ID:673128 发表于 2020-2-18 17:32 | 显示全部楼层 |阅读模式
  用数码管和矩阵按键实现密码锁功能,我的理解是实现输入数据并判断数据是否和密码一致,并且更改密码。矩阵按键是4×4的,图在下面。先说功能,初始密码值4321。第一部分:当数码管未进行闪烁的时候,按下S11是进行数据和密码的比较,当正确时数码管显示1111,错误显示2222。按下S12进行数据移位(口误了,应该是数据选择而不是数据移位,但意思大家一定要理解,因为下面的我都口误了),这时数码管闪烁,你按下S1到S10可以进行设定,当按四次S12的时候或者按下S13可以不闪烁了,这时按下S11才能进行数据比较(意思是只有不闪烁才能进行数据比较)。这是数据和密码的比较。第二部分:当数码管不进行闪烁的时候才能进行密码的更改,按下S14显示密码值。按下S15时进行密码值的选择,也就是闪烁,按下S1到S10可以进行数码值的改变,按四次S15或者按一次S16可以将数码管闪烁消除,再按一次S14可以退出密码设置,问题在于你如果按了S11到S13会改变数据数值吗?同理在数据和密码比较的时候你要是按了S14到S16会对密码造成影响吗?这是标志位的设定问题大家思考一下。自己写一遍是最好的,会发现很多问题考虑。
  我们还按照从小到大,从浅入深的方法解决这个问题。


  步骤一、考虑一下你的数据如何从矩阵按键输送给数码管,这里面大家可以想一下如何解决这个问题,我用了函数封装以及调用。(这里有一个很有意思的东西,大家好好考虑一下,超有意思)


  步骤二、考虑如何实现输入数据,数据的输入方式是从右向左依次输入,举个例子就是输入4321,显示就是4321,,这是规则。


  步骤三、实现数据输入后,再进行输入数据和密码的比较,当正确的时候显示1111,错误显示2222。


这是这个程序的骨架,以后的程序都是在上面的添加。

  步骤四、当按下S12的时候(也就是输入数据11,我程序中用的都是数据),进行移位操作,数码管会进行闪烁。这是可以更改数据,当你按四次S12或者按下S13的时候数码管不会闪烁了,这时再按一下S11,就是数据和密码的比较,这也是规则。当你在数码管闪烁的时候按S11是不会进行比较的(规则)。这时程序已经开始丰满了。


步骤五、进行改变密码操作,这个操作和改变数据操作很相似,但由于太相似了,所以会有所冲突,这时就需要条件才能保证程序的正常运行。具体操作手法就是用数据和密码的移位的标志位来限制数据和密码的比较(按下S11)和更改密码的按键(S14),这样避免了在你按错键又看不到现象的情况下,程序自己在两者之间不断运行。

总结:没必要太过纠结于别人程序怎么写,先看现象理解那个程序的功能,想好思路,自己写一遍(由浅入深一步步来,不要一步成,写程序大忌)。出了问题自己找解决办法,没法解决参考别人的也可以。记住一定要保证基层骨架的完美,才可进行复杂功能的添加。大家只需要找到自己需要的一部分就行了。


  程序我觉得最重要的部分:矩阵函数的封装,移位时数码管的闪烁,如何将大于9的数不显示在数码管上,进行密码改变时的标志位设定,数据和密码的比较与密码改变的互锁关系,定时器开关的设定(TR0=1或0)

电路原理图如下:

图片1.png

单片机源程序如下:
  1. #include "digdisplay.h"                        //矩阵按键输入10(键表面为S11,程序中默认都是数值)为密码确认,矩阵按键输入11为移位操作按钮,输入12为移位后闪烁的确认键,按下之后便会不闪烁;
  2. #include "key.h"                                //矩阵按键输入13将进行密码的设定,输入14为密码的移位,输入15为结束闪烁
  3. u8 digdate[4]={0,0,0,0};                //存放输入数值
  4. u8 digcode[4]={1,2,3,4};                //存放密码值
  5. u8 knum=0,flag0,flag1=1,knum1=0;         //knum代表数据的移动位置,flag0代表移位闪烁标志位,flag1代表更改密码操作的标志位,knum1是进行密码移位的操作数
  6. u8 time;                        //定时器中断时间计时,
  7. void keyprogress()                                //检测密码的输入并进行判断
  8. {
  9.    u8 keynum;
  10.    keynum=KeyDown();                 //if的判断语句里应该不要加含有return的语句,我把KeyDown()放到if()里面程序错误了。
  11.    if(keynum!=0xff)                         //检测按键是否按下,如果矩阵按键程序返回值不是0xff,说明是在输入密码值
  12. {
  13.    if(keynum==13&&knum==0&&knum1==0)                         //13代表着是否密码需要更改,默认不需要更改,不在闪烁的时候进行更改,程序一步步走
  14.    {
  15.       flag1=!flag1;                         //改变输入数据和密码的标志位变化
  16.    }
  17.    if(flag1)
  18.   {
  19.    if(keynum==11)                         //代表开始移位,定时器中断开始
  20.    {
  21.      knum++;                         //代表4个数码管的某一位改变
  22.          if(knum==5)                         //代表移位四次了,
  23.          {
  24.             knum=0;                                 //变为初始状态,为确认做准备
  25.          }
  26.          if(knum!=0)                         //有按键按下
  27.          {
  28.             if(TR0!=1)                         //如果定时器没开启
  29.                 {
  30.                   TR0=1;                         //开启定时器
  31.                 }
  32.          }
  33.          else                                         //按键按了五次回到knum=0时,
  34.          {
  35.                    if(TR0!=0)                         //如果定时器开启
  36.                 {
  37.                    TR0=0;                         //关闭定时器
  38.                 }
  39.          }
  40.    }
  41.    if(knum==0)                                 //代表没有进行移位时可以进行密码输入操作
  42.    {
  43.       if(keynum<=9)       
  44.          {
  45.       digdate[3]=digdate[2];
  46.       digdate[2]=digdate[1];
  47.       digdate[1]=digdate[0];
  48.           digdate[0]=keynum;
  49.          }
  50.    }
  51.    else if(knum==1)                                 //代表第零位数码管需要改变数值
  52.    {
  53.       if(keynum<=9)                                 //防止按下移位按钮的时候显示b
  54.          {
  55.       digdate[0]=keynum;        //结合显示函数写
  56.          }
  57.          else if(keynum==12)
  58.          {
  59.            knum=0;
  60.            if(TR0!=0)
  61.            {
  62.              TR0=0;
  63.            }
  64.          }
  65.    }
  66.    else if(knum==2)
  67.    {
  68.       if(keynum<=9)
  69.          {       
  70.       digdate[1]=keynum;     //结合显示函数写
  71.          }
  72.          else if(keynum==12)
  73.          {
  74.            knum=0;
  75.            if(TR0!=0)
  76.            {
  77.               TR0=0;
  78.            }
  79.          }
  80.    }
  81.    else if(knum==3)
  82.    {
  83.      if(keynum<=9)       
  84.          {
  85.       digdate[2]=keynum;     //结合显示函数写
  86.          }
  87.          else if(keynum==12)
  88.          {
  89.            knum=0;
  90.            if(TR0!=0)
  91.            {
  92.               TR0=0;
  93.            }
  94.          }
  95.    }
  96.    else if(knum==4)
  97.    {
  98.      if(keynum<=9)       
  99.          {
  100.       digdate[3]=keynum;     //结合显示函数写
  101.          }
  102.          else if(keynum==12)
  103.          {
  104.            knum=0;
  105.            if(TR0!=0)
  106.            {
  107.               TR0=0;
  108.            }
  109.          }
  110.    }

  111.    if(keynum==10&&knum==0&&knum1==0)  //当矩阵按键值为10,且没有移位的时候才能判断
  112.    {
  113.     if(digdate[3]==digcode[3]&&digdate[2]==digcode[2]&&digdate[1]==digcode[1]&&digdate[0]==digcode[0])
  114.         {
  115.            digdate[3]=1;
  116.            digdate[2]=1;
  117.            digdate[1]=1;
  118.            digdate[0]=1;
  119.         }
  120.         else
  121.         {                                       
  122.            digdate[3]=2;
  123.            digdate[2]=2;
  124.            digdate[1]=2;
  125.            digdate[0]=2;
  126.         }
  127.    }
  128.   }
  129.   else                                  //如果密码进行更改
  130.   {
  131.       if(keynum==14)   //密码开始移位的按键
  132.           {
  133.              knum1++;
  134.                  if(knum1==5)
  135.                  {
  136.                    knum1=0;
  137.                  }
  138.                  if(knum1!=0)
  139.                  {
  140.                     if(TR0!=1)
  141.                         {
  142.                           TR0=1;
  143.                         }
  144.                  }
  145.                  else
  146.                  {
  147.                     if(TR0!=0)
  148.                         {
  149.                           TR0=0;
  150.                         }
  151.                  }
  152.           }
  153.           if(knum1==0)
  154.           {
  155.              if(keynum<=9)         
  156.                  {
  157.                     digcode[3]=digcode[2];
  158.                     digcode[2]=digcode[1];
  159.                     digcode[1]=digcode[0];
  160.                         digcode[0]=keynum;
  161.                  }
  162.           }
  163.           else if(knum1==1)
  164.           {
  165.              if(keynum<=9)
  166.                  {
  167.                     digcode[0]=keynum;
  168.                  }
  169.                  else if(keynum==15)
  170.                  {
  171.                     knum1=0;
  172.                         if(TR0!=0)
  173.                         {
  174.                           TR0=0;
  175.                         }
  176.                  }
  177.           }
  178.           else if(knum1==2)
  179.           {
  180.              if(keynum<=9)
  181.                  {
  182.                     digcode[1]=keynum;
  183.                  }
  184.                  else if(keynum==15)
  185.                  {
  186.                     knum1=0;
  187.                         if(TR0!=0)
  188.                         {
  189.                           TR0=0;
  190.                         }
  191.                  }
  192.           }
  193.           else if(knum1==3)
  194.           {
  195.              if(keynum<=9)
  196.                  {
  197.                     digcode[2]=keynum;
  198.                  }
  199.                  else if(keynum==15)
  200.                  {
  201.                     knum1=0;
  202.                         if(TR0!=0)
  203.                         {
  204.                            TR0=0;
  205.                         }
  206.                  }
  207.           }
  208.           else if(knum1==4)
  209.           {
  210.              if(keynum<=9)
  211.                  {
  212.                     digcode[3]=keynum;
  213.                  }
  214.                  else if(keynum==15)
  215.                  {
  216.                     knum1=0;
  217.                         if(TR0!=0)
  218.                         {
  219.                           TR0=0;
  220.                         }
  221.                  }
  222.           }
  223.   }
  224. }
  225. }

  226. void display()                          //显示函数的实现
  227. {  
  228.   if(flag1)
  229. {
  230.   if(knum==0)
  231. {
  232.   digdisplay(3,digdate[3]);
  233.   digdisplay(2,digdate[2]);
  234.   digdisplay(1,digdate[1]);
  235.   digdisplay(0,digdate[0]);
  236. }
  237. else if(knum==1)
  238. {
  239.    if(flag0)
  240.    {
  241.      digdisplay(3,digdate[3]);
  242.      digdisplay(2,digdate[2]);
  243.      digdisplay(1,digdate[1]);
  244.      digdisplay(0,digdate[0]);
  245.    }
  246.    else
  247.    {
  248.      digdisplay(3,digdate[3]);
  249.      digdisplay(2,digdate[2]);
  250.      digdisplay(1,digdate[1]);
  251.      digdisplay(0,17);                  //显示空白
  252.    }
  253. }
  254. else if(knum==2)
  255. {
  256.    if(flag0)
  257.    {
  258.      digdisplay(3,digdate[3]);
  259.      digdisplay(2,digdate[2]);
  260.      digdisplay(1,digdate[1]);
  261.      digdisplay(0,digdate[0]);     
  262.    }
  263.    else
  264.    {
  265.      digdisplay(3,digdate[3]);
  266.      digdisplay(2,digdate[2]);
  267.      digdisplay(1,17);
  268.      digdisplay(0,digdate[0]);   
  269.    }
  270. }
  271. else if(knum==3)
  272. {
  273.    if(flag0)
  274.    {
  275.      digdisplay(3,digdate[3]);
  276.      digdisplay(2,digdate[2]);
  277.      digdisplay(1,digdate[1]);
  278.      digdisplay(0,digdate[0]);      
  279.    }
  280.    else
  281.    {
  282.      digdisplay(3,digdate[3]);
  283.      digdisplay(2,17);
  284.      digdisplay(1,digdate[1]);
  285.      digdisplay(0,digdate[0]);   
  286.    }
  287. }
  288.    else if(knum==4)
  289.   {
  290.    if(flag0)
  291.    {
  292.      digdisplay(3,digdate[3]);
  293.      digdisplay(2,digdate[2]);
  294.      digdisplay(1,digdate[1]);
  295.      digdisplay(0,digdate[0]);
  296.    }
  297.    else
  298.    {
  299.      digdisplay(3,17);
  300.      digdisplay(2,digdate[2]);
  301.      digdisplay(1,digdate[1]);
  302.      digdisplay(0,digdate[0]);
  303.    }
  304.   }
  305. }
  306. else
  307. {
  308.     if(knum1==0)                   //开始显示密码
  309.         {
  310.           digdisplay(3,digcode[3]);
  311.       digdisplay(2,digcode[2]);
  312.       digdisplay(1,digcode[1]);
  313.       digdisplay(0,digcode[0]);
  314.         }
  315.         else if(knum1==1)
  316.         {
  317.            if(flag0)
  318.           {
  319.            digdisplay(3,digcode[3]);
  320.        digdisplay(2,digcode[2]);
  321.        digdisplay(1,digcode[1]);
  322.        digdisplay(0,digcode[0]);             
  323.           }
  324.           else
  325.           {
  326.            digdisplay(3,digcode[3]);
  327.        digdisplay(2,digcode[2]);
  328.        digdisplay(1,digcode[1]);
  329.        digdisplay(0,17);          
  330.           }
  331.         }
  332.         else if(knum1==2)
  333.         {
  334.           if(flag0)
  335.           {
  336.            digdisplay(3,digcode[3]);
  337.        digdisplay(2,digcode[2]);
  338.        digdisplay(1,digcode[1]);
  339.        digdisplay(0,digcode[0]);
  340.           }
  341.           else
  342.           {
  343.            digdisplay(3,digcode[3]);
  344.        digdisplay(2,digcode[2]);
  345.        digdisplay(1,17);
  346.        digdisplay(0,digcode[0]);            
  347.           }          
  348.         }
  349.         else if(knum1==3)
  350.         {
  351.           if(flag0)
  352.           {
  353.            digdisplay(3,digcode[3]);
  354.        digdisplay(2,digcode[2]);
  355.        digdisplay(1,digcode[1]);
  356.        digdisplay(0,digcode[0]);          
  357.           }
  358.           else
  359.           {
  360.            digdisplay(3,digcode[3]);
  361.        digdisplay(2,17);
  362.        digdisplay(1,digcode[1]);
  363.        digdisplay(0,digcode[0]);
  364.           }
  365.         }
  366.         else if(knum1==4)
  367.         {
  368.           if(flag0)
  369.           {
  370.            digdisplay(3,digcode[3]);
  371.        digdisplay(2,digcode[2]);
  372.        digdisplay(1,digcode[1]);
  373.        digdisplay(0,digcode[0]);          
  374.           }
  375.           else
  376.           {
  377.            digdisplay(3,17);
  378.        digdisplay(2,digcode[2]);
  379.        digdisplay(1,digcode[1]);
  380.        digdisplay(0,digcode[0]);          
  381.           }
  382.         }
  383. }
  384. }
  385.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
  386. void main()
  387. {
  388.    TMOD &= 0xF0;   //设置定时器模式        10毫秒定时中断
  389.    TMOD |= 0x01;   //设置定时器模式
  390.    TL0 = 0xF0;           //设置定时初值
  391.    TH0 = 0xD8;           //设置定时初值
  392.    TF0 = 0;                   //清除TF0标志
  393.    ET0=1;      
  394.    EA=1;
  395.    while(1)
  396.    {
  397.         keyprogress();
  398.                 display();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
  399.    }
  400. }
  401. void  Timer0() interrupt 1
  402. {
  403.    TL0 = 0xF0;                //设置定时初值
  404.    TH0 = 0xD8;                //设置定时初值
  405.    if(knum!=0||knum1!=0)   //数码管显示所需的条件,二合一。
  406.   {
  407.    time++;
  408.    if(time==50)                //进行0.5秒的计时
  409.    {
  410.       time=0;
  411.           flag0=!flag0;
  412.    }
  413.   }
  414. }
复制代码

全部资料51hei下载地址:
用数码管以及矩阵按键实现密码锁功能.rar (38.4 KB, 下载次数: 38)






评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2020-2-21 00:25 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表