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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

興向榮電子密碼鎖配套資料 1602顯示屏,矩陣鍵盤實現4組密碼鎖

[復制鏈接]
跳轉到指定樓層
樓主
ID:197912 發(fā)表于 2017-5-8 00:53 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
基于51單片機密碼鎖,1602顯示屏,矩陣鍵盤以及繼電器





10、讀寫存儲并顯示\
11最終程序-按鍵修改完密碼后進行存儲\
1、液晶顯示\
2、讀取矩陣鍵盤鍵碼\
3、六個按鍵碼的顯示\
4、將程序3輸入的6個鍵碼顯示改為隱藏\
5、判斷輸入的6位數和系統(tǒng)默認密碼是否一樣\
6、再程序5的基礎上加入定時器\
7、在程序6的基礎上加入聲音和計數器\
8、加入修改開鎖密碼的功能\
9、讀存儲器并顯示\


  1. //編譯環(huán)境: KEIL UVISION2
  2. //單片機晶振:12M  單片機型號AT89S52
  3. //單片機晶振: 無特殊要求
  4. //作者:興向榮電子元件店
  5. //功能:實現4組密碼鎖,4組密碼均可以修改,修改后掉電可以保持
  6. #include <reg52.h>
  7. #include <intrins.h>

  8. #define uchar unsigned char
  9. #define uint  unsigned int

  10. //==============LCD1602接口連接方法=====================
  11. /*-----------------------------------------------------
  12.        |DB0-----P0.0 | DB4-----P0.4 | RW-------P2.3    |
  13.        |DB1-----P0.1 | DB5-----P0.5 | RS-------P2.4    |
  14.        |DB2-----P0.2 | DB6-----P0.6 | E--------P2.2    |
  15.        |DB3-----P0.3 | DB7-----P0.7 |
  16.     ---------------------------------------------------*/
  17. //===============================AT24C16控制引腳定義===================
  18. sbit    sda_24c16=P2^0;//定義24C16串行數據線 第5腳
  19. sbit    scl_24c16=P2^1;//定義24C16串行時鐘線 第6腳
  20. //================================================*/              
  21. #define LCM_Data     P0    //LCD1602數據接口
  22. #define Busy         0x80   //用于檢測LCM狀態(tài)字中的Busy標識
  23. sbit    LCM_RW     = P2^6;  //讀寫控制輸入端,LCD1602的第五腳
  24. sbit    LCM_RS     = P2^5;  //寄存器選擇輸入端,LCD1602的第四腳
  25. sbit    LCM_E      = P2^7;  //使能信號輸入端,LCD1602的第6腳
  26. #define key_port   P3//用KEY_PORT代替P3
  27. sbit    beek_c  =P2^2;//定義蜂鳴器控制口
  28. sbit    lock_c  =P2^3;//定義鎖信號輸出口
  29. //**************函數聲明***************************************
  30. void    delay_3us();//3US的延時程序
  31. void    nack_24c16();//24C16非應答信號   
  32. void    stop_24c16();//停止通訊信號
  33. void    star_24c16();//啟動信號
  34. void    cack_24c16();//檢測應答信號
  35. void    mack_24c16();//發(fā)送應答信號
  36. void    w1byte_24c16(uchar byte1);//向24C16寫入一字節(jié)的數據
  37. uchar   rd1byte_24c16(void);
  38. void    read_24c16();//讀數據操作
  39. void    write_24c16();//寫入16字節(jié)的數據操作
  40. void    init_t0();//定時器0初始化函數
  41. void    WriteDataLCM                (uchar WDLCM);//LCD模塊寫數據
  42. void    WriteCommandLCM        (uchar WCLCM,BuysC); //LCD模塊寫指令
  43. uchar   ReadStatusLCM(void);//讀LCD模塊的忙標
  44. void    DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置顯示一個字符
  45. void    LCMInit(void);//LCD初始
  46. void    delayms(uint ms);//1MS基準延時程序
  47. void    delay_50us(unsigned int t);// 延時50*t(us)
  48. void    DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData);
  49. void    judge_xianshi(void);//顯示處理程序
  50. void    read_key(void);//按鍵鍵碼讀取子函數,返回相應的鍵碼
  51. uchar   keybord_value;//全局變量,存儲最終的鍵碼,其值為0-F
  52. void    read_password(void);//6位數據的讀取,也就是密碼的讀取
  53. uchar        deal_password(void);//輸入密碼和系統(tǒng)碼對比,看是否符合開鎖條件
  54.                             //返回值為1就開鎖,返回值為0為密碼錯誤
  55. void    makesurekeydeal();//確認鍵處理程序
  56. void    cancelkeydeal();//取消鍵處理程序
  57. //***********矩陣鍵盤鍵碼****************************************
  58. const uchar tabl2[16]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,
  59.                           //    s1   s2   s3   s4   s5   s6   s7   s8   s9
  60.                                0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77};
  61.                           //    s10  s11  s12  s13  s14  s15  s16
  62. uchar system[4][6];//定義 4*6個數據作為系統(tǒng)的密碼 也就是4組6位數
  63. uchar passin[6];//定義全局變量,儲存輸入的6個按鍵數據
  64. uchar temppassin[6];//輸入的數據暫存
  65. uchar flag1;//按鍵鍵入是否成功的標準,為1成功  為0失敗
  66. uchar  passcount;//鍵入次數的統(tǒng)計
  67. uchar  flag2;//密碼是否對的標志單位 ,為1成功  ,為0失敗
  68. uchar  flag3,flag4,flag5,flag6,flag7,flag12;
  69. uchar t0_crycle;
  70. uchar error_count;//密碼輸入次數
  71. //***********************主程序******************************
  72. main()   
  73. {   
  74.    passcount=0;
  75.    flag5=0;
  76.    flag7=0;
  77.    flag6=0;
  78.    flag4=0;
  79.    flag3=0;
  80.    flag1=0;
  81.    beek_c=1;//關閉蜂鳴器
  82.    lock_c=0;//關閉鎖
  83.    LCMInit();//液晶初始化設置
  84.    init_t0();
  85.    TR0=0;//關閉定時器T0
  86.    error_count=0;
  87.    read_24c16();//單片機上電的時候先讀取4組密碼
  88.    while(1)
  89.    {
  90.        read_key();//讀取鍵碼
  91.        read_password();//把鍵碼轉為密碼
  92.        judge_xianshi();//顯示
  93.    }
  94. }
  95. //****************************************************
  96. //寫入數據操作
  97. void write_24c16()
  98. {
  99.    uchar i,j;
  100. write1:
  101.    star_24c16();//發(fā)送啟動脈沖
  102.    w1byte_24c16(0xa0);//寫24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  103.    cack_24c16();// 讀取應答或非應答信號
  104.    if(flag12)goto write1;//判斷
  105.    w1byte_24c16(01);//寫入24C16的內部地址
  106.    cack_24c16();
  107.    if(flag12)goto write1;
  108.    for(j=0;j<2;j++)//先寫入12個字節(jié)的數據
  109.    {
  110.      for(i=0;i<6;i++)
  111.      {
  112.        w1byte_24c16(system[j][i]);
  113.        cack_24c16();
  114.        if(flag12)goto write1;
  115.      }
  116.     }
  117.     stop_24c16();//寫數據完畢,發(fā)送停止脈沖      
  118. write2:
  119.     star_24c16();//發(fā)送啟動脈沖
  120.     w1byte_24c16(0xa0);//寫24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  121.     cack_24c16();// 讀取應答或非應答信號
  122.     if(flag12)goto write2;//判斷
  123.     w1byte_24c16(17);//寫入24C16的內部地址
  124.     cack_24c16();
  125.     if(flag12)goto write2;
  126.     for(j=2;j<4;j++)//寫入后面24字節(jié)的數據
  127.     {
  128.         for(i=0;i<6;i++)
  129.         {
  130.              w1byte_24c16(system[j][i]);
  131.              cack_24c16();
  132.              if(flag12)goto write2;
  133.         }
  134.      }
  135.      stop_24c16();//寫數據完畢,發(fā)送停止脈沖              
  136. }  
  137. //***************************************************
  138. //讀數據操作
  139. void read_24c16()
  140. { uchar  i,j;
  141. read1:  
  142.   for(j=0;j<2;j++)//讀取前面12字節(jié)的數據
  143.   {
  144.      for(i=0;i<6;i++)
  145.      {
  146.         nack_24c16();
  147.         star_24c16();//發(fā)送啟動脈沖
  148.         w1byte_24c16(0xa0);//24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  149.         cack_24c16();
  150.         if(flag12)goto read1;
  151.         w1byte_24c16(j*6+i+1);//寫入24C16的內部地址,選擇第二頁
  152.         cack_24c16();
  153.         if(flag12)goto read1;
  154.         nack_24c16();
  155.         stop_24c16();//重新開始   
  156.         star_24c16();//
  157.         w1byte_24c16(0xa1);// 24C16的芯片地址,高四位固定為1010,選擇第一區(qū),讀操作
  158.         cack_24c16();
  159.         if(flag12)goto read1;
  160.         system[j][i]=rd1byte_24c16();
  161.       }
  162.    }
  163.    mack_24c16();
  164.    nack_24c16();
  165.    stop_24c16();
  166. read2:  
  167.    for(j=2;j<4;j++)
  168.    {
  169.      for(i=0;i<6;i++)
  170.      {
  171.         nack_24c16();
  172.         star_24c16();//發(fā)送啟動脈沖
  173.         w1byte_24c16(0xa0);//24C16的芯片地址,高四位固定為1010,選擇第一區(qū),寫操作
  174.         cack_24c16();
  175.         if(flag12)goto read2;
  176.         w1byte_24c16(j*6+i+5);//寫入24C16的內部地址,選擇第二頁
  177.         cack_24c16();
  178.         if(flag12)goto read2;
  179.         nack_24c16();
  180.         stop_24c16();//重新開始   
  181.         star_24c16();//
  182.         w1byte_24c16(0xa1);// 24C16的芯片地址,高四位固定為1010,選擇第一區(qū),讀操作
  183.         cack_24c16();
  184.         if(flag12)goto read2;
  185.        system[j][i]=rd1byte_24c16();
  186.      }
  187.   }
  188.   mack_24c16();
  189.   nack_24c16();
  190.   stop_24c16();
  191.   for(j=0;j<4;j++)//
  192.   {
  193.      for(i=0;i<6;i++)
  194.      {
  195.          if(system[j][i]>15)system[j][i]=1;//出廠芯片讀出的是FF,這樣就沒有密碼可以輸入了,防止防止這種任何密碼都無效的情況,我們設置出廠4組密碼都是111 111
  196.      }
  197.   }
  198. }
  199. //****************************************************
  200. //顯示處理程序
  201. void   judge_xianshi()
  202. {
  203.   uchar i;
  204.   _nop_();
  205.   if(flag2==0)//開關初始顯示
  206.   {
  207.      DisplayListChar(0,0,0, "Electronics Lock");//
  208.      DisplayListChar(1,0,0, "Password:");
  209.      for(i=0;i<passcount&&i<6;i++)//顯示輸入的6個數據
  210.      {
  211.         DisplayOneChar( 1, 9+i, '*'); //第一行改為隱藏
  212. //    //第二行改為真實顯示,可以把這句刪除就隱藏密碼了
  213.      }
  214.   }
  215.   else if(flag2==5)
  216.   {
  217.      DisplayListChar(0,0,0, "Change passwor ");
  218.      DisplayOneChar( 0,15,flag5+0x30);
  219.      DisplayListChar(1,0,0, "0:      n:      ");
  220.      
  221.      for(i=0;i<6;i++)
  222.      {
  223.         DisplayOneChar( 1,i+2,system[flag5-1][i]+0x30);
  224.      }
  225.      for(i=0;i<6;i++)DisplayOneChar( 1,i+10,temppassin[i]+0x30);
  226.   }
  227. }
  228. //6位數據的讀取,也就是密碼的讀取
  229. void  read_password()
  230. {
  231.    _nop_();
  232.    if(flag1==1 )//判斷鍵入是否成功
  233.    {
  234.       flag1=0;
  235.       if(passcount<6 && flag5==0)
  236.       {
  237.               passin[passcount]=keybord_value;
  238.               passcount++;
  239.       }

  240.       if(passcount<6 && flag5!=0)
  241.       {
  242.               if(keybord_value!=15 && keybord_value!=14 )
  243.               {
  244.                 flag7=1;
  245.                 temppassin[passcount]=keybord_value;
  246.                 passcount++;
  247.               }
  248.       }
  249.       cancelkeydeal();//取消鍵處理程序
  250.       makesurekeydeal();//確認鍵處理程序
  251.       if(keybord_value==15 && flag7==0)//判斷是否為設置鍵
  252.       {
  253.          flag5++;
  254.          if(flag5>=5)flag5=1;
  255.        }
  256.    }
  257. }
  258. //************************************************
  259. //確認鍵處理程序
  260. void    makesurekeydeal()
  261. {
  262.    uchar i;
  263.    _nop_();
  264.    if(keybord_value==12 && flag7==0 )//判斷時候為確認鍵
  265.       {
  266.            flag2=deal_password();// 判斷輸入的密碼是否正確
  267.            passcount=0;
  268.            if(flag3==0)//按第一次確認
  269.            {
  270.               flag3=1;
  271.               if(flag2==1)//輸入的密碼正確
  272.               {
  273.                  beek_c=0;//開蜂鳴器
  274.                  lock_c=1;//開鎖
  275.                  flag6=1;
  276.                  DisplayListChar(1,0,0, "Opening........");//在液晶的第二行顯示字符"OPERING
  277.                  TR0=1;
  278.                  flag4=0;
  279.                  error_count=0;
  280.                  while(flag4<=20);//密碼正確開鎖信號閉合2秒 蜂鳴器響2秒
  281.                  flag4=0;
  282.                  flag2=0;
  283.                  flag3=0;
  284.                  TR0=0;
  285.                  WriteCommandLCM(0x01,1); //清除顯示一下
  286.                  beek_c=1;//關閉蜂鳴器
  287.                  lock_c=0;//斷開鎖信號輸出
  288.                
  289.               }
  290.               else if(flag2==2)//輸入的密碼錯誤
  291.               {
  292.                   beek_c=0;
  293.                   TR0=1;
  294.                   flag6=0;
  295.                   error_count++;//密碼輸入錯誤后,計數器+1
  296.                   DisplayListChar(1,0,0, "Input Error  TIS");
  297.                   DisplayOneChar( 1,12,error_count+0x30);//顯示輸入多少次錯誤
  298.                   while(flag4<=5);//密碼輸入錯誤蜂鳴器響0.5秒,關0.5秒的頻率響2次
  299.                   beek_c=1;
  300.                   flag4=0;
  301.                   while(flag4<=5);
  302.                   beek_c=0;
  303.                   flag4=0;
  304.                   while(flag4<=5);
  305.                   beek_c=1;
  306.                   flag4=0;
  307.                   flag2=0;
  308.                   flag3=0;
  309.                   TR0=0;
  310.                   if(error_count>=3)//如果密碼輸入3次錯誤經鎖定2.54分鐘或需要重新斷電
  311.                   {
  312.                      DisplayListChar(0,0,0, "Input Error 3 Ts");
  313.                      DisplayListChar(1,0,0, "locked 3 minutes");
  314.                      TR0=1;
  315.                      while(flag4<=254);//鎖定時間過后系統(tǒng)恢復
  316.                      DisplayListChar(0,0,0, "Electronics Lock");
  317.                      TR0=0;
  318.                      error_count=0;
  319.                      flag4=0;
  320.                   }
  321.               }
  322.            }
  323.        /*    else if(flag3==1)//第二次按確認
  324.            {
  325.               flag2=0;
  326.               flag3=0;
  327.            }*/
  328.             WriteCommandLCM(0x01,1); //清除顯示一下
  329.       }
  330.     if(keybord_value==12 && flag7==1 )//確認修改密碼
  331.     {
  332.            for(i=0;i<6;i++)
  333.            {
  334.                   system[flag5-1][i]=temppassin[i];//把暫存單元的數據傳給對應的開始密碼
  335.                   temppassin[i]=0;//暫存單元清零,下次修改密碼可以再次利用
  336.            }
  337.            write_24c16();
  338.            flag7=0;//各種標志單元清零
  339.            flag2=0;
  340.            flag3=0;
  341.            flag5=0;
  342.            flag6=0;
  343.            passcount=0; //按鍵次數計數清零
  344.            WriteCommandLCM(0x01,1); //清除顯示一下
  345.     }
  346. }
  347. //************************************************
  348. //取消鍵處理程序
  349. void    cancelkeydeal()
  350. {
  351.     uchar i;
  352.     _nop_();
  353.     if(keybord_value==13 )//判斷是否為取消鍵
  354.     {
  355.        if(flag7==0)
  356.        {
  357.            for(i=0;i<passcount;i++)
  358.            {
  359.                passin[i]=0;
  360.            }//清零
  361.            passcount=0;//按取消鍵后,鍵入按鍵次數的計數單元清零
  362.            if(flag3==1)//取消顯示密碼錯誤
  363.            {
  364.               flag2=0;
  365.               flag3=0;
  366.             }
  367.        }
  368.        else if(flag7==1)
  369.        {
  370.            flag7=0;
  371.            flag2=0;
  372.            flag3=0;
  373.            flag5=0;
  374.            flag6=0;
  375.            passcount=0;
  376.            
  377.        }
  378.        WriteCommandLCM(0x01,1); //清除顯示一下
  379.     }
  380. }
  381. uchar  deal_password()//輸入密碼和系統(tǒng)碼對比,看是否符合開鎖條件
  382. {
  383.    uchar i,j,temp2,temp;
  384.    temp2=0;
  385.    _nop_();
  386.    for(j=0;j<4;j++)//依次判斷4組
  387.    {
  388.      temp=0;
  389.      for(i=0;i<6;i++)
  390.      {
  391.       if(system[j][i]==passin[i])temp++;//如果系統(tǒng)密碼和鍵入的密碼對應的位一樣,則暫存單元自加1
  392.      }
  393.      if(temp==6)
  394.      {
  395.        temp2=1;
  396.        return(1);//如果TEMP為6,證明鍵入的密碼和4組系統(tǒng)密碼中的一組一樣;
  397.        break;//退出判斷
  398.      }
  399.    }
  400.    if(temp2==0)return(2);
  401. }
  402. void read_key(void)
  403. {
  404.    uchar  key_value,i=1;
  405.    uchar key_high_value,key_low_value;//定義變量暫存高四位和低四位按鍵的鍵碼
  406.    _nop_();
  407.    key_port=0xf0;//置按鍵控制口為1,準備讀入數據
  408.    key_value=key_port & 0xf0;
  409.    if(key_value!=0xf0)//如果沒有按鍵按下,則相等
  410.    {
  411.       delay_50us(200);//延時10ms去除抖動
  412.       key_port=0xf0;//再次講IO置1,準備讀入去除抖動后的數據
  413.       key_value=key_port & 0xf0;
  414.       switch (key_value)
  415.       { case 0xf0:break;//經軟件延時后,判斷為誤判,則退出函數,返回
  416.         case 0x70:key_high_value=0x70;break;
  417.         case 0xb0:key_high_value=0xb0;break;
  418.         case 0xd0:key_high_value=0xd0;break;
  419.         case 0xe0:key_high_value=0xe0;break;
  420.         default:key_high_value=0x00;break;//多個按鍵同時按下,顯示0,然后退出
  421.       }
  422.       key_port=0x0f;//交換高四位和低四位的狀態(tài),再次讀取鍵碼
  423.       key_value=key_port & 0x0f;
  424.       switch(key_value)
  425.       {
  426.          case 0x07:key_low_value=0x07;break;
  427.          case 0x0b:key_low_value=0x0b;break;
  428.          case 0x0d:key_low_value=0x0d;break;
  429.          case 0x0e:key_low_value=0x0e;break;
  430.          default:key_low_value=0x00;break;
  431.       }
  432.      key_value=key_high_value | key_low_value;
  433.      for(i=0;i<16;i++)
  434.      {
  435.        if(key_value==tabl2[i])
  436.        {
  437.           keybord_value=i;
  438.           flag1=1;//置按鍵碼讀取成功標志位1;
  439.           if(flag6==1 && keybord_value==14)
  440.           {
  441.                 flag1=0;
  442.           }
  443.           break;
  444.        }
  445.      }
  446.      beek_c=0;//開蜂鳴器
  447.      TR0=1;
  448.      while(flag4<=1);//按按鍵的時候蜂鳴器響0.1秒
  449.      flag4=0;
  450.      TR0=0;//關閉定時器
  451.      beek_c=1;//關閉蜂鳴器
  452.      if(flag6!=0)
  453.      {
  454.      if(keybord_value==14)
  455.      {
  456.          TR0=1;
  457.          key_port=0xf0;//置按鍵控制口為1,準備讀入數據
  458.          while((key_port & 0xf0 )!=0xf0 && flag5==0)
  459.          {
  460.             
  461.              if(flag4>=30)
  462.              {
  463.                 TR0=0;
  464.                 flag4=0;
  465.                 flag2=5;
  466.                 flag5=1;
  467.                 flag7=0;
  468.              }
  469.          }

  470.        }
  471.      }
  472.      key_port=0xf0;//置按鍵控制口為1,準備讀入數據
  473.      while((key_port & 0xf0 )!=0xf0 && keybord_value!=14 );    //等待按鍵釋放,按鍵釋放后才往下執(zhí)行程序
  474.    }
  475. }
  476. //定時器0中斷服務程序
  477. void timer0() interrupt 1
  478. {
  479.         TH0=(65536-50000)/256;
  480.         TL0=(65536-50000)%256;//定時器設置為定時50MS
  481.         t0_crycle++;
  482.         if(t0_crycle==2)// 0.1秒
  483.         {
  484.           t0_crycle=0;
  485.           flag4++; //定時器開啟后,FLAG4每0.1秒自加1
  486.       if(flag6!=0 && flag4>=40)//輸入密碼正確開鎖后超過2分鐘后不能進入修改開鎖密碼的界面
  487.       {
  488.          flag6=0;
  489.          flag4=0;
  490.          TR0=0;
  491.       }
  492.         }
  493. }
  494. //********************************************************************************************
  495. void init_t0()
  496. {
  497.     _nop_();
  498.            TMOD=0x01;//設定定時器工作方式1,定時器定時50毫秒
  499.         TH0=(65536-50000)/256;
  500.         TL0=(65536-50000)%256;
  501.         EA=1;//開總中斷
  502.         ET0=1;//允許定時器0中斷
  503.         t0_crycle=0;//定時器中斷次數計數單元
  504. }
  505. /*====================================================================  
  506.   按指定位置顯示一串字符:第 X 行,第 y列
  507.   注意:字符串不能長于16個字符
  508. ======================================================================*/
  509. void DisplayListChar(uchar X,uchar Y,uchar ms, uchar code *DData)
  510. {
  511.     uchar ListLength;
  512.     _nop_();
  513.     ListLength = 0;
  514.     X &= 0x1;
  515.     Y &= 0xF; //限制X不能大于15,Y不能大于1
  516.     while (DData[ListLength]!='\0') //若到達字串尾則退出
  517.     {
  518.         if (Y <= 0xF) //X坐標應小于0xF
  519.         {
  520.              DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符
  521.              ListLength++;
  522.              Y++;
  523.                  delayms(ms);//延時顯示字符串
  524.         }
  525.         else
  526.             break;//跳出循環(huán)體
  527.      }
  528. }
  529. /*======================================================================
  530. LCM初始化
  531. ======================================================================*/
  532. void LCMInit(void)
  533. {
  534. LCM_Data = 0;
  535. _nop_();
  536. WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
  537. delayms(5);
  538. WriteCommandLCM(0x38,0);
  539. delayms(5);
  540. WriteCommandLCM(0x38,0);
  541. delayms(5);
  542. WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
  543. WriteCommandLCM(0x08,1); //關閉顯示
  544. WriteCommandLCM(0x01,1); //顯示清屏
  545. WriteCommandLCM(0x06,1); // 顯示光標移動設置
  546. WriteCommandLCM(0x0C,1); // 顯示開及光標設置
  547. delayms(100);
  548. }
  549. //==============================LCD1602顯示子程序================================================
  550. // 寫數據函數: E =高脈沖 RS=1 RW=0
  551. //======================================================================*/
  552. void WriteDataLCM(uchar WDLCM)
  553. {
  554. ReadStatusLCM(); //檢測忙
  555. _nop_();
  556. LCM_Data = WDLCM;
  557. LCM_RS = 1;
  558. LCM_RW = 0;
  559. LCM_E = 0; //若晶振速度太高可以在這后加小的延時
  560. LCM_E = 0; //延時
  561. LCM_E = 1;
  562. }
  563. /*====================================================================
  564.   寫指令函數: E=高脈沖 RS=0 RW=0
  565. ======================================================================*/
  566. void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC為0時忽略忙檢測
  567. {
  568. if (BuysC) ReadStatusLCM(); //根據需要檢測忙
  569. LCM_Data = WCLCM;
  570. LCM_RS = 0;
  571. LCM_RW = 0;
  572. LCM_E = 0;
  573. LCM_E = 0;
  574. LCM_E = 1;
  575. }
  576. /*====================================================================
  577.   正常讀寫操作之前必須檢測LCD控制器狀態(tài):E=1 RS=0 RW=1;
  578.   DB7: 0 LCD控制器空閑,1 LCD控制器忙。
  579.   讀狀態(tài)
  580. ======================================================================*/
  581. uchar ReadStatusLCM(void)
  582. {
  583. LCM_Data = 0xFF;
  584. LCM_RS = 0;
  585. LCM_RW = 1;
  586. LCM_E = 0;
  587. LCM_E = 0;
  588. LCM_E = 1;
  589. while (LCM_Data & Busy); //檢測忙信號  
  590. return(LCM_Data);
  591. }
  592. /*======================================================================
  593. 功 能:     在1602 指定位置顯示一個字符:第一行位置0~15,第二行16~31
  594. 說 明:     第 X 行,第 y 列  注意:字符串不能長于16個字符
  595. ======================================================================*/
  596. void DisplayOneChar( uchar X, uchar Y, uchar ASCII)
  597. {
  598.   X &= 0x1;
  599.   Y &= 0xF; //限制Y不能大于15,X不能大于1
  600.   if (X) Y |= 0x40; //當要顯示第二行時地址碼+0x40;
  601.   Y |= 0x80; // 算出指令碼
  602.   WriteCommandLCM(Y, 0); //這里不檢測忙信號,發(fā)送地址碼
  603.   WriteDataLCM(ASCII);
  604. }
  605. /*====================================================================
  606.   設定延時時間:x*1ms
  607. ====================================================================*/
  608. void delayms(uint Ms)
  609. {
  610.   uint i,TempCyc;
  611.   for(i=0;i<Ms;i++)
  612.   {
  613.     TempCyc =70;
  614.     while(TempCyc--);
  615.   }
  616. }
  617. //***********************************************************************
  618. //函數名稱:void delay_50US(unsigned int t)
  619. //功能: 延時50*t(us)
  620. void delay_50us(unsigned int t)
  621. {
  622.   unsigned char j;
  623.   for(;t>0;t--)
  624.   {
  625.     for(j=19;j>0;j--);
  626.   }
  627. }
  628. //******************************************************************************************
  629. //***********************************************
  630. //3微秒延時程序
  631. void delay_3us()
  632. {
  633.   ;
  634.   ;
  635. }   
  636. //*************************************************
  637. //功能:發(fā)送非應答信號
  638. void nack_24c16()
  639. {
  640. sda_24c16=1;   
  641. delay_3us();
  642. delay_3us();
  643. scl_24c16=1;
  644. delay_3us();
  645. delay_3us();
  646. scl_24c16=0;
  647. sda_24c16=0;
  648. }
  649. //*************************************************
  650. //功能:發(fā)送IIC停止信號
  651. void stop_24c16()
  652. {  
  653.    sda_24c16=0;
  654.    scl_24c16=1;                              
  655.    delay_3us();
  656.    delay_3us();                        
  657.    sda_24c16=1;
  658.    delay_3us();
  659.    delay_3us();                                 
  660.    scl_24c16=0;
  661. }
  662. //*************************************************
  663. //功能:發(fā)送啟動通訊的信號
  664. void star_24c16()
  665. {
  666.   sda_24c16=1;
  667.   scl_24c16=1;
  668.   delay_3us();
  669.   delay_3us();
  670.   sda_24c16=0;
  671.   delay_3us();
  672.   delay_3us();
  673.   scl_24c16=0;
  674. }  
  675. //****************************************************
  676. //功能:判斷應答或非應答
  677. //說明:通訊出錯時標志為1,否則為0
  678. void cack_24c16()
  679. {  
  680.    scl_24c16=0;
  681.    sda_24c16=1;
  682.    delay_3us();         
  683.    scl_24c16=1;              
  684.    flag12=0;//清除錯誤標志   
  685.    if(sda_24c16)flag12=1;
  686.    scl_24c16=0;
  687. }      
  688. //****************************************************
  689. //功能:發(fā)送應答信號
  690. void mack_24c16()  
  691. {
  692.   sda_24c16=0;
  693.   scl_24c16=1;
  694.   delay_3us();
  695.   delay_3us();
  696.   scl_24c16=0;
  697.   sda_24c16=1;
  698. }
  699. //*************************************************
  700. //功能:向24C16寫入一字節(jié)的數據
  701. void w1byte_24c16(uchar byte1)
  702. {
  703.   uchar i=8;
  704.   while(i--)   
  705.   {            
  706.     delay_3us();
  707.     delay_3us();
  708.     delay_3us();
  709.     if(byte1 & 0x80)
  710.     {sda_24c16=1;}
  711.     else
  712.     {sda_24c16=0;}
  713.     delay_3us();
  714.     delay_3us();
  715.     delay_3us();
  716.     scl_24c16=1;
  717.     delay_3us();
  718.     delay_3us();
  719.     delay_3us();
  720.     scl_24c16=0;
  721.     byte1<<=1;  
  722.   }
  723. }
  724. //*******************************
  725. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼




