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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 16762|回復: 25
收起左側

DIY制作單片機斷電密碼保存電子鎖,含原理圖

  [復制鏈接]
ID:70481 發表于 2014-12-17 00:09 | 顯示全部樓層 |閱讀模式
DIY單片機斷電密碼保存電子鎖電子密碼鎖是集計算機技術、電子技術、數字密碼技術為一體的機電一體化高科技產品,具有安全性高,使用方便等優點。本論文從電子密碼鎖系統的功能,硬件電路設計,軟件設計分別論述這一系統。通過使用單片機AT89S52作為控制核心,連接外部存儲器AT24C02,實現密碼斷電保存,制作一種密碼鎖。
102217mi5q6io5i4jd6eho.jpg.thumb.jpg 102218zcm2wi520own7884.jpg.thumb.jpg
單片機斷電密碼保存電子鎖.rar (84.01 KB, 下載次數: 179)

評分

參與人數 2黑幣 +17 收起 理由
tianxiadiyi + 5 贊一個!
zhaok2013 + 12 很給力!

查看全部評分

回復

使用道具 舉報

ID:70481 發表于 2014-12-17 00:10 | 顯示全部樓層
下面是源碼預覽
  1. 數碼管的A--H 引腳 接到單片機的p0 口的 p0^0--P0^7 引腳  .

  2. 電路圖也有點問題,AT24C02 的引腳應該是 sbit Scl=P3^4; //串行時鐘信號
  3.                                            sbit Sda=P3^5; //串行數據信號




  4. #define uchar unsigned char //定義一下方便使用
  5. #include "reg52.h"
  6. #include "intrins.h"         //調用頭文件
  7. #define WriteDeviceAddress  0xa0   // AT24C02的識別碼是1010,硬件的三個地址引腳接地為000,最后一位為0時表示向存儲器寫入數據
  8. #define ReadDviceAddress  0xa1     //最后一位為1時表示從存儲器讀出數據。0xa0=1010 000 0 ,0xa1=1010 000 1 .
  9. sbit Scl=P3^4; //串行時鐘信號
  10. sbit Sda=P3^5; //串行數據信號
  11. sbit  xin=P2^0;   //在硬件電路上驅動青色發光二極管,用與顯示當前處于密碼輸入狀態
  12. sbit    xin_on=P3^6; //  在硬件電路上驅動繼電器,當8位密碼輸入正確時,繼電器工作
  13. sbit    ch_pass=P2^2;   //  在硬件電路上驅動紅色發光二極管,用于顯示當前處于修改密碼狀態
  14. sbit    on=P3^7;
  15. static  cound ;    //  用于計算密碼輸入的個數,每次輸入8位密碼后,清0

  16. uchar  code DB_dat[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};     // 存放數碼管顯示字符碼
  17. uchar  DB_password[8];    //    存放從存儲器中讀取的原始密碼
  18. uchar  DB_inword[8];   //    存放從鍵盤輸入的密碼
  19.                                           
  20. void DelayMs(unsigned int number)       //延時函數 延時1 MS
  21. {
  22. unsigned char temp;
  23. for(;number!=0;number--)
  24. {
  25.   for(temp=112;temp!=0;temp--) ;
  26. }
  27. }


  28. void Start(void)       /
  29. {
  30.         Sda=0;
  31.         Scl=1;
  32.         _nop_ ();      //根據時序圖盡心延時
  33.         _nop_ ();
  34.         _nop_ ();
  35.         _nop_ ();
  36.         Sda=1;
  37.         _nop_ ();
  38.         _nop_ ();
  39.         _nop_ ();
  40.         _nop_ ();
  41. }
  42. void Ack(void)
  43. {
  44.         Sda=0;
  45.          _nop_ ();
  46.         _nop_ ();    //延時 根據時序圖
  47.         _nop_ ();
  48.         _nop_ ();
  49.         Scl=1;
  50.         _nop_ ();
  51.         _nop_ ();
  52.         _nop_ ();
  53.         _nop_ ();
  54.         Scl=0;
  55. }
  56. void  NoAck(void)      
  57. {
  58.         Sda=1;
  59.         _nop_ ();    //根據時序圖進行延時
  60.         _nop_ ();
  61.         _nop_ ();
  62.         _nop_ ();
  63.         Scl=1;
  64.         _nop_ ();
  65.         _nop_ ();
  66.         _nop_ ();
  67.         _nop_ ();
  68.         Scl=0;
  69. }
  70. void Send(uchar Data)  
  71. {        
  72.         uchar BitCounter=8;      
  73.         uchar temp;   
  74.         do
  75.         {
  76.            temp=Data;
  77.            Scl=0;
  78.            _nop_ ();
  79.            _nop_ ();
  80.            _nop_ ();
  81.            _nop_ ();
  82.            if((temp&0x80)==0x80)
  83.                 Sda=1;
  84.            else
  85.                 Sda=0;        //如果最高位是0就發送0
  86.            Scl=1;
  87.            temp=Data<<1;      
  88.            Data=temp;      
  89.            BitCounter--;       //沒發完一位數據就減一
  90.          }while(BitCounter);    //如果發送完8位后跳出循環
  91.          Scl=0;               //釋放總線           
  92. }
  93. uchar Read(void)
  94. {
  95.         uchar temp=0;
  96.         uchar temp1=0;
  97.         uchar BitCounter=8;   //定義從存儲器讀出的數據位數
  98.         Sda=1;
  99.         do{
  100.           Scl=0;
  101.           _nop_ ();
  102.           _nop_ ();
  103.           _nop_ ();
  104.           _nop_ ();
  105.           Scl=1;
  106.           _nop_ ();
  107.           _nop_ ();
  108.           _nop_ ();
  109.           _nop_ ();
  110.           if(Sda)      
  111.                 temp=temp|0x01;
  112.           else
  113.                 temp=temp&0xfe;
  114.           if(BitCounter-1)
  115.           {   temp1=temp<<1;       //逐位的讀出
  116.               temp=temp1;
  117.           }
  118.           BitCounter--;
  119.         }while(BitCounter);   //讀出8位后跳出循環
  120.         return(temp);         //返回讀出的數據
  121. }
  122. void WrToROM(uchar Data,uchar Address)   //向存儲器寫一字節的數據 函數
  123. {
  124.      uchar i=0;
  125.    
  126.      Start();             //調用起始條件函數
  127.      Send(0xa0);       // 發送命令,準備寫入數據到存儲器,讓存儲器做好準備
  128.      Ack();            //  調用應答函數
  129.      Send(Address);    // 先發送要寫入數據的的存儲器內存地址
  130.      Ack();            // 調用應答函數
  131.    
  132.       Send(Data);      // 開始發送要寫入到存儲器中的數據
  133.         Ack();         // 調用應答函數
  134.   
  135.      Stop();           // 調用停止發送函數,表示發送完畢
  136. }
  137. uchar  RdFromROM(uchar Address)  //  從存儲器讀出一字節的數據
  138. {
  139.      uchar i;
  140.   
  141.         Start();                //調用起始條件函數
  142.         Send(0xa0);           //  讓存儲器準備接受命令
  143.         Ack();   
  144.         Send(Address);        //  發送要讀出來的數據地址
  145.         Ack();
  146.         Start();              //   重新調用起始函數
  147.         Send(0xa1);          //   發送讀出數據的命令
  148.         Ack();
  149.         i=Read ( );          // 開始讀出數據
  150.         Scl=0;
  151.         NoAck();             // 讀出數據成功。返回信號成功信號給存儲器
  152.         Stop();
  153.     return (i);             //  返回讀出的數據
  154. }


  155. uchar Key()                                    //鍵盤掃描子程序
  156. { uchar KValue;
  157. uchar tmp;
  158. P1|=0xff;   //將P1口的接鍵盤的位置1
  159. KValue=P1;
  160. KValue|=0x00;  //將未接鍵的位置1
  161. if(KValue==0xff) //
  162. return(0);  //返回
  163.   DelayMs(20);  //延時10ms,去鍵抖
  164. KValue=P1;
  165. KValue|=0x00;  //將未接鍵的位置1
  166. if(KValue==0xff) //位均為1,無鍵按下
  167. return(0);  //返回
  168.                         //如尚未返回,說明一定有1或更多位被按下
  169. for(;;)
  170. { tmp=P1;  
  171.   if((tmp|0x00)==0xff)
  172.    break;  //等待按鍵釋放,防止按一次鍵盤,產生多次輸入數據
  173. }
  174. return(KValue);          //返回按鍵值
  175. }

  176. Keyplay(uchar key)     // 按鍵值 處理函數
  177. { uchar password;        
  178.   
  179.    if (( key&0x80)==0)   //  按鍵值位7時的相應處理
  180.      { password=7;   
  181.       P0=DB_dat[7];      //  顯示按鍵值,通過數碼管顯示
  182.   }
  183.    if (( key&0x40)==0)   //     按鍵值位6時的相應處理
  184.      { password=6;      
  185.       P0=DB_dat[6];      //     顯示按鍵值,數碼管顯示
  186.   }
  187.    if (( key&0x20)==0)   //     按鍵值位5時的的相應處理
  188.       {password=5;
  189.       P0=DB_dat[5] ;     //     顯示按鍵值
  190.   }
  191.    if (( key&0x10)==0)    //     按鍵值位4時的相應處理
  192.       {password=4;
  193.       P0=DB_dat[4];
  194.    }
  195.    if (( key&0x08)==0)    //     按鍵值位3時的處理
  196.       {password=3;
  197.       P0=DB_dat[3];
  198.    }
  199.    if (( key&0x04)==0)    //     按鍵值位2時的處理
  200.       {password=2;
  201.       P0=DB_dat[2];
  202.    }
  203.    if (( key&0x02)==0)
  204.       {password=1;
  205.       P0=DB_dat[1];
  206.    }
  207.    if (( key&0x01)==0)    //     按鍵值位0時的處理
  208.       {password=0;
  209.       P0=DB_dat[0];
  210.    }
  211.   
  212.     return password;     //返回輸入的按鍵值
  213.      
  214.             
  215. }
  216. void Init()       //中斷初始化
  217. {                  //定時器0工作于模式2
  218.      IT0=1;                    //負變跳電平有效
  219.   EX0=1;                    //開外部中斷
  220.      EA=1;                      //開總中斷
  221.    
  222. }

  223. void Init0() interrupt 0    //中斷入口,中斷后的程序處理 函數
  224. {                    
  225.    uchar k,j,key;
  226.    EX0=0;              //關閉中斷,防止重復中斷  ((重要 不可以把EX0=0;放在char k,j,key; 之前  否則將出現編譯出錯))
  227.    ch_pass=0;                //點亮紅色發光二極管,顯示當前處于密碼修改狀態 ,當輸入8位密碼后,取消密碼修改狀態
  228.    P0=0xff;                  //清空-數碼管
  229.    cound=0;                  //清空密碼輸入個數標致,確保修改的密碼個數從開始,直到輸入8位密碼后,再一次清0
  230.   while (1)
  231.    {  key=Key();             //調用鍵盤掃描程序,獲取按鍵值
  232.       if (key)               //判斷按鍵值是否位非0,非0代表有按鍵輸入
  233.       { DB_inword[cound]=Keyplay(key);     //調用按鍵值處理程序,并且把按鍵輸入的數字存放到 數組中
  234.      cound++;                           //  每輸入一位的密碼,COUND 自加
  235.         
  236.       if(cound==8)                     //  判斷輸入的密碼個數是否到達8個
  237.     { cound=0;                       
  238.                                      //  密碼輸入個數已經到達8個
  239.            DelayMs(1000);
  240.    
  241.    
  242.                ch_pass=1;
  243.                DelayMs(700);
  244.                ch_pass=0;                  //  讓紅色發光二極管閃亮一次后,熄滅,表示密碼已經成功輸入8位
  245.                DelayMs(700);
  246.          ch_pass=1;

  247.       for(k=0;k<8;k++)               //   把輸入的8位密碼逐位的用數碼管顯示,并且寫入到存儲器中
  248.       { j=DB_inword[k];           //   斷電后密碼仍然保存起來,不會消失
  249.         P0=DB_dat[j];             //   獲取數碼管字符碼,并且顯示
  250.      DelayMs(1000);
  251.     WrToROM(j,k);                 //   寫入密碼到存儲器,寫入的內存地址為0~7
  252.         DelayMs(1000);
  253.           }
  254.              for(k=0;k<8;k++)
  255.                {   DB_password[k]=RdFromROM(k) ;}   
  256.          
  257.              P0=0xff;
  258.    break;                         //   密碼修改成功后,跳出中斷程序,返回主程序
  259.        }
  260.         }
  261.      
  262.   }
  263.    EX0=1;               //重新開啟中斷
  264. }

  265. void main ()                                //   主程序
  266. {
  267.    uchar i,j,key,pass=0;
  268.    Init();                                  //   中斷初始化

  269.   
  270.    cound=0;
  271.   
  272.    for (i=0;i<8;i++)                       //   逐為的顯示可以輸入的密碼值0~7,只能輸入這8為有效數字
  273.    { P0=DB_dat[ i];
  274.      DelayMs(1000);
  275.   P0=0xff;
  276.    }
  277.   
  278.     for (i=0;i<8;i++)
  279.           { DB_password[ i]=RdFromROM(i) ; }      //從存儲器讀出密碼值,并保存起來
  280.     while (1)                                 
  281. {    on=0;              
  282.          DelayMs(200);                           // 點亮右下腳的青色發光二極管,表明發光二極管在閃耀表明單片機在正常工作
  283.          on=1;
  284.          key=Key();                              // 獲取按鍵值
  285.      if (key)                                 //  判斷是否有按鍵按下
  286.       { DB_inword[cound]=Keyplay(key);           //  調用按鍵值處理函數,把輸入的按鍵值保存起來  
  287.      cound++;                                 //  每輸入一個值,自加1
  288.          xin=0;                                  //  顯示當前處于密碼輸入狀態,點亮左上腳的青色發光二極管
  289.       if(cound==8)
  290.     { cound=0;                             //   輸入的密碼個數到達8個后,進行密碼驗證
  291.                                             
  292.            DelayMs(1000);
  293.       
  294.      
  295.            xin=1;                           //   取消當前處于密碼輸入狀態
  296.    
  297.              for (i=0;i<8;i++)        
  298.                   {   DelayMs(1000);
  299.             j=DB_inword[ i];         
  300.          P0=DB_dat[j];          //   逐位的顯示輸入的密碼值,用送到P0口,數碼管顯示
  301.          DelayMs(1000);
  302.             if( DB_password[ i]==DB_inword[ i] )   //  逐位的驗證輸入的密碼值是否和原始密碼一致
  303.                                   { pass++;   }              //  輸入的密碼和原始密碼一致是 變量PASS自加1
  304.                         
  305.                         if ( pass==8)                       //   PASS為8時,表明輸入的密碼和原始密碼8位都一致
  306.                  {  xin_on=0;
  307.                                    DelayMs(10000);             //   密碼完全正確,驅動繼電器工作,將聽到“嗒”的一聲
  308.                                    xin_on=1;
  309.          
  310.                                 }
  311.                         }
  312.                   pass=0;                           //  清空驗證位
  313.       P0=0xff;                          //  清空數碼管
  314.                  for (i=0;i<8;i++)
  315.                     DB_inword[ i]=9;                 //  清空用于存放輸入密碼的數組,由于輸入的密碼限制在0~7之間                                    
  316.               }                                     //   9為無效的輸入密碼值。確保下次輸入密碼時,數組里邊為無效值
  317.         }
  318.      }  
  319. }
