找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3318|回复: 0
打印 上一主题 下一主题
收起左侧

单片机八位数码管+矩阵键盘密码锁Proteus仿真程序

[复制链接]
跳转到指定楼层
楼主
定时中断法实现1ms定时扫描,主程序执行按键识别矩阵键盘接在P0口,八位一体数显的位控由P2口完成经过三极管方向驱动共阳级,P1口通过245驱动段码,在仿真图里面用反相器4069替代三极管驱动


单片机源程序如下:
  1. #include<reg51.h>
  2. sbit SPEAK=P3^7;
  3. sbit LED_RED=P3^6;        // 红色LED点亮表示密码错误
  4. sbit LED_GREEN=P3^5;// 绿色LED点亮表示密码正确
  5. bit flag=0;        // 标志位
  6. unsigned char data  buffer[8]={0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF}; //缓存器存放输入的密码,初始"-"
  7. unsigned char data keycode[8]={1,2,3,4,5,6,7,8}; // 原始密码
  8. unsigned char code led[]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  9.                                                         0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E    };//共阳数显段码         
  10. void delay(unsigned int i)        // 延时
  11.         {
  12.          unsigned int k;
  13.          for(k=0;k<i;k++);
  14.         }


  15. // 1毫秒中断,8位一体数显扫描输出显示函数
  16. unsigned char wei=0x01,j=0;
  17. void timer_0 ()interrupt 1         
  18.         {
  19.            TH0=(65536-1000)/256;
  20.            TL0=(65536-1000)%256;
  21.            P1=0XFF;
  22.            if(buffer[j]==0xBF)P1=0XBF;         // 若显示"-",则直接输出不查表
  23.             else  if(buffer[j]==0xff)P1=0Xff;        // 此处为密码输入时设置的消隐信号
  24.                    else P1=led[buffer[j]];                 // 若显示数字,则根据号码查表
  25.                    P2=~(wei<<j);
  26.                    j++;
  27.                    if(j==8){j=0; wei=0x01;}
  28.         }


  29. //键盘扫描函数 具有返回值
  30. char key_scan()  
  31. {
  32.          unsigned char i,temp,m,n;
  33.           bit find=0;
  34.           P0=0x0f;         // 向所有列线输出高电平
  35.           i=P0;
  36.           i&=0x0f; // 屏蔽高四位,取行信号
  37.           if(i!=0x0f)          //判断是否有按键按下
  38.           {
  39.            delay(120);
  40.            i=P0;
  41.            i&=0x0f;
  42.            if(i!=0x0f)
  43.            {
  44.                 for(i=0;i<4;i++) //逐列判断
  45.                 {
  46.                  P0=~(0x10<<i);         // 列输出低电位,如果有按键按下则对应读入的数据为低电平
  47.                  temp=~P0;
  48.                  temp=temp&0x0f;  // 屏蔽高四位读行值,若有按键按下,则取反后出现高电平
  49.                  if(temp!=0)
  50.                  {
  51.                    m=i;
  52.                   find=1;
  53.                   switch(temp)
  54.                   {
  55.                    case 0x01:n=0;break;
  56.                    case 0x02:n=1;break;
  57.                    case 0x04:n=2;break;
  58.                    case 0x08:n=3;break;
  59.                    default:break;
  60.                   }
  61.                   break;
  62.                  }
  63.                 }
  64.            }
  65.           }
  66.           if(find==0)return -1;
  67.           else return(n*4+m);
  68.   }
  69. // 8位密码输入函数
  70. void  key_num()        
  71.    {
  72.          unsigned char key,i,m,n=0;
  73.           while(1)         // 此方法可以检测排除非0-9号按键
  74.           {
  75.            key=key_scan();
  76.            if(key==-1)continue;
  77.           else if(key>=0&&key<=9)
  78.                  {
  79.                         for(m=8;m>0;m--)
  80.                         buffer[m]=buffer[m-1];  // 为了达到号码移位输入的效果,采用后一个写入前一个地址的方法
  81.                         buffer[0]=key;        // 新输入的号码永远放在第0个位置
  82.                         P0=0X0F;
  83.                         while(P0!=0X0F);   // 按键弹起检测
  84.                          n++;
  85.                  }
  86.                
  87.            if(n==8){n=0;break;}
  88.           }
  89.         
  90.                 for(i=0;i<8;i++)                 // 8位密码与原始密码进行比对,完全一致的时候标志位置1
  91.                 {
  92.                  if(buffer[i]!=keycode[7-i])  // 此处由于输入密码移位,所以逆取
  93.                  {
  94.                   flag=0;           // 一旦出现密码比对不正确,立刻终止比对,并标志位置0
  95.                   break;
  96.                  }
  97.                          else flag=1;
  98.                 }
  99.   }

  100. // 重设密码函数
  101. void key_reset()               
  102. {
  103.                    unsigned char key,i,n=0;
  104.                         LED_GREEN=0;   // 红绿均点亮,表示重设密码
  105.                 LED_RED=0;
  106.                         while(1)
  107.                          {
  108.                           key=key_scan();
  109.                           if(key==-1)continue;
  110.                           else if(key!=-1)
  111.                           {
  112.                                  if(key>=0&&key<=9)
  113.                                   {
  114.                                   keycode[n]=key;
  115.                                   buffer[n]=0xff;          // 密码输入的时候,显示器消隐
  116.                                    P0=0X0F;         // 键盘重新读入行数据
  117.                                   while(P0!=0x0f);  // 如果行数据未出现低电平,表明按键全部弹起,此处一定要做按键弹起检测,否则多次加载数据
  118.                                   n++;
  119.                           }
  120.                          }
  121.                          if(n==8){n=0;break;}
  122.                     }
  123.                   while(1)
  124.                            {
  125.                               key=key_scan();
  126.                                 P0=0X0F;         // 键盘重新读入行数据
  127.                             while(P0!=0x0f);
  128.                                 if(key==11)break;           // 11按键按下退出
  129.                            }      

  130.                    LED_GREEN=1;   // 红绿均灭,表示重设密码结束,可以输入密码打开密码锁
  131.                        LED_RED=1;
  132.                             for(i=0;i<8;i++)                // 缓存区域数据全部清除,用"-"替代
  133.                                   {
  134.                                    buffer[i]=0xBF;
  135.                                   }
  136.    }


  137. // 输入密码结果函数
  138. unsigned char k=0;
  139. void key_result()          // 密码输入结果显示,正确时蜂鸣器响绿色LED点亮,密码错误,红色LED点亮
  140.         {
  141.           unsigned char key,i;
  142.           if(flag==0)
  143.          {
  144.                            k++;
  145.                    if(k!=3)                         //密码输入未达到三次,可继续输入
  146.                          { LED_RED=0;
  147.                           LED_GREEN=1;
  148.                           delay(50000);
  149.                            for(i=0;i<8;i++)                // 缓存区域数据全部清除,用"-"替代
  150.                           {
  151.                            buffer[i]=0xBF;
  152.                           }
  153.                         }
  154.                                 else                            // 密码错误为三次,锁定,11号按键解锁
  155.                                     {         
  156.                                          k=0;
  157.                                           while(1)
  158.                                            {
  159.                                               key=key_scan();
  160.                                                 P0=0X0F;         // 键盘重新读入行数据
  161.                                             while(P0!=0x0f);
  162.                                                 LED_RED=~LED_RED;                //红绿LED闪烁蜂鸣器鸣响报警
  163.                                                 LED_GREEN=~LED_GREEN;
  164.                                                  SPEAK=~SPEAK;
  165.                                                 delay(1000);
  166.                                                 if(key==11)
  167.                                                  {
  168.                                                  LED_GREEN=1;
  169.                                                  LED_RED=1;
  170.                                                  SPEAK=1;
  171.                                                  break;           // 11按键按下退出
  172.                                              }
  173.                                            }
  174.                             for(i=0;i<8;i++)                // 缓存区域数据全部清除,用"-"替代
  175.                                   {
  176.                                    buffer[i]=0xBF;
  177.                                   }
  178.                      }
  179.            }

  180.          
  181.         else    // 密码输入正确可重置密码或直接退出
  182.          {

  183.            LED_GREEN=0;
  184.            LED_RED=1;
  185.            SPEAK=0;
  186.            delay(50000);
  187.            SPEAK=1;
  188.            k=0;          // 密码错误次数也要清零,否则会出现密码正确但不重设退出后两次密码错误就报警
  189.            flag=0;// 标志位清零
  190.                    for(i=0;i<8;i++)                // 缓存区域数据全部清除,用"-"替代
  191.                   {
  192.                    buffer[i]=0xBF;
  193.                   }
  194.                   
  195.                          while(1)
  196.                          {
  197.                                   key=key_scan();
  198.                                 P0=0X0F;         // 键盘重新读入行数据
  199.                             while(P0!=0x0f); // 等待按键弹起
  200.                                           if(key==10) {key_reset();break;}         // 按下10号键,重设密码
  201.                                              else  if(key==11){LED_RED=1;LED_GREEN=1;break;}         // 11号按键按下退出,其他按键无效
  202.                                                     continue;  //此处为了防止其他按键的按下而设置            
  203.                   }
  204.                 }                        
  205.   }

  206. void main()
  207. {
  208.                   TMOD=0X01;// 初始化,开启1毫秒定时器中断
  209.                   ET0=1;
  210.                   EA=1;
  211.                   TH0=(65536-1000)/256;
  212.                   TL0=(65536-1000)%256;
  213.                   TR0=1;
  214.                   LED_RED=1;
  215.                   LED_GREEN=1;
  216.                   SPEAK=1;
  217.         
  218.         while(1)
  219.         {
  220.                  key_num();
  221.                  key_result();
  222.         }         
  223. }
复制代码

下载: 八位数码管密码锁.zip (83.68 KB, 下载次数: 90)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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