下載:
rar (1)rr.rar (1.95 MB, 下載次數: 46)


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

使用道具 舉報

沙發(fā)
ID:139236 發(fā)表于 2017-5-8 07:54 | 只看該作者
很好的例程感謝分享
回復

使用道具 舉報

板凳
ID:257877 發(fā)表于 2017-12-6 15:55 | 只看該作者
我想請問下樓主你的這個程序里是怎么按下才算是修改密碼的
回復

使用道具 舉報

地板
ID:795427 發(fā)表于 2022-12-5 22:33 | 只看該作者
修改密碼存在問題
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品免费看 | 日日干天天操 | 成人性生交a做片 | 欧美最猛黑人xxxx黑人 | 91在线精品视频 | 狠狠亚洲 | 欧美一级做性受免费大片免费 | 日韩一区二区在线视频 | 成人亚洲视频 | 亚洲精品久久国产高清情趣图文 | 日本不卡一区 | 久久99国产精一区二区三区 | 欧美激情综合网 | 欧美成人第一页 | 国产成人福利视频在线观看 | 国产中文字幕在线 | 久久久久国产一区二区三区四区 | 91成人免费电影 | 成人毛片在线观看 | 色婷婷狠狠 | 精品av| 欧美最猛性xxxxx亚洲精品 | 欧美在线一区二区三区 | 国产精品1区2区3区 国产在线观看一区 | 日韩午夜电影 | 在线观看a视频 | 亚洲国产日韩欧美 | 久久久久久国产精品 | 看片国产 | 国产精品久久久久aaaa樱花 | 美国一级黄色片 | 久久91 | www.久久| av国产在线观看 | 精品国产乱码一区二区三区 | 欧洲高清转码区一二区 | 精品一区二区三区不卡 | 中文字幕亚洲专区 | 视频二区 | 国产精品欧美一区二区三区 | 亚洲精品日韩一区二区电影 |