找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4269|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)做的密碼鎖程序及proteus仿真

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主

簡(jiǎn)單的51單片機(jī)做的密碼鎖,帶矩陣鍵盤(pán),用數(shù)碼管來(lái)顯示,初始密碼111111,

所有資料下載:
51密碼鎖改.zip (147.63 KB, 下載次數(shù): 58)


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

  4. //鍵盤(pán)子程序相關(guān)說(shuō)明
  5. #define BLANKCHAR 10          //定義空白常量
  6. #define PCHAR 11                  //定義字符 P 常量(等待用戶輸入密碼)
  7. #define OPENCHAR 12                  //定義開(kāi)鎖字符 |— 常量
  8. #define ALARMCHAR 13          //定義字符 A 常量(密碼多次錯(cuò)誤警告)
  9. #define LINECHAR 14                  //定義字符 - 常量
  10. #define BACKKEY 0X0D          //定義退格按鍵常量
  11. #define ENTERKEY 0X0F          //定義確認(rèn)鍵常量
  12. #define LOCKKEY 0X0E          //定義閉鎖鍵常量
  13. #define NO_KEY 20                   //定義無(wú)按鍵返回值


  14. //定義按鍵掃描碼表,按鍵掃描時(shí),4位列線和4位行線組成字節(jié)數(shù)據(jù)表
  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;//用于控制按鍵去抖動(dòng)操作。1:掃描時(shí)消抖 2:等待釋放 3:釋放時(shí)消抖       

  21. #define LEDPORT P0                  //定義顯示器段碼輸出端口
  22. #define LEDCON P1                  //定義顯示器位控制端口
  23. #define KEYPORT P2                  //定義鍵盤(pán)端口

  24. sbit ALARMCON = P3^3;     //定義報(bào)警控制引腳
  25. sbit LOCKCON = P3^5;      //定義電子鎖控制引腳

  26. uchar code SEGCODE[] =
  27. {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,//0...9的共陽(yáng)極段碼
  28.                                      0XFF,//不顯示
  29.                                          0X8C,//顯示字符P(等待用戶輸入密碼)
  30.                                          0X8F,//|-的共陽(yáng)極段碼(開(kāi)鎖)
  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;                          //控制顯示時(shí),是正常顯示還是閃爍顯示
  39. uchar DispCnt;                          //控制閃爍顯示時(shí)的頻率
  40. #define SHORT_TIME 10          //蜂鳴器響200ms
  41. #define LONG_TIME 100          //蜂鳴器響2s
  42. #define LONGER_TIME 9000  //蜂鳴器響3min

  43. bit AlarmEnable;          //是否報(bào)警或聲音提示
  44. uint AlarmTime;           //控制報(bào)警時(shí)間長(zhǎng)度

  45. uchar code PassWord[] = {1,1,1,1,1,1};//定義初始密碼表
  46. uchar PassInBuf[5];       //保存輸入的密碼字符
  47. uchar PassPosi;         //用戶輸入密碼字符存放在PassInBuf[]的位置
  48. bit TimerBit;             //20ms定時(shí)時(shí)間到
  49. uchar SysMode;            //系統(tǒng)所處模式 0:輸入密碼模式 1:報(bào)警模式 2:開(kāi)鎖模式
  50. uchar ErrorCnt;           //用戶連續(xù)輸入密碼出錯(cuò)次數(shù)

  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、填充子程序負(fù)責(zé)將顯示內(nèi)容寫(xiě)入DisBuf和PassInBuf緩沖區(qū),*
  60. *    分為以下幾個(gè)子程序。                                *
  61. *   函數(shù)Fill_Buf;使用特定字符填充DisBuf和PassInBuf。         *
  62. *        函數(shù)Fill_Buf_P;將系統(tǒng)閉鎖時(shí)的顯示信息寫(xiě)入緩沖區(qū)。    *
  63. *   函數(shù)Fill_Buf_O;將系統(tǒng)開(kāi)鎖時(shí)的顯示信息寫(xiě)入緩沖區(qū)。    *
  64. *   函數(shù)Fill_Buf_A;將系統(tǒng)報(bào)警時(shí)的顯示信息寫(xiě)入緩沖區(qū)。         *
  65. *********************************************************/

  66. /**********函數(shù)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];//在最后一個(gè)數(shù)碼管顯示

  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];//在最后一個(gè)數(shù)碼管顯示
  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];//在最后一個(gè)數(shù)碼管顯示

  96. }

  97. /*********************************************************
  98. *2、緩沖區(qū)顯示子程序負(fù)責(zé)將顯示內(nèi)容寫(xiě)入DisBuf和PassInBuf         *
  99. *   緩沖區(qū),分為以下幾個(gè)子程序。                         *
  100. *   函數(shù)Disp_Led_Sin;在某個(gè)LED數(shù)碼管上顯示一個(gè)字符。         *
  101. *        函數(shù)Disp_Led_OFF;關(guān)閉數(shù)碼管顯示。                    *
  102. *   函數(shù)Disp_Led_All;將DispBuf緩沖區(qū)的內(nèi)容顯示。         *
  103. *   函數(shù)Disp_Led;當(dāng)系統(tǒng)處于不同模式時(shí),刷新顯示器。             *
  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;//關(guān)閉顯示器
  111. }

  112. /*********啟動(dòng)報(bào)警函數(shù)***********/
  113. void Sys_Speaker(uint stime)
  114. {
  115.         AlarmEnable = 1;//允許報(bào)警
  116.         AlarmTime = stime;//報(bào)警時(shí)間長(zhǎng)短
  117. }

  118. /*********系統(tǒng)報(bào)警函數(shù)**********/
  119. void Sys_Alarm()
  120. {
  121.         if (AlarmEnable == 1)  //允許報(bào)警
  122.         {
  123.                 ALARMCON = 0;//報(bào)警
  124.                 AlarmTime--;
  125.                 if (AlarmTime == 0)        //停止報(bào)警時(shí)間到
  126.                 {
  127.                         AlarmEnable = 0;
  128.                         ALARMCON = 1;
  129.                         if (SysMode == 1) //報(bào)警發(fā)生在模式1.要返回模式0
  130.                         {
  131.                                 SysMode = 0;
  132.                                 Fill_Buf_P();//顯示P
  133.                         }               
  134.                 }
  135.                        
  136.         }
  137. }

  138. /*********按鍵檢測(cè)子程序**************/
  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])//根據(jù)按鍵端口掃描值,查找按鍵值
  151.                         return i;//返回按鍵值
  152.                 else if(i >= 15)
  153.                         {       
  154.                                 i = NO_KEY;
  155.                                 return i;
  156.                         }       
  157.         }
  158. }

  159. /****************按鍵掃描函數(shù)**************/
  160. uchar Scan_Key()
  161. {
  162.         uchar KeyTOP;
  163.         KeyTOP = Find_Key();//接收按鍵檢測(cè)的返回值
  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;//無(wú)按鍵,不處理
  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++;//調(diào)整密碼輸入位置
  200.                                         Sys_Speaker(SHORT_TIME);//發(fā)按鍵提示音
  201.                                         break;
  202.                                 case 20:break;
  203.                                 case BACKKEY:
  204.                                         DispBuf[PassPosi] =  BLANKCHAR;//顯示空鍵
  205.                                         PassInBuf[PassPosi] = BLANKCHAR;//清除當(dāng)前位置的密碼
  206.                                         if (PassPosi>0)
  207.                                         {
  208.                                                 PassPosi--;//調(diào)整顯示位置
  209.                                                 Disp_Led_Sin(15,5);
  210.                                         }
  211.                                         Sys_Speaker(SHORT_TIME);//發(fā)按鍵提示音
  212.                                         break;
  213.                                 case ENTERKEY:
  214.                                         for (i=0; i<5; i++)//比較用戶密碼是否與預(yù)設(shè)密碼一致
  215.                                         {
  216.                                                 if (PassInBuf[i] != PassWord[i])
  217.                                                         break;
  218.                                         }
  219.                                         if (i>=5)//輸入密碼正確
  220.                                         {
  221.                                                  Fill_Buf_O();//顯示開(kāi)鎖狀態(tài)
  222.                                                  PassPosi = 0;
  223.                                                  LOCKCON = 1;//開(kāi)鎖
  224.                                                  ErrorCnt = 0;
  225.                                                  Sys_Speaker(LONG_TIME);//發(fā)長(zhǎng)提示音
  226.                                                  SysMode = 2;//轉(zhuǎn)模式2
  227.                                         }
  228.                                         else
  229.                                         {
  230.                                                  ErrorCnt++;
  231.                                                  if(ErrorCnt>2)//超過(guò)3次
  232.                                                  {
  233.                                                          ErrorCnt = 0;
  234.                                                         Fill_Buf_A();//顯示報(bào)警狀態(tài)
  235.                                                         PassPosi = 0;
  236.                                                         Sys_Speaker(LONGER_TIME);//發(fā)報(bào)警音
  237.                                                         SysMode = 1;       
  238.                                                  }
  239.                                                  else //少于3次,重新輸入
  240.                                                  {
  241.                                                           Fill_Buf_P();
  242.                                                          PassPosi = 0;
  243.                                                          Sys_Speaker(LONG_TIME);//發(fā)長(zhǎng)提示音
  244.                                                  }
  245.                                         }
  246.                                         break;
  247.                                         case LOCKKEY://閉鎖鍵
  248.                                                 Fill_Buf_P();
  249.                                                 PassPosi = 0;
  250.                                                  Sys_Speaker(SHORT_TIME);//發(fā)短提示音
  251.                                                 break;
  252.                         }
  253.                         break;
  254.                         case 2://開(kāi)鎖狀態(tài)
  255.                                 if (Key == LOCKKEY)//用戶按動(dòng)閉鎖按鍵
  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定時(shí)時(shí)間到
  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();//報(bào)警函數(shù)
  301.                         KeyTemp = Scan_Key();//按鍵掃描
  302.                         Key_Process(KeyTemp);//按鍵處理
  303.                         TimerBit = 0;
  304.                 }
  305.         }
  306. }
復(fù)制代碼



評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
123woscc + 5

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:212451 發(fā)表于 2017-6-19 09:21 | 只看該作者
謝謝樓主
回復(fù)

使用道具 舉報(bào)

板凳
ID:212587 發(fā)表于 2017-6-19 14:40 | 只看該作者
謝謝樓主?
回復(fù)

使用道具 舉報(bào)

地板
ID:212587 發(fā)表于 2017-6-19 14:40 | 只看該作者
樓主萬(wàn)歲。。感謝感謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表