找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机做的密码锁程序及proteus仿真

[复制链接]
跳转到指定楼层
楼主

简单的51单片机做的密码锁,带矩阵键盘,用数码管来显示,初始密码111111,

所有资料下载:
51密码锁改.zip (147.63 KB, 下载次数: 58)


下面是源程序:
  1. #include <reg51.h>
  2. typedef unsigned char uchar;
  3. typedef unsigned int uint;

  4. //键盘子程序相关说明
  5. #define BLANKCHAR 10          //定义空白常量
  6. #define PCHAR 11                  //定义字符 P 常量(等待用户输入密码)
  7. #define OPENCHAR 12                  //定义开锁字符 |— 常量
  8. #define ALARMCHAR 13          //定义字符 A 常量(密码多次错误警告)
  9. #define LINECHAR 14                  //定义字符 - 常量
  10. #define BACKKEY 0X0D          //定义退格按键常量
  11. #define ENTERKEY 0X0F          //定义确认键常量
  12. #define LOCKKEY 0X0E          //定义闭锁键常量
  13. #define NO_KEY 20                   //定义无按键返回值


  14. //定义按键扫描码表,按键扫描时,4位列线和4位行线组成字节数据表
  15. uchar code KEYCODE[] = {0XEE,0XDE,0XBE,0X7E, //        0 1 2 3
  16.                                             0XED,0XDD,0XBD,0X7D, //        4 5 6 7
  17.                                             0XEB,0XDB,0XBB,0X7B, // 8 9
  18.                                             0XE7,0XD7,0XB7,0X77};//          back lockkey enter

  19. uchar KeyPre;                          //保存上次扫描按键的键值
  20. uchar KeyUp;//用于控制按键去抖动操作。1:扫描时消抖 2:等待释放 3:释放时消抖       

  21. #define LEDPORT P0                  //定义显示器段码输出端口
  22. #define LEDCON P1                  //定义显示器位控制端口
  23. #define KEYPORT P2                  //定义键盘端口

  24. sbit ALARMCON = P3^3;     //定义报警控制引脚
  25. sbit LOCKCON = P3^5;      //定义电子锁控制引脚

  26. uchar code SEGCODE[] =
  27. {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,//0...9的共阳极段码
  28.                                      0XFF,//不显示
  29.                                          0X8C,//显示字符P(等待用户输入密码)
  30.                                          0X8F,//|-的共阳极段码(开锁)
  31.                                          0X88,//字符A
  32.                                          0XBF,//字符-
  33.                                          0X9f,//返回字符
  34. };

  35. //定义LED位码控制码
  36. uchar code BITCODE[6] = {0XC1,0XC2,0XC4,0XC8,0XD0,0XE0};
  37. uchar DispBuf[6];                  //保存显示的字符
  38. bit DispNormal;                          //控制显示时,是正常显示还是闪烁显示
  39. uchar DispCnt;                          //控制闪烁显示时的频率
  40. #define SHORT_TIME 10          //蜂鸣器响200ms
  41. #define LONG_TIME 100          //蜂鸣器响2s
  42. #define LONGER_TIME 9000  //蜂鸣器响3min

  43. bit AlarmEnable;          //是否报警或声音提示
  44. uint AlarmTime;           //控制报警时间长度

  45. uchar code PassWord[] = {1,1,1,1,1,1};//定义初始密码表
  46. uchar PassInBuf[5];       //保存输入的密码字符
  47. uchar PassPosi;         //用户输入密码字符存放在PassInBuf[]的位置
  48. bit TimerBit;             //20ms定时时间到
  49. uchar SysMode;            //系统所处模式 0:输入密码模式 1:报警模式 2:开锁模式
  50. uchar ErrorCnt;           //用户连续输入密码出错次数

  51. void Delay(int z)
  52. {
  53.         uchar y;
  54.         int x;
  55.         for(x=z; x>0; x--)
  56.                 for(y=255; y>0; y--);
  57. }

  58. /*********************************************************
  59. *1、填充子程序负责将显示内容写入DisBuf和PassInBuf缓冲区,*
  60. *    分为以下几个子程序。                                *
  61. *   函数Fill_Buf;使用特定字符填充DisBuf和PassInBuf。         *
  62. *        函数Fill_Buf_P;将系统闭锁时的显示信息写入缓冲区。    *
  63. *   函数Fill_Buf_O;将系统开锁时的显示信息写入缓冲区。    *
  64. *   函数Fill_Buf_A;将系统报警时的显示信息写入缓冲区。         *
  65. *********************************************************/

  66. /**********函数Fill_Buf**************/
  67. void Fill_Buf(uchar FillChar)
  68. {
  69.         uchar i;
  70.         for (i=0; i<6; i++)
  71.         {
  72.                 DispBuf[i] = FillChar;//用字符FillChar填充DispBuf[i]
  73.                 PassInBuf[i] = FillChar;//用字符FillChar填充PassInBuf[i]
  74.         }
  75. }

  76. void  Fill_Buf_P()
  77. {
  78.         Fill_Buf(BLANKCHAR);//DispBuf[1..5] = ' '
  79.         DispBuf[0] = PCHAR;//DispBuf[0] = 'p'
  80.         LEDPORT = SEGCODE[PCHAR]; //显示P
  81.         LEDCON = BITCODE[5];//在最后一个数码管显示

  82. }

  83. void  Fill_Buf_O()
  84. {
  85.         Fill_Buf(BLANKCHAR);
  86.         DispBuf[0] = OPENCHAR;// DispBuf[0] = '|-'
  87.         LEDPORT = SEGCODE[OPENCHAR]; //显示'|-'
  88.         LEDCON = BITCODE[5];//在最后一个数码管显示
  89. }

  90. void  Fill_Buf_A()
  91. {
  92.         Fill_Buf(BLANKCHAR);
  93.         DispBuf[0] = ALARMCHAR;// DispBuf[0] = 'A'
  94.         LEDPORT = SEGCODE[ALARMCHAR]; //显示'A'
  95.         LEDCON = BITCODE[5];//在最后一个数码管显示

  96. }

  97. /*********************************************************
  98. *2、缓冲区显示子程序负责将显示内容写入DisBuf和PassInBuf         *
  99. *   缓冲区,分为以下几个子程序。                         *
  100. *   函数Disp_Led_Sin;在某个LED数码管上显示一个字符。         *
  101. *        函数Disp_Led_OFF;关闭数码管显示。                    *
  102. *   函数Disp_Led_All;将DispBuf缓冲区的内容显示。         *
  103. *   函数Disp_Led;当系统处于不同模式时,刷新显示器。             *
  104. *********************************************************/

  105. void  Disp_Led_Sin(uchar DispChar, uchar DispPosi)
  106. {
  107.         LEDPORT = SEGCODE[DispChar];//输出显示段码
  108.         LEDCON = BITCODE[DispPosi];//输出显示位码
  109.         Delay(500);
  110.         LEDCON = 0X00;//关闭显示器
  111. }

  112. /*********启动报警函数***********/
  113. void Sys_Speaker(uint stime)
  114. {
  115.         AlarmEnable = 1;//允许报警
  116.         AlarmTime = stime;//报警时间长短
  117. }

  118. /*********系统报警函数**********/
  119. void Sys_Alarm()
  120. {
  121.         if (AlarmEnable == 1)  //允许报警
  122.         {
  123.                 ALARMCON = 0;//报警
  124.                 AlarmTime--;
  125.                 if (AlarmTime == 0)        //停止报警时间到
  126.                 {
  127.                         AlarmEnable = 0;
  128.                         ALARMCON = 1;
  129.                         if (SysMode == 1) //报警发生在模式1.要返回模式0
  130.                         {
  131.                                 SysMode = 0;
  132.                                 Fill_Buf_P();//显示P
  133.                         }               
  134.                 }
  135.                        
  136.         }
  137. }

  138. /*********按键检测子程序**************/
  139. uchar Find_Key()
  140. {
  141.         uchar KeyTOP, i;
  142.         KEYPORT = 0XF0;//行线输出全0,列线输出全1
  143.         KeyTOP = KEYPORT;//读按键端口值
  144.         if(KeyTOP == 0XF0)
  145.                 return NO_KEY;
  146.         KEYPORT = KeyTOP | 0X0F;//列线输出,行线输入
  147.         KeyTOP = KEYPORT;
  148.         for (i=0; i<16; i++)
  149.         {
  150.                 if(KeyTOP == KEYCODE[i])//根据按键端口扫描值,查找按键值
  151.                         return i;//返回按键值
  152.                 else if(i >= 15)
  153.                         {       
  154.                                 i = NO_KEY;
  155.                                 return i;
  156.                         }       
  157.         }
  158. }

  159. /****************按键扫描函数**************/
  160. uchar Scan_Key()
  161. {
  162.         uchar KeyTOP;
  163.         KeyTOP = Find_Key();//接收按键检测的返回值
  164.         if (KeyTOP != NO_KEY)
  165.         {
  166.                 Delay(100);
  167.                 if (KeyTOP != NO_KEY)
  168.                         KeyPre = KeyTOP;
  169.                 while(KeyTOP == Find_Key());
  170.                 return KeyPre;
  171.         }
  172.         else
  173.                 return NO_KEY;
  174. }

  175. /***************按键处理子程序**************/
  176. void Key_Process(uchar Key)
  177. {
  178.         uchar i;
  179.         if (Key == NO_KEY)
  180.                 return;//无按键,不处理
  181.         switch(SysMode)
  182.         {
  183.                 case 0://输入密码
  184.                         switch(Key)
  185.                         {
  186.                                 case 0:
  187.                                 case 1:
  188.                                 case 2:
  189.                                 case 3:
  190.                                 case 4:
  191.                                 case 5:
  192.                                 case 6:
  193.                                 case 7:
  194.                                 case 8:
  195.                                 case 9:
  196.                                         Disp_Led_Sin(Key,PassPosi);
  197.                                         PassInBuf[PassPosi] = Key;//保存用户输入的密码
  198.                                         if (PassPosi<5)
  199.                                                 PassPosi++;//调整密码输入位置
  200.                                         Sys_Speaker(SHORT_TIME);//发按键提示音
  201.                                         break;
  202.                                 case 20:break;
  203.                                 case BACKKEY:
  204.                                         DispBuf[PassPosi] =  BLANKCHAR;//显示空键
  205.                                         PassInBuf[PassPosi] = BLANKCHAR;//清除当前位置的密码
  206.                                         if (PassPosi>0)
  207.                                         {
  208.                                                 PassPosi--;//调整显示位置
  209.                                                 Disp_Led_Sin(15,5);
  210.                                         }
  211.                                         Sys_Speaker(SHORT_TIME);//发按键提示音
  212.                                         break;
  213.                                 case ENTERKEY:
  214.                                         for (i=0; i<5; i++)//比较用户密码是否与预设密码一致
  215.                                         {
  216.                                                 if (PassInBuf[i] != PassWord[i])
  217.                                                         break;
  218.                                         }
  219.                                         if (i>=5)//输入密码正确
  220.                                         {
  221.                                                  Fill_Buf_O();//显示开锁状态
  222.                                                  PassPosi = 0;
  223.                                                  LOCKCON = 1;//开锁
  224.                                                  ErrorCnt = 0;
  225.                                                  Sys_Speaker(LONG_TIME);//发长提示音
  226.                                                  SysMode = 2;//转模式2
  227.                                         }
  228.                                         else
  229.                                         {
  230.                                                  ErrorCnt++;
  231.                                                  if(ErrorCnt>2)//超过3次
  232.                                                  {
  233.                                                          ErrorCnt = 0;
  234.                                                         Fill_Buf_A();//显示报警状态
  235.                                                         PassPosi = 0;
  236.                                                         Sys_Speaker(LONGER_TIME);//发报警音
  237.                                                         SysMode = 1;       
  238.                                                  }
  239.                                                  else //少于3次,重新输入
  240.                                                  {
  241.                                                           Fill_Buf_P();
  242.                                                          PassPosi = 0;
  243.                                                          Sys_Speaker(LONG_TIME);//发长提示音
  244.                                                  }
  245.                                         }
  246.                                         break;
  247.                                         case LOCKKEY://闭锁键
  248.                                                 Fill_Buf_P();
  249.                                                 PassPosi = 0;
  250.                                                  Sys_Speaker(SHORT_TIME);//发短提示音
  251.                                                 break;
  252.                         }
  253.                         break;
  254.                         case 2://开锁状态
  255.                                 if (Key == LOCKKEY)//用户按动闭锁按键
  256.                                 {
  257.                                         Fill_Buf_P();
  258.                                         SysMode = 0;
  259.                                         LOCKCON = 0;//闭锁
  260.                                         Sys_Speaker(SHORT_TIME);
  261.                                 }
  262.                                 break;
  263.         }
  264. }

  265. void Init_Timer()
  266. {
  267.         TMOD &= 0XF0;
  268.         TMOD |= 0X01;
  269.         TR0 = 0;
  270.         TH0 = (65536-20000) / 256;
  271.         TL0 = (65536-20000) % 256;
  272.         TR0 = 1;
  273.         ET0 = 1;
  274. }

  275. void Timer0() interrupt 1
  276. {       
  277.         TR0 = 0;
  278.         TH0 = (65536-20000) / 256;
  279.         TL0 = (65536-20000) % 256;
  280.         TR0 = 1;
  281.         TimerBit = 1;//20ms定时时间到
  282. }

  283. void Init_System()
  284. {
  285.         PassPosi = 1;
  286.         LOCKCON = 0; //闭锁
  287.         Init_Timer();
  288.         Fill_Buf_P();
  289.         EA = 1;
  290. }
  291. void main()
  292. {               
  293.         uchar KeyTemp;
  294.         Init_System();
  295.         PassPosi = 0;
  296.         while(1)
  297.         {
  298.                 if(TimerBit == 1)
  299.                 {
  300.                         Sys_Alarm();//报警函数
  301.                         KeyTemp = Scan_Key();//按键扫描
  302.                         Key_Process(KeyTemp);//按键处理
  303.                         TimerBit = 0;
  304.                 }
  305.         }
  306. }
复制代码



评分

参与人数 1黑币 +5 收起 理由
123woscc + 5

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:212451 发表于 2017-6-19 09:21 | 只看该作者
谢谢楼主
回复

使用道具 举报

板凳
ID:212587 发表于 2017-6-19 14:40 | 只看该作者
谢谢楼主?
回复

使用道具 举报

地板
ID:212587 发表于 2017-6-19 14:40 | 只看该作者
楼主万岁。。感谢感谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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