復制代碼
回復

使用道具 舉報

ID:69843 發表于 2014-12-22 15:49 | 顯示全部樓層
這不錯,頂一下
回復

使用道具 舉報

ID:72142 發表于 2015-1-13 14:29 | 顯示全部樓層
很好,樓主的創意很棒
回復

使用道具 舉報

ID:72778 發表于 2015-1-25 22:14 | 顯示全部樓層
謝謝LZ分享
回復

使用道具 舉報

ID:72570 發表于 2015-1-26 01:35 | 顯示全部樓層
不錯啊,我也想DIY一個試試
回復

使用道具 舉報

ID:79544 發表于 2015-10-25 19:49 | 顯示全部樓層
不錯學習,數碼管顯示適合初學者。頂!
回復

使用道具 舉報

ID:93926 發表于 2015-10-28 22:21 | 顯示全部樓層
很好,樓主的創意很棒
回復

使用道具 舉報

ID:148363 發表于 2016-11-16 22:26 | 顯示全部樓層
支持支持 很好
回復

使用道具 舉報

ID:148426 發表于 2016-11-17 11:19 | 顯示全部樓層
這可是好東西,果斷收藏了
回復

使用道具 舉報

ID:148440 發表于 2016-11-20 17:23 | 顯示全部樓層
頂一頂
回復

