久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7583|回復: 8
打印 上一主題 下一主題
收起左側

51單片機+LCD12864實現密碼鎖Proteus仿真和代碼

  [復制鏈接]
跳轉到指定樓層
樓主
51單片機-密碼鎖仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include <reg51.h>      //  包含51單片機寄存器定義的頭文件
  2. #include <intrins.h>    //包含_nop_()函數定義的頭文件
  3. #include<string.h>
  4. #include <12864.h>
  5. #include<KEYPAD4_3.h>
  6. #define N 8
  7. #define        NOP5() {_nop_();_nop_();_nop_();_nop_();_nop_();}        // 執行5個空操作,延時5微秒
  8. unsigned char readerror=0;  //讀取成功為0,否則為1
  9. unsigned char writeerror=0; //寫入成功為0,否則為1
  10. unsigned char Rbuff[10]={0};
  11. unsigned char Wbuff[10]="0000";
  12. sbit SDA=P2^7;          //將串行數據總線SDA位定義在為P3.4引腳
  13. sbit SCL=P2^6;          //將串行時鐘總線SDA位定義在為P3.3引腳
  14. sbit led = P2^0;
  15. u8 str[]="123456789*0#";
  16. u8 s[10]={0};
  17. /*****************************************************
  18. 函數功能:延時若干毫秒
  19. 入口參數:n
  20. *****************************************************/
  21. void delay_ms(unsigned int n)
  22. {
  23.    unsigned int i,j;       
  24.          for(i=0;i<n;i++)
  25.           for(j=0;j<110;j++);                 
  26. }
  27. /***************************************************
  28. 函數功能:開始數據傳送
  29. ***************************************************/
  30. void start()
  31. // 開始位
  32. {
  33.         SDA = 1;    //SDA初始化為高電平“1”
  34.     SCL = 1;    //開始數據傳送時,要求SCL為高電平“1”
  35.         NOP5();
  36.         SDA = 0;    //SDA的下降沿被認為是開始信號
  37.         NOP5();
  38.         SCL = 0;    //SCL為低電平時,SDA上數據才允許變化(即允許以后的數據傳遞)  
  39. }
  40. /***************************************************
  41. 函數功能:結束數據傳送
  42. ***************************************************/
  43. void stop()
  44. // 停止位
  45. {
  46.         SDA = 0;     //SDA初始化為低電平“0”        _n
  47.         SCL = 1;     //結束數據傳送時,要求SCL為高電平“1”
  48.         NOP5();
  49.         SDA = 1;    //SDA的上升沿被認為是結束信號
  50.         NOP5();       
  51. }
  52. /***************************************************
  53. 函數功能:發送應答/非應答信號
  54. ***************************************************/
  55. void Send_Ack(bit ack)
  56. //ack=0表示應答;ack=1表示非應答
  57. {
  58.         SCL = 0; //拉低SCL為輸出數據到SDA做準備
  59.         SDA = ack; //輸出ack到SDA,表示應答/不應答
  60.         SCL = 1;
  61.         NOP5();   //NOP5()>4us
  62.     SCL = 0;    //SCL從0-1-0為一個完整的時鐘周期
  63.     SDA=1;//釋放總線
  64. }
  65. /***************************************************
  66. 函數功能:查詢/接收應答信號
  67. ***************************************************/
  68. unsigned char Rec_Ack(void)   
  69. //返回值為0表示應答,為1表示非應答
  70. {unsigned char i,ack;
  71. SCL=0;  //拉低SCL為輸出數據到SDA做準備
  72. SDA = 1; //釋放總線,讓從設備能輸出數據到SDA
  73. SCL=1;
  74. while((SDA==1)&&(i<250)) i++;
  75. /*等待從設備發送應答信號,若為0,表示應答,循環結束;若為1,可能是從機還未將信號送上來,循環延時到i>250,若仍為1,此時才認為是未應答*/
  76. ack=SDA;
  77. SCL = 0;//SCL從0-1-0為一個完整的時鐘周期
  78. SDA=1; //釋放總線
  79. return(ack);
  80. }
  81. /***************************************************
  82. 函數功能:從AT24Cxx讀取數據
  83. 出口參數:recbyte
  84. ***************************************************/
  85. unsigned char ReadData()
  86. // 從AT24Cxx中讀取一個字節數據到MCU
  87. {
  88.         unsigned char i;
  89.         unsigned char recbyte;   //儲存從AT24Cxx中讀出的數據
  90.         SCL=0;         //拉低SCL為從設備輸出數據到SDA做準備
  91.     SDA=1; //釋放總線
  92.     for(i = 0; i < 8; i++)
  93.         {
  94.                 SCL = 1;                //SCL置為高電平
  95.                 NOP5();
  96.         recbyte=(recbyte<<1)|SDA;       //讀SDA
  97.         SCL=0;                       //SCL從0-1-0為一個完整的時鐘周期
  98.     }
  99.     SDA=1;
  100.         return(recbyte);         //返回所讀數據
  101. }
  102. /***************************************************
  103. 函數功能:向AT24Cxx的當前地址寫入數據
  104. 入口參數:sendbyte (儲存待寫入的數據)
  105. ***************************************************/
  106. //在調用此數據寫入函數前需首先調用開始函數start(),所以SCL=0
  107. void WriteData(unsigned char sendbyte)
  108. {
  109.         unsigned char i;
  110.         for(i = 0; i < 8; i++)                // 循環移入8個位
  111.         {
  112.             sendbyte<<=1; //左移時最低位補0,最高位移入PSW的CY位
  113.         SDA=CY;        //輸出數據到SDA
  114.         SCL = 1;            //在SCL的上升沿將數據寫入AT24Cxx      
  115.                NOP5();                 
  116.             SCL = 0;            //將SCL重新置為低電平,以在SCL線形成傳送數據所需的8個脈沖
  117.          }
  118.         SDA = 1;  // 發送設備(主機)應在時鐘脈沖的高電平期間(SCL=1)釋放SDA線,
  119. }
  120. /***************************************************
  121. 函數功能:向AT24Cxx中的指定地址寫入數據
  122. 入口參數:add (儲存指定的地址);dat(儲存待寫入的數據)
  123. ***************************************************/
  124. void WriteRom(unsigned char add, unsigned char dat[],unsigned char j)
  125. // 將數組里的j個字節的數據寫入到起始地址為addr處的連續區域中
  126. {  unsigned char flag=0,k=0,i=3;//i為允許最大重寫次數,若出現i次操作失效后,則函數中止操作,并返回
  127.    while(i--)
  128.    {start();             //開始數據傳遞
  129.         WriteData(0xa0);  //選擇要操作的AT24Cxx芯片,并告知要對其寫入數據,器件地址以及寫入操作為1010 0000B(0xa0)
  130.         if(Rec_Ack()) continue;
  131.     WriteData(add);   //寫入器件內部地址
  132.         if(Rec_Ack()) continue;
  133.     while(j--)
  134.         {WriteData(dat[k++]);   //向當前地址(上面指定的地址)寫入數據
  135.          if(!Rec_Ack()) continue;
  136.      flag=1;
  137.          break;
  138.         }
  139.         if(flag)  continue;/*能不能改成:if(j>=0)  continue? (j>=0意味著數據未寫完,即出現了未應答,要重寫)*/
  140.         break;
  141.    }
  142.    stop();                //停止數據傳遞         
  143.    if(i<0) writeerror=1;     
  144. }
  145. /***************************************************
  146. 函數功能:從AT24Cxx中的指定地址讀取數據
  147. 入口參數:set_addr
  148. 出口參數:x
  149. ***************************************************/
  150. void ReadRom(unsigned char set_addr,unsigned char dat[],unsigned char j)
  151. // 在指定地址開始連續讀取j個字節,并將數據存放到數組中
  152. { unsigned char i=3,k=0;//i為允許最大重讀次數,若出現i次操作失效后,則函數中止操作,并返回
  153.   while(i--)
  154.   {        start();             //開始數據傳遞
  155.         WriteData(0xa0);     //選擇要操作的AT24Cxx芯片,并告知要對其寫入數據,器件地址以及寫入操作為1010 0000B(0xa0)
  156.         if(Rec_Ack()) continue;
  157.     WriteData(set_addr);       //寫入指定地址
  158.         if(Rec_Ack()) continue;
  159.     start();//調啟動總線函數
  160.     WriteData(0xa1);    //選擇器件要操作的AT24Cxx芯片,并告知要對其讀取數據,器件地址以及讀取操作為1010 0001B(0xa1)
  161.     if(Rec_Ack()) continue;//如果操作失敗,就退出
  162.     while(--j)
  163.         { dat[k++]=ReadData();
  164.           Send_Ack(0);          
  165.         }//接收前j-1個字節,并應答
  166.         dat[k++]=ReadData();//接收最后一個字節
  167.         Send_Ack(1);//向從設備發出非應答信號,結束數據傳輸
  168.     break;
  169.   }
  170.   stop();
  171.   if(i<0) readerror=1;  
  172. }


  173. //密碼錯誤時
  174. void mimacuowu(){
  175.         lcd_wcmd(0x01);
  176.         lcd12864_pos(0,0);
  177.         LCD12864disp("密碼錯誤!");
  178.         lcd12864_pos(1,0);
  179.         LCD12864disp("請重新輸入!");
  180.         delay_ms(1000);
  181.         lcd_wcmd(0x01);
  182.         lcd12864_pos(0,0);
  183.         LCD12864disp("請輸入密碼:");
  184.         lcd12864_pos(1,0);
  185. }


  186. //密碼正確時
  187. u8 zhengque(){
  188.                   u8 key;
  189.                 lcd_wcmd(0x01);
  190.                 lcd12864_pos(0,0);
  191.                 LCD12864disp("開鎖成功!");
  192.                 lcd12864_pos(1,0);
  193.                 LCD12864disp("是否修改密碼?");
  194.                 lcd12864_pos(2,0);
  195.                 LCD12864disp("1:是,2:否");
  196.                 lcd12864_pos(3,0);
  197.                 while(1){
  198.                         key=keypad4_3();
  199.                         if(key==0 || key==1){
  200.                                 if(key==0)  LCD12864disp("1");
  201.                                 else        LCD12864disp("2");
  202.                                 delay_ms(1000);
  203.                                 return key;
  204.                                 }
  205.                 }
  206. }

  207. //改密碼
  208. void gai(){
  209.         u8 key,a=0;
  210.         u8 s1[10]={0};
  211.         u8 s2[10]={0};
  212.         lcd_wcmd(0x01);
  213.         lcd12864_pos(0,0);
  214.         LCD12864disp("請輸入密碼:");
  215.         lcd12864_pos(1,0);
  216.         while(1){
  217.                 key=keypad4_3();
  218.                 if(key<12)
  219.                 {
  220.                         if(key==9)         LCD12864_backspace();
  221.                         if(key==11)  break;
  222.                         if(key!=9 && key!=11){s1[a++]=str[key]; LCD12864disp("*");}
  223.                 }
  224.         }
  225.         lcd12864_pos(2,0);
  226.         LCD12864disp("再次輸入密碼:");
  227.         lcd12864_pos(3,0);
  228.         a=0;
  229.         while(1){
  230.         key=keypad4_3();       
  231.         if(key<12)
  232.         {
  233.                 if(key==9)         LCD12864_backspace();
  234.                 if(key==11)  break;
  235.                 if(key!=9 && key!=11){s2[a++]=str[key]; LCD12864disp("*");}
  236.                 }
  237.         }
  238.         if(strcmp(s1,s2)==0){
  239.                 SDA = 1;           //I2C初始化:SDA=1,SCL=1,使主從設備處于空閑狀態
  240.                    SCL = 1;
  241.                 memset(Rbuff,0,sizeof(s));   //再次初始化數組
  242.                 strcpy(Rbuff,s2);
  243.                 //WriteRom(0x32,s2,10);   //向起始地址為“0x32”的連續區域中寫入數組Wbuff中的5個數據
  244.                    //ReadRom(0x32,Rbuff,10);    //從起始地址為“0x32”的連續區域中讀取5個數據到數組Rbuff中
  245.                   
  246.                 lcd_wcmd(0x01);
  247.                 lcd12864_pos(0,0);
  248.                 LCD12864disp("密碼修改成功");
  249.                 delay_ms(2000);

  250.                    lcd_wcmd(0x01);
  251.                 lcd12864_pos(0,0);
  252.                 LCD12864disp("請輸入密碼:");
  253.                 lcd12864_pos(1,0);
  254.         }
  255.         else
  256.         {
  257.                 lcd_wcmd(0x01);
  258.                 lcd12864_pos(0,0);
  259.                 LCD12864disp("兩次輸入不一致");
  260.                 lcd12864_pos(1,0);
  261.                 LCD12864disp("密碼修改失敗");
  262.                 delay_ms(2000);

  263.                 lcd_wcmd(0x01);
  264.                 lcd12864_pos(0,0);
  265.                 LCD12864disp("請輸入密碼:");
  266.                 lcd12864_pos(1,0);       
  267.         }
  268. }

  269. /***************************************************
  270. 函數功能:主函數
  271. ***************************************************/
  272. void main()
  273. {  
  274.    int a=0,flage=1;
  275.    unsigned char i=0;
  276.    u8 key,f;
  277.    SDA = 1;           //I2C初始化:SDA=1,SCL=1,使主從設備處于空閑狀態
  278.    SCL = 1;  
  279.    //led = 1;               
  280.    WriteRom(0x32,Wbuff,10);   //向起始地址為“0x32”的連續區域中寫入數組Wbuff中的5個數據
  281.    ReadRom(0x32,Rbuff,10);    //從起始地址為“0x32”的連續區域中讀取5個數據到數組Rbuff中
  282.           
  283.     //初始化

  284.    /*while(i<N)
  285.      { P1=Rbuff[i];
  286.            delaynms(1000);
  287.            i++;        //將讀出的數據送P1口顯示
  288.          }*/
  289.        
  290.         lcd12864_init();
  291.           lcd12864_pos(0,0);
  292.         //lcd_wcmd(0x01);
  293.         LCD12864disp("請輸入密碼:");
  294.         lcd12864_pos(1,0);
  295.           while(1)
  296.           {

  297.           key=keypad4_3();

  298.         if(key<12){ if(key==9) {LCD12864_backspace();}  //刪除
  299.                            if(key==11) //密碼確認
  300.                            {
  301.                                   
  302.                                      if(strcmp(Rbuff,s)==0) flage=0;  //正確
  303.                                   else flage=1;                                           //錯誤
  304.                                   if(flage==0)
  305.                                   {
  306.                                              led=0;   //燈亮
  307.                                             f=zhengque();
  308.                                           if(f==0){
  309.                                              
  310.                                                     gai();
  311.                                           }
  312.                                           if(f==1){
  313.                                                           lcd_wcmd(0x01);
  314.                                                           lcd12864_pos(0,0);
  315.                                                         LCD12864disp("請輸入密碼:");
  316.                                                         lcd12864_pos(1,0);       
  317.                                           }
  318.                                           led = 1;   //燈滅
  319.                                           a=0;
  320.                                           memset(s,0,sizeof(s));   //再次初始化數組
  321.                                   }
  322.                                   else
  323.                                   {
  324.                                             mimacuowu();
  325.                                           a=0;
  326.                                           memset(s,0,sizeof(s));   //再次初始化數組
  327.                                   }
  328.                            }
  329.                           if(key!=9 && key!=11) {s[a++]=str[key]; LCD12864disp("*");}
  330.                           }          
  331.   }                 
  332. }