使用道具 舉報

ID:150019 發表于 2016-11-24 23:44 來自手機 | 顯示全部樓層
xiaoyao 發表于 2014-12-17 00:10
下面是源碼預覽

你好,我是個小白。沒有黑幣。如果你有這個壓縮包的話能發到我的郵箱嗎?846449482@qq.com 感激不盡
回復

使用道具 舉報

ID:150019 發表于 2016-11-24 23:45 來自手機 | 顯示全部樓層
Gameboy 發表于 2015-1-25 22:14
謝謝LZ分享

你好,我是個小白。沒有黑幣。如果你有這個壓縮包的話能發到我的郵箱嗎?846449482@qq.com 感激不盡
回復

使用道具 舉報

ID:152043 發表于 2016-12-4 13:23 | 顯示全部樓層
發的風格
回復

使用道具 舉報

ID:130591 發表于 2016-12-9 15:18 | 顯示全部樓層
謝謝分享,太好了!
回復

使用道具 舉報

ID:153476 發表于 2016-12-9 15:49 | 顯示全部樓層
看了一下 樓主專業知識很扎實
回復

使用道具 舉報

ID:130231 發表于 2017-3-17 19:12 | 顯示全部樓層
感謝你的分享
回復

使用道具 舉報

ID:166459 發表于 2017-3-18 09:49 | 顯示全部樓層

不錯學習,數碼管顯示適合初學者。我也弄個試試頂!頂!頂!
回復

使用道具 舉報

ID:233080 發表于 2017-9-29 14:52 | 顯示全部樓層
這個程序很好,我試過了,非常實用,多頂頂
回復

使用道具 舉報

ID:239797 發表于 2017-10-16 09:56 | 顯示全部樓層
樓主仿真用的是Multisim么?
回復

使用道具 舉報

ID:356193 發表于 2018-6-21 16:39 | 顯示全部樓層
樓主厲害,學習
回復

使用道具 舉報

ID:99130 發表于 2018-6-21 17:55 | 顯示全部樓層
想知道怎么和鎖連接
回復

使用道具 舉報

ID:266164 發表于 2018-6-21 20:37 | 顯示全部樓層
收下了。謝謝
回復

使用道具 舉報

ID:356610 發表于 2018-6-22 14:50 | 顯示全部樓層
好好研究研究
回復

使用道具 舉報

ID:517951 發表于 2020-11-15 13:41 | 顯示全部樓層
謝謝樓主分享,,51hei有你更精彩!!內容需要花時間消化
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产男女视频 | 中文字幕国产 | 玖草资源 | 99re视频 | 久久在线| com.国产 | 精品av天堂毛片久久久借种 | 两性午夜视频 | 久久久久久久香蕉 | 91婷婷韩国欧美一区二区 | 国产一级免费视频 | 黑人性hd | 欧美精品久久久久久久久老牛影院 | 日韩精品一二三 | 99视频入口| 欧美专区在线 | 午夜视频在线 | 日韩一二区在线 | 精品av | 一区二区在线免费观看视频 | 亚洲日本欧美日韩高观看 | 国产精品久久久久9999鸭 | 久草成人 | 国产a级黄色录像 | 九色网址| 国产精品免费一区二区 | 国产精品久久久久久久午夜 | 国产精品美女一区二区三区 | 成人激情视频在线 | 日日噜噜噜夜夜爽爽狠狠视频97 | 中文字幕一区二区三区四区五区 | 男女激情网 | 91观看 | 国产激情精品视频 | 国产观看 | 可以看黄的视频 | 久久久久久999 | 中文字幕第十一页 | 日韩中文在线观看 | 极品电影院 | 中文字幕在线欧美 |