復制代碼

所有資料51hei提供下載:
密碼鎖.zip (295.89 KB, 下載次數: 233)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:393984 發表于 2019-1-15 15:54 | 只看該作者
這個可以成功的嗎?
回復

使用道具 舉報

板凳
ID:454000 發表于 2019-1-16 01:24 | 只看該作者
yangqun1998 發表于 2019-1-15 15:54
這個可以成功的嗎?

我空間有16位的,仿真絕對沒任何問題

評分

參與人數 2黑幣 +30 收起 理由
還有誰? + 15
鉆牛尖滴劉尖尖 + 15

查看全部評分

回復

使用道具 舉報

地板
ID:524025 發表于 2019-5-6 16:53 | 只看該作者
這個初始密碼是什么啊
回復

使用道具 舉報

5#
ID:473704 發表于 2019-6-21 17:35 | 只看該作者
帶中文字庫的12864怎么做出來的
回復

使用道具 舉報

6#
ID:432151 發表于 2019-9-8 15:07 | 只看該作者
非常感謝,很有用
回復

使用道具 舉報

7#
ID:247623 發表于 2021-4-10 23:16 | 只看該作者
shuisheng 發表于 2019-1-16 01:24
我空間有16位的,仿真絕對沒任何問題

你好,你空間我看了,沒有找到16按鍵的密碼鎖啊
回復

使用道具 舉報

8#
ID:895926 發表于 2021-4-12 23:09 | 只看該作者
你這個是做了一個中文字庫嗎?
回復

使用道具 舉報

9#
ID:895926 發表于 2021-4-13 13:35 | 只看該作者
1145483334 發表于 2019-6-21 17:35
帶中文字庫的12864怎么做出來的

你會做字庫了嗎
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品久久久久久亚洲国产800 | 久热久草| 国产精品精品视频 | 亚洲男人网 | 亚洲欧美综合精品久久成人 | 在线小视频 | 精品伦精品一区二区三区视频 | www国产成人免费观看视频,深夜成人网 | 青青青伊人 | 色999视频 | 亚洲一区免费视频 | 日韩www| 久久人爽 | a级网站 | 亚洲天堂中文字幕 | 国产精品1区2区 | 浮生影院免费观看中文版 | 久草.com | 成年人视频在线免费观看 | 日韩毛片在线观看 | 91成人在线视频 | 亚洲精品二区 | 日本在线看 | 羞羞的视频免费在线观看 | 国产精品一区二区日韩 | 国产精品久久久久久久午夜片 | 国产精品久久精品 | 国产精品人人做人人爽 | 男人天堂网av | 国产色网站| 成人羞羞国产免费视频 | www久| 亚洲精品字幕 | 国产毛片av| 色综合一区二区三区 | 一区二区av| 在线看91| 精品91久久 | 秋霞影院一区二区 | 久久精品99久久 | 国产精品一码二码三码在线 |