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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7091|回復: 15
收起左側

關于單片機密碼鎖*號顯示的一個簡單問題!

[復制鏈接]
ID:289777 發表于 2018-5-2 18:00 | 顯示全部樓層 |閱讀模式
密碼鎖已經編寫號,但有一個功能求助
我想實現這么一個功能,就是輸入密碼全是 * ,然后如果一直按下仿真中那個按鈕A,所有*號顯示成相應的數字,這個功能一直沒實現,求助應該如何改寫程序?


I@7UOT8`)4B9CP4M7PRQN}P.png

項目設計-密碼鎖.zip (1.36 MB, 下載次數: 28)

  1. #include <REG52.h>
  2. #include<intrins.h>
  3. sbit K1=P1^2;
  4. sbit ALAM = P2^5;                                                                                                //報警        
  5. sbit open_led=P2^3;                                                                                                //開鎖指示燈        
  6. /*LCD接口定義*/
  7. sbit LcdRS   = P2^0;                                                                                      //lcd數據/命令選擇端  數據1命令0
  8. sbit LcdRW   = P2^1;                                                                                      //lcd讀/寫選擇端    讀1寫0
  9. sbit LcdEn   = P2^2;                                                                                      //lcd使能控制端  1有效
  10. sfr  LcdIO   = 0x80;                                                                                      //lcd數據接口 P0=0x80

  11. unsigned char code a[]={0xFE,0xFD,0xFB,0xF7};                                         //控盤掃描控制表
  12.                
  13. unsigned char countt0,second;                                                                        //t0中斷計數器,秒計數器
  14. unsigned char code start_line[]        = {"password:       "};
  15. unsigned char code name[]                  = {"===Coded Lock==="};                     //顯示名稱                 
  16. unsigned char code Error[]           = {"      error     "};                  //輸入錯誤
  17. unsigned char code codepass[]        = {"      pass      "};
  18. unsigned char code LockOpen[]        = {"      open      "};                        //OPEN

  19. char InputData[6];                                                                                                //輸入密碼暫存區
  20. unsigned char CurrentPassword[6]={6,5,4,3,2,1};                                 //當前密碼值
  21. unsigned char N=0;                                                                                                //密碼輸入位數記數
  22. unsigned char ErrorCont;                                                                                //錯誤次數計數
  23. unsigned char KEY_SCAN,NUM;

  24. /****向LCD寫入命令或數據部分****/
  25. #define LCD_COMMAND         0         // 輸出指令
  26. #define LCD_DATA            1         // 輸出數據
  27. #define LCD_CLEAR_SCREEN    0x01      // 清屏指令
  28. #define LCD_HOME            0x02      // 光標返回原點指令

  29. //=====================16us短延時==============================
  30. void Delay_short(unsigned int n)
  31. {
  32.          unsigned int i;
  33.          for(i=0;i<n;i++)     
  34.          {;}
  35. }
  36. //=====================長延時==============================
  37. void Delay_long(unsigned char N)
  38. {
  39.         unsigned char i;
  40.           unsigned int j;
  41.            for(i=0;i<N;i++)
  42.            {
  43.                 for(j=0;j<315;j++)  //一個循環16us,共5ms
  44.               {;}
  45.    }
  46. }
  47. //=====================5ms延時==============================
  48. void Delay5Ms(void)
  49. {
  50.         unsigned int TempCyc = 5552;
  51.         while(TempCyc--);
  52. }
  53. //===================400ms延時==============================
  54. void Delay400Ms(void)
  55. {
  56.          unsigned char TempCycA = 5;
  57.          unsigned int TempCycB;
  58.          while(TempCycA--)
  59.          {
  60.                   TempCycB=7269;
  61.                   while(TempCycB--);
  62.          }
  63. }

  64. /*寫LCD子程序                                          */
  65. /*入口參數:數據style=1 指令, style=0 input:寫入的內容*/

  66. void LCD_Write(bit style, unsigned char input)  
  67. {
  68.     LcdRS=style;         //數據style=1  指令style=0
  69.     LcdRW=0;             //寫
  70.     LcdIO=input;         //P0口輸出
  71.     Delay_short(10);     //延時
  72.     LcdEn=1;             //lcd使能
  73.     Delay_short(10);     //延時
  74.     LcdEn=0;             //停止
  75. }

  76. /****初始化LCD程序****/
  77. void LCD_Initial()
  78. {
  79.     Delay_long(6);                                     //延遲5*6=30ms
  80.     LCD_Write(LCD_COMMAND,0x38);                       //8位數據端口,2行顯示,5*7點陣
  81.     LCD_Write(LCD_COMMAND,0x38);
  82.     LCD_Write(LCD_COMMAND,0x38);                       //發送三遍
  83.     Delay_short(2);                                    //延遲大于39us
  84.     LCD_Write(LCD_COMMAND,0x0c);                            //顯示模式設置:開啟顯示, 無光標 0x0c
  85.     Delay_short(2);                             //延遲大于39us
  86.     LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);           //清屏                          0x01
  87.     Delay_short(100);                           //延遲大于1.53ms
  88.     LCD_Write(LCD_COMMAND,0x06);                               //輸入模式設置:AC遞增, 畫面不動 0x06
  89. }


  90. /*液晶字符輸入的位置定位程序*/
  91. /*入口參數:x范圍:0-15     y范圍:1,2*/
  92. void GotoXY(unsigned char x, unsigned char y)  
  93. {
  94.     unsigned char address;
  95.     if(y==1)
  96.         {
  97.         address=0x80+x;         //y=1顯示在第一行
  98.     }
  99.         else
  100.         {
  101.         address=0xc0+x;      //y=2顯示在第二行
  102.     }
  103.         LCD_Write(LCD_COMMAND, address);
  104. }

  105. /*將字符串輸出到液晶顯示函數*/
  106. /*入口參數:字符串指針      */
  107. void Print(unsigned char *str)
  108. {
  109.     while(*str!='\0')
  110.     {
  111.         LCD_Write(LCD_DATA,*str);
  112.         str++;
  113.     }
  114. }
  115. //*********************************************************************
  116. //==============將按鍵值編碼為數值=========================
  117. unsigned char coding(unsigned char m)         
  118. {
  119.         unsigned char k;
  120.         switch(m)
  121.         {
  122. //                case (0x18): k=3;break;
  123. //                case (0x28): k=7;break;
  124. //                case (0x48): k='#';break;
  125. //                case (0x88): k='D';break;
  126.                 case (0x14): k=3;break;
  127.                 case (0x24): k=6;break;
  128.                 case (0x44): k=9;break;
  129.                 case (0x84): k='#';break;
  130.                 case (0x12): k=2;break;
  131.                 case (0x22): k=5;break;
  132.                 case (0x42): k=8;break;
  133.                 case (0x82): k=0;break;
  134.                 case (0x11): k=1;break;
  135.                 case (0x21): k=4;break;
  136.                 case (0x41): k=7;break;
  137.                 case (0x81): k='*';break;
  138.         }
  139.         return(k);
  140. }
  141. //=====================按鍵檢測并返回按鍵值===============================
  142. unsigned char keynum(void)
  143. {
  144.          unsigned char row,col,i;
  145.          P3=0xf0;
  146.          if((P3&0xf0)!=0xf0)
  147.          {
  148.                    Delay5Ms();
  149.               Delay5Ms();
  150.                    if((P3&0xf0)!=0xf0)
  151.                 {
  152.                     row=P3^0xf0;          //確定行線
  153.                         i=0;
  154.                         P3=a[i];                  //精確定位
  155.                         while(i<4)
  156.                         {
  157.                                  if((P3&0xf0)!=0xf0)
  158.                                   {
  159.                                            col=~(P3&0xff);          //確定列線
  160.                                            break;            //已定位后提前退出   
  161.                                   }
  162.                                 else
  163.                                   {
  164.                                            i++;
  165.                                            P3=a[i];
  166.                                   }
  167.                         }
  168.                 }
  169.                 else
  170.                 {                 
  171.                         return 0xff;        
  172.                 }
  173.                 while((P3&0xf0)!=0xf0);
  174.                 return (row|col);                         //行線與列線組合后返回
  175.          }
  176.          else
  177.         {
  178.                 return 0xff;                                 //無鍵按下時返回0xff
  179.         }
  180. }
  181. //***************************************************************************************/
  182. //=======================一聲提示音,表示有效輸入========================
  183. void OneAlam(void)
  184. {
  185.         unsigned char y;
  186.         for(y=0;y<30;y++)
  187.         {
  188.         ALAM=0;
  189.         Delay_short(50);
  190.           ALAM=1;
  191.         Delay_short(50);
  192.         }

  193. }

  194. //========================二聲提示音,表示操作成功========================
  195. void TwoAlam(void)
  196. {
  197.         OneAlam();
  198.         Delay5Ms();
  199.     ALAM=1;
  200.           Delay5Ms();
  201.         OneAlam();
  202.         Delay5Ms();
  203.     ALAM=1;
  204. }
  205. //========================三聲提示音,表示錯誤========================
  206. void ThreeAlam(void)
  207. {
  208.         OneAlam();
  209.         Delay5Ms();
  210.     ALAM=1;
  211.         Delay5Ms();
  212.         OneAlam();
  213.         Delay5Ms();
  214.     ALAM=1;
  215.           Delay5Ms();
  216.         OneAlam();
  217.         Delay5Ms();
  218.     ALAM=1;
  219. }
  220. //=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
  221. void Alam_KeyUnable(void)
  222. {
  223.         P3=0x00;
  224.         {
  225.                 OneAlam();
  226.                 Delay5Ms();
  227.             ALAM=1;
  228.                 Delay5Ms();
  229.         }
  230. }
  231. //=======================取消所有操作============================================
  232. void Cancel(void)
  233. {        
  234.         unsigned char i;
  235.         GotoXY(0,2);
  236.         Print(start_line);        
  237.         TwoAlam();                                //提示音
  238.         for(i=0;i<6;i++)
  239.         {
  240.                 InputData[i]=0;
  241.         }
  242.         ALAM=1;                                        //報警關
  243.         ErrorCont=0;                        //密碼錯誤輸入次數清零
  244.         open_led=1;                                  //指示燈關閉
  245.         N=0;                                        //輸入位數計數器清零
  246. }
  247. //==========================確認鍵,并通過相應標志位執行相應功能===============================
  248. void Ensure(void)
  249. {        
  250.         unsigned char i,j;
  251.         for(i=0;i<6;)
  252.         {                                       
  253.                 if(CurrentPassword[i]==InputData[i])
  254.                 {
  255.                         i++;
  256.                 }
  257.                 else
  258.                 {                        
  259.                         ErrorCont++;
  260.                         if(ErrorCont==3)                        //錯誤輸入計數達三次時,報警并鎖定鍵盤
  261.                         {
  262.                                 GotoXY(0,2);
  263.                                 Print("  KeypadLocked! ");
  264.                                 TR0=1;
  265.                                 do
  266.                                     Alam_KeyUnable();
  267.                                 while(TR0);
  268.                 return ;
  269.                         }
  270.             break;
  271.                 }
  272.         }

  273.         if(i==6)   //密碼正確輸入
  274.         {
  275.                         GotoXY(0,2);
  276.                         Print(codepass);
  277.                         Delay400Ms();
  278.                         Delay400Ms();
  279.                         GotoXY(0,2);
  280.                         Print(LockOpen);        
  281.                         TwoAlam();                                           //操作成功提示音
  282.                         //KEY_CLOCK=0;                                                                                        //開鎖
  283.                         //pass=1;                                                                                        //置正確標志位
  284.                         open_led=0;                                                                                //開鎖指示燈亮
  285.                         for(j=0;j<6;j++)                                                                //將輸入清除
  286.                         {
  287.                                 InputData[i]=0;
  288.                         }
  289.                         while(1);
  290.         }
  291.         else
  292.         {
  293.         GotoXY(0,2);
  294.                 Print(Error);        
  295.                  ThreeAlam();                                                                                //錯誤提示音
  296.         Delay400Ms();
  297.         GotoXY(0,2);
  298.                 Print(start_line);
  299.         for(j=0;j<6;j++)                                                                //將輸入清除
  300.                 {
  301.                         InputData[i]=0;
  302.                  }
  303.     }
  304.         N=0;                                                                                                        //將輸入數據計數器清零,為下一次輸入作準備
  305. }

  306. void test_led()
  307. {
  308.         while(1)
  309.         {
  310.                 open_led=0;
  311.                 Delay400Ms();
  312.                 open_led=1;
  313.                 Delay400Ms();
  314.         }
  315. }

  316. void test_alarm()
  317. {
  318.     while(1)
  319.         {
  320.                 ALAM=1;
  321.                 Delay_short(60);
  322.                 ALAM=0;
  323.                 Delay_short(60);
  324.         }
  325. }
  326. void timer_init()
  327. {
  328.         TMOD=0x11;
  329.          TL0=0xB0;
  330.          TH0=0x3C;
  331.          EA=1;
  332.          ET0=1;        
  333.          TR0=0;
  334. }

  335. void test_key()
  336. {
  337.         unsigned char code ascii[]={"0123456789ABCDEF"};
  338.         KEY_SCAN=keynum();
  339.         if(KEY_SCAN!=0xff)
  340.         {
  341.                 GotoXY(0,1);
  342.                 Print("key_code:0x");
  343.                 LCD_Write(LCD_DATA, ascii[KEY_SCAN/16]);
  344.                 LCD_Write(LCD_DATA, ascii[KEY_SCAN%16]);
  345.         }
  346. }

  347. //==============================主函數===============================
  348. void main(void)
  349. {
  350.          
  351.         unsigned char j;
  352. //        test_led();
  353. //        test_alarm();
  354.          Delay400Ms();         //啟動等待,等LCM講入工作狀態
  355.          LCD_Initial();         //LCD初始化

  356. //        while(1)
  357. //        {
  358. //                test_key();
  359. //        }

  360.         GotoXY(0,1);//日歷顯示固定符號從第一行第0個位置之后開始顯示
  361.         Print(name);//向液晶屏寫日歷顯示的固定符號部分
  362.         GotoXY(0,2);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
  363.         Print(start_line);//寫顯示時間固定符號,兩個冒號
  364.         GotoXY(9,2);        //設置光標位置
  365.         LCD_Write(LCD_COMMAND,0x0f);        //設置光標為閃爍

  366. //        while(1);

  367.          P3=0xFF;
  368.         timer_init();



  369.          Delay5Ms(); //延時片刻(可不要)
  370.         N=0;                                                                                                                //初始化數據輸入位數
  371.          while(1)
  372.          {
  373.         if (!TR0)
  374.                 {
  375.                     KEY_SCAN=keynum();
  376.                 }
  377.         else
  378.                 {
  379.             KEY_SCAN = 0xff;
  380.         }

  381.                 if(KEY_SCAN!=0xff)
  382.                 {                                   
  383.                                         NUM=coding(KEY_SCAN);
  384.                                         switch(NUM)
  385.                                         {
  386.                                                 case 'A':         ;                                         break;
  387.                                                 case 'B':        ;                                     break;
  388.                                                 case 'C':         ;                                         break;
  389.                                                 case 'D':         ;                                        break;   
  390.                                                 case '*': Cancel();                                break;      //取消當前輸入
  391.                                                 case '#': Ensure();                         break;           //確認鍵,
  392.                                                 default:
  393.                                                 {        
  394.                                                         if(N<6)                                                           //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
  395.                                                         {                          unsigned        char temp;
  396.                                                                 OneAlam();                                                                //按鍵提示音                                                
  397.                                                                  
  398.                                                                
  399.                                                                                  for(j=N;j<=N;j++)
  400.                                                                 {
  401.                                                                         GotoXY(9+j,2);
  402.                                                                         LCD_Write(LCD_DATA,'*');
  403.                                                                 }
  404.                                                                                                    if(K1==0)
  405.                                                                                                    {
  406.                                                                                                    GotoXY(9+N,2);
  407.                                                                         temp=NUM+0x30           ;
  408.                                                                         LCD_Write(LCD_DATA,temp);
  409.                                                                                                   
  410.                                                                 }
  411.                                                                 InputData[N]=NUM;                                                                  
  412.                                                                 N++;
  413.                                                         }
  414.                                                         else                                                                                //輸入數據位數大于6后,忽略輸入
  415.                                                         {
  416.                                                                 N=6;
  417.                                                                  
  418.                                                         }
  419.                             break;
  420.                                                 }
  421.                                         }
  422.                         }
  423.         }
  424. }

  425. //*********************************中斷服務函數**************************************
  426. void  time0_int(void) interrupt 1
  427. {
  428.          TL0=0xB0;
  429.          TH0=0x3C;
  430.          countt0++;
  431.           if(countt0==20)
  432.            {
  433.                 countt0=0;
  434.                 second++;
  435.                 if(second==10)
  436.                 {
  437.                                 P3=0xf0;
  438.                                 TL0=0xB0;
  439.                                  TH0=0x3C;
  440.                                 second=0;
  441.                                 ErrorCont=0;                        //密碼錯誤輸入次數清零
  442.         GotoXY(0,2);
  443.                                 Print(start_line);
  444.         TR0=0;                                //關定時器
  445.                 }
  446.                         
  447.            }
  448. }
復制代碼

回復

使用道具 舉報

ID:213173 發表于 2018-5-2 20:23 | 顯示全部樓層
可以設一個標志,為0所有字符顯示“*”,為1所有字符正常顯示,這個標志由按鈕A控制。
回復

使用道具 舉報

ID:289777 發表于 2018-5-2 21:50 | 顯示全部樓層
跪求解答
回復

使用道具 舉報

ID:198543 發表于 2018-5-3 09:10 | 顯示全部樓層
設定一個顯示緩存區,保存輸入接收的密碼,當檢測到按鈕A按下時,調用顯示緩存區的值,否則顯示“*”
回復

使用道具 舉報

ID:289777 發表于 2018-5-3 14:04 | 顯示全部樓層
wulin 發表于 2018-5-2 20:23
可以設一個標志,為0所有字符顯示“*”,為1所有字符正常顯示,這個標志由按鈕A控制。

具體如何設定呢,能寫一下嗎?在線等,拜托了
回復

使用道具 舉報

ID:289777 發表于 2018-5-3 14:04 | 顯示全部樓層
nbhmwj 發表于 2018-5-3 09:10
設定一個顯示緩存區,保存輸入接收的密碼,當檢測到按鈕A按下時,調用顯示緩存區的值,否則顯示“*”

具體如何設定呢,能寫一下嗎?在線等,拜托了
回復

使用道具 舉報

ID:213173 發表于 2018-5-3 15:49 | 顯示全部樓層
無標題2.jpg 無標題3.jpg
示例代碼
#include<reg51.h>
#define led P0
#define LED P2
sbit K1=P2^4;
unsigned int i=0,j=0;
unsigned char k=0,s=0;
bit sign=0;
unsigned char code LedChar[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char code LedArr[]={0,1,2,3,4,5,6,7};
unsigned char LedBuff[9]={0,0,0,0,0,0,0,0,0x40};
void keyscan()                                        //按鍵掃描程序
{
        static bit key_sign=0;        //按鍵自鎖標志
        static unsigned int count=0;//計數變量                       
        if(!K1)                                        //檢測按鍵如果為0
        {
                count++;                                        //消抖計數
                if((count>=100)&&(key_sign==0))
                {                       
                        key_sign=1;                        //按鍵自鎖標志置1
                        sign=~sign;                        //顯示標志取反
                }
        }
        else                                                        //按鍵抬起
        {
                key_sign=0;                                //按鍵自鎖標志清0
                count=0;                                        //消抖計數清0
        }
}
void main()
{
        TMOD=0x01;
        TH0=0xb1;
        TL0=0xe0;
        TR0=1;
        while(1)
        {
                if(TF0==1)
                {
                        TF0=0;
                        TH0=0xb1;
                        TL0=0xe0;
                        s++;
                }
                if(s>=50)
                {
                        s=0;
                        i++;
                        if(i>9999)
                        {
                                i=0;
                                j++;
                                if(j>9999)
                                        j=0;
                        }
                }
/************數據分解到緩存************/
                LedBuff[0]=LedChar[j/1000];
                LedBuff[1]=LedChar[j%1000/100];
                LedBuff[2]=LedChar[j%100/10];       
                LedBuff[3]=LedChar[j%10];
                LedBuff[4]=LedChar[i/1000];
                LedBuff[5]=LedChar[i%1000/100];
                LedBuff[6]=LedChar[i%100/10];
                LedBuff[7]=LedChar[i%10];

                keyscan();//調用按鍵程序
/************8位數碼管顯示************/
                led=0x00;                        //消隱
                LED&=0xF8;                        //清除P2低3位,保留高5位狀態不變
                LED|=LedArr[k];        //送位碼
                if(sign==1)
                        led=LedBuff[8];        //送段碼*
                else
                        led=LedBuff[k];        //送段碼
                k++;
                if(k>=8)
                        k=0;
        }
}


回復

使用道具 舉報

ID:289777 發表于 2018-5-3 17:36 | 顯示全部樓層
感謝上面那位大佬的指點,但是他的歷程顯示屏和我的這道題顯示不大一樣啊
請問我的如何改呢,有沒有人會,拜托
回復

使用道具 舉報

ID:19715 發表于 2018-5-3 18:11 | 顯示全部樓層
主程序里面的switch(NUM)不能相應按鈕A,只有12個按鍵有按下才能執行switch(NUM)
回復

使用道具 舉報

ID:213173 發表于 2018-5-4 16:38 | 顯示全部樓層
本帖最后由 wulin 于 2018-5-6 16:53 編輯
haohaoxue51 發表于 2018-5-3 14:04
具體如何設定呢,能寫一下嗎?在線等,拜托了

你這程序框架有缺陷,K1功能只能在矩陣鍵盤功能內有效。目前只能單獨寫一個按鍵程序放在主循環中,刷新LCD顯示內容。 無標題.jpg



回復

使用道具 舉報

ID:289777 發表于 2018-5-6 14:17 | 顯示全部樓層
wulin 發表于 2018-5-4 16:38
你這程序框架有缺陷,K1功能只能在矩陣鍵盤功能內有效。

不行啊,帖子里沒有你的截圖。你發的這個改正程序我也試了,沒效果啊,K1按下后,在按鍵盤啥都不顯示,我的目的是輸入完密碼,它不是顯示*號嗎,按下K1后,所有*變為對應的數字
回復

使用道具 舉報

ID:213173 發表于 2018-5-6 17:15 | 顯示全部樓層
haohaoxue51 發表于 2018-5-6 14:17
不行啊,帖子里沒有你的截圖。你發的這個改正程序我也試了,沒效果啊,K1按下后,在按鍵盤啥都不顯示,我 ...

這是改過的程序
  1. #include <REG52.h>
  2. #include<intrins.h>
  3. sbit K1=P1^2;
  4. sbit ALAM = P2^5;                                                                                                //報警        
  5. sbit open_led=P2^3;                                                                                                //開鎖指示燈        
  6. /*LCD接口定義*/
  7. sbit LcdRS   = P2^0;                                                                                      //lcd數據/命令選擇端  數據1命令0
  8. sbit LcdRW   = P2^1;                                                                                      //lcd讀/寫選擇端    讀1寫0
  9. sbit LcdEn   = P2^2;                                                                                      //lcd使能控制端  1有效
  10. sfr  LcdIO   = 0x80;                                                                                      //lcd數據接口 P0=0x80

  11. unsigned char code a[]={0xFE,0xFD,0xFB,0xF7};                                         //控盤掃描控制表
  12.                
  13. unsigned char countt0,second;                                                                        //t0中斷計數器,秒計數器
  14. unsigned char code start_line[]        = {"password:       "};
  15. unsigned char code name[]                  = {"===Coded Lock==="};                     //顯示名稱                 
  16. unsigned char code Error[]           = {"      error     "};                  //輸入錯誤
  17. unsigned char code codepass[]        = {"      pass      "};
  18. unsigned char code LockOpen[]        = {"      open      "};                        //OPEN

  19. char InputData[6];                                                                                                //輸入密碼暫存區
  20. unsigned char CurrentPassword[6]={6,5,4,3,2,1};                                 //當前密碼值
  21. unsigned char N=0;                                                                                                //密碼輸入位數記數
  22. unsigned char ErrorCont;                                                                                //錯誤次數計數
  23. unsigned char KEY_SCAN,NUM;

  24. /****向LCD寫入命令或數據部分****/
  25. #define LCD_COMMAND         0         // 輸出指令
  26. #define LCD_DATA            1         // 輸出數據
  27. #define LCD_CLEAR_SCREEN    0x01      // 清屏指令
  28. #define LCD_HOME            0x02      // 光標返回原點指令

  29. //=====================16us短延時==============================
  30. void Delay_short(unsigned int n)
  31. {
  32.          unsigned int i;
  33.          for(i=0;i<n;i++)     
  34.          {;}
  35. }
  36. //=====================長延時==============================
  37. void Delay_long(unsigned char N)
  38. {
  39.         unsigned char i;
  40.           unsigned int j;
  41.            for(i=0;i<N;i++)
  42.            {
  43.                 for(j=0;j<315;j++)  //一個循環16us,共5ms
  44.               {;}
  45.    }
  46. }
  47. //=====================5ms延時==============================
  48. void Delay5Ms(void)
  49. {
  50.         unsigned int TempCyc = 5552;
  51.         while(TempCyc--);
  52. }
  53. //===================400ms延時==============================
  54. void Delay400Ms(void)
  55. {
  56.          unsigned char TempCycA = 5;
  57.          unsigned int TempCycB;
  58.          while(TempCycA--)
  59.          {
  60.                   TempCycB=7269;
  61.                   while(TempCycB--);
  62.          }
  63. }

  64. /*寫LCD子程序                                          */
  65. /*入口參數:數據style=1 指令, style=0 input:寫入的內容*/

  66. void LCD_Write(bit style, unsigned char input)  
  67. {
  68.     LcdRS=style;         //數據style=1  指令style=0
  69.     LcdRW=0;             //寫
  70.     LcdIO=input;         //P0口輸出
  71.     Delay_short(10);     //延時
  72.     LcdEn=1;             //lcd使能
  73.     Delay_short(10);     //延時
  74.     LcdEn=0;             //停止
  75. }

  76. /****初始化LCD程序****/
  77. void LCD_Initial()
  78. {
  79.     Delay_long(6);                                     //延遲5*6=30ms
  80.     LCD_Write(LCD_COMMAND,0x38);                       //8位數據端口,2行顯示,5*7點陣
  81.     LCD_Write(LCD_COMMAND,0x38);
  82.     LCD_Write(LCD_COMMAND,0x38);                       //發送三遍
  83.     Delay_short(2);                                    //延遲大于39us
  84.     LCD_Write(LCD_COMMAND,0x0c);                            //顯示模式設置:開啟顯示, 無光標 0x0c
  85.     Delay_short(2);                             //延遲大于39us
  86.     LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);           //清屏                          0x01
  87.     Delay_short(100);                           //延遲大于1.53ms
  88.     LCD_Write(LCD_COMMAND,0x06);                               //輸入模式設置:AC遞增, 畫面不動 0x06
  89. }


  90. /*液晶字符輸入的位置定位程序*/
  91. /*入口參數:x范圍:0-15     y范圍:1,2*/
  92. void GotoXY(unsigned char x, unsigned char y)  
  93. {
  94.     unsigned char address;
  95.     if(y==1)
  96.         {
  97.         address=0x80+x;         //y=1顯示在第一行
  98.     }
  99.         else
  100.         {
  101.         address=0xc0+x;      //y=2顯示在第二行
  102.     }
  103.         LCD_Write(LCD_COMMAND, address);
  104. }

  105. /*將字符串輸出到液晶顯示函數*/
  106. /*入口參數:字符串指針      */
  107. void Print(unsigned char *str)
  108. {
  109.     while(*str!='\0')
  110.     {
  111.         LCD_Write(LCD_DATA,*str);
  112.         str++;
  113.     }
  114. }
  115. //*********************************************************************
  116. //==============將按鍵值編碼為數值=========================
  117. unsigned char coding(unsigned char m)         
  118. {
  119.         unsigned char k;
  120.         switch(m)
  121.         {
  122. //                case (0x18): k=3;break;
  123. //                case (0x28): k=7;break;
  124. //                case (0x48): k='#';break;
  125. //                case (0x88): k='D';break;
  126.                 case (0x14): k=3;break;
  127.                 case (0x24): k=6;break;
  128.                 case (0x44): k=9;break;
  129.                 case (0x84): k='#';break;
  130.                 case (0x12): k=2;break;
  131.                 case (0x22): k=5;break;
  132.                 case (0x42): k=8;break;
  133.                 case (0x82): k=0;break;
  134.                 case (0x11): k=1;break;
  135.                 case (0x21): k=4;break;
  136.                 case (0x41): k=7;break;
  137.                 case (0x81): k='*';break;
  138.         }
  139.         return(k);
  140. }
  141. //=====================按鍵檢測并返回按鍵值===============================
  142. unsigned char keynum(void)
  143. {
  144.          unsigned char row,col,i;
  145.          P3=0xf0;
  146.          if((P3&0xf0)!=0xf0)
  147.          {
  148.                    Delay5Ms();
  149.               Delay5Ms();
  150.                    if((P3&0xf0)!=0xf0)
  151.                 {
  152.                     row=P3^0xf0;          //確定行線
  153.                         i=0;
  154.                         P3=a[i];                  //精確定位
  155.                         while(i<4)
  156.                         {
  157.                                  if((P3&0xf0)!=0xf0)
  158.                                   {
  159.                                            col=~(P3&0xff);          //確定列線
  160.                                            break;            //已定位后提前退出   
  161.                                   }
  162.                                 else
  163.                                   {
  164.                                            i++;
  165.                                            P3=a[i];
  166.                                   }
  167.                         }
  168.                 }
  169.                 else
  170.                 {                 
  171.                         return 0xff;        
  172.                 }
  173.                 while((P3&0xf0)!=0xf0);
  174.                 return (row|col);                         //行線與列線組合后返回
  175.          }
  176.          else
  177.         {
  178.                 return 0xff;                                 //無鍵按下時返回0xff
  179.         }
  180. }
  181. //***************************************************************************************/
  182. //=======================一聲提示音,表示有效輸入========================
  183. void OneAlam(void)
  184. {
  185.         unsigned char y;
  186.         for(y=0;y<30;y++)
  187.         {
  188.         ALAM=0;
  189.         Delay_short(50);
  190.           ALAM=1;
  191.         Delay_short(50);
  192.         }

  193. }

  194. //========================二聲提示音,表示操作成功========================
  195. void TwoAlam(void)
  196. {
  197.         OneAlam();
  198.         Delay5Ms();
  199.     ALAM=1;
  200.           Delay5Ms();
  201.         OneAlam();
  202.         Delay5Ms();
  203.     ALAM=1;
  204. }
  205. //========================三聲提示音,表示錯誤========================
  206. void ThreeAlam(void)
  207. {
  208.         OneAlam();
  209.         Delay5Ms();
  210.     ALAM=1;
  211.         Delay5Ms();
  212.         OneAlam();
  213.         Delay5Ms();
  214.     ALAM=1;
  215.           Delay5Ms();
  216.         OneAlam();
  217.         Delay5Ms();
  218.     ALAM=1;
  219. }
  220. //=======================輸入密碼錯誤超過三過,報警并鎖死鍵盤======================
  221. void Alam_KeyUnable(void)
  222. {
  223.         P3=0x00;
  224.         {
  225.                 OneAlam();
  226.                 Delay5Ms();
  227.             ALAM=1;
  228.                 Delay5Ms();
  229.         }
  230. }
  231. //=======================取消所有操作============================================
  232. void Cancel(void)
  233. {        
  234.         unsigned char i;
  235.         GotoXY(0,2);
  236.         Print(start_line);        
  237.         TwoAlam();                                //提示音
  238.         for(i=0;i<6;i++)
  239.         {
  240.                 InputData[i]=0;
  241.         }
  242.         ALAM=1;                                        //報警關
  243.         ErrorCont=0;                        //密碼錯誤輸入次數清零
  244.         open_led=1;                                  //指示燈關閉
  245.         N=0;                                        //輸入位數計數器清零
  246. }
  247. //==========================確認鍵,并通過相應標志位執行相應功能===============================
  248. void Ensure(void)
  249. {        
  250.         unsigned char i,j;
  251.         for(i=0;i<6;)
  252.         {                                       
  253.                 if(CurrentPassword[i]==InputData[i])
  254.                 {
  255.                         i++;
  256.                 }
  257.                 else
  258.                 {                        
  259.                         ErrorCont++;
  260.                         if(ErrorCont==3)                        //錯誤輸入計數達三次時,報警并鎖定鍵盤
  261.                         {
  262.                                 GotoXY(0,2);
  263.                                 Print("  KeypadLocked! ");
  264.                                 TR0=1;
  265.                                 do
  266.                                     Alam_KeyUnable();
  267.                                 while(TR0);
  268.                 return ;
  269.                         }
  270.             break;
  271.                 }
  272.         }

  273.         if(i==6)   //密碼正確輸入
  274.         {
  275.                         GotoXY(0,2);
  276.                         Print(codepass);
  277.                         Delay400Ms();
  278.                         Delay400Ms();
  279.                         GotoXY(0,2);
  280.                         Print(LockOpen);        
  281.                         TwoAlam();                                           //操作成功提示音
  282.                         //KEY_CLOCK=0;                                                                                        //開鎖
  283.                         //pass=1;                                                                                        //置正確標志位
  284.                         open_led=0;                                                                                //開鎖指示燈亮
  285.                         for(j=0;j<6;j++)                                                                //將輸入清除
  286.                         {
  287.                                 InputData[i]=0;
  288.                         }
  289.                         while(1);
  290.         }
  291.         else
  292.         {
  293.         GotoXY(0,2);
  294.                 Print(Error);        
  295.                  ThreeAlam();                                                                                //錯誤提示音
  296.         Delay400Ms();
  297.         GotoXY(0,2);
  298.                 Print(start_line);
  299.         for(j=0;j<6;j++)                                                                //將輸入清除
  300.                 {
  301.                         InputData[i]=0;
  302.                  }
  303.     }
  304.         N=0;                                                                                                        //將輸入數據計數器清零,為下一次輸入作準備
  305. }

  306. void test_led()
  307. {
  308.         while(1)
  309.         {
  310.                 open_led=0;
  311.                 Delay400Ms();
  312.                 open_led=1;
  313.                 Delay400Ms();
  314.         }
  315. }

  316. void test_alarm()
  317. {
  318.     while(1)
  319.         {
  320.                 ALAM=1;
  321.                 Delay_short(60);
  322.                 ALAM=0;
  323.                 Delay_short(60);
  324.         }
  325. }
  326. void timer_init()
  327. {
  328.         TMOD=0x11;
  329.          TL0=0xB0;
  330.          TH0=0x3C;
  331.          EA=1;
  332.          ET0=1;        
  333.          TR0=0;
  334. }

  335. void test_key()
  336. {
  337.         unsigned char code ascii[]={"0123456789ABCDEF"};
  338.         KEY_SCAN=keynum();
  339.         if(KEY_SCAN!=0xff)
  340.         {
  341.                 GotoXY(0,1);
  342.                 Print("key_code:0x");
  343.                 LCD_Write(LCD_DATA, ascii[KEY_SCAN/16]);
  344.                 LCD_Write(LCD_DATA, ascii[KEY_SCAN%16]);
  345.         }
  346. }
  347. void keyscan()                                        //按鍵掃描程序
  348. {
  349.         static bit key_sign=0;        //按鍵自鎖標志
  350.         static bit sign=0;
  351.         static unsigned char count=0;//計數變量                        
  352.         unsigned char i;
  353.         if(K1==0)                                        //檢測按鍵如果為0
  354.         {
  355.                 count++;                                        //消抖計數
  356.                 if((count>=250)&&(key_sign==0))
  357.                 {                        
  358.                         key_sign=1;                        //按鍵自鎖標志置1
  359.                         sign=~sign;
  360.                         if(sign==1)
  361.                         {
  362.                                 for(i=0;i<N;i++)
  363.                                 {
  364.                                         GotoXY(9+i,2);
  365.                                         LCD_Write(LCD_DATA,InputData[i]+0x30);
  366.                                 }
  367.                         }
  368.                         else
  369.                         {
  370.                                 for(i=0;i<N;i++)
  371.                                 {
  372.                                         GotoXY(9+i,2);
  373.                                         LCD_Write(LCD_DATA,'*');
  374.                                 }
  375.                         }
  376.                 }
  377.         }
  378.         else                                                        //按鍵抬起
  379.         {
  380.                 key_sign=0;                                //按鍵自鎖標志清0
  381.                 count=0;                                        //消抖計數清0
  382.         }
  383. }

  384. //==============================主函數===============================
  385. void main(void)
  386. {
  387.          
  388.         unsigned char j;
  389. //        test_led();
  390. //        test_alarm();
  391.          Delay400Ms();         //啟動等待,等LCM講入工作狀態
  392.          LCD_Initial();         //LCD初始化

  393. //        while(1)
  394. //        {
  395. //                test_key();
  396. //        }

  397.         GotoXY(0,1);//日歷顯示固定符號從第一行第0個位置之后開始顯示
  398.         Print(name);//向液晶屏寫日歷顯示的固定符號部分
  399.         GotoXY(0,2);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
  400.         Print(start_line);//寫顯示時間固定符號,兩個冒號
  401.         GotoXY(9,2);        //設置光標位置
  402.         LCD_Write(LCD_COMMAND,0x0f);        //設置光標為閃爍

  403. //        while(1);

  404.          P3=0xFF;
  405.         timer_init();



  406.          Delay5Ms(); //延時片刻(可不要)
  407.         N=0;                                                                                                                //初始化數據輸入位數
  408.          while(1)
  409.          {
  410.         if (!TR0)
  411.                 {
  412.                     KEY_SCAN=keynum();
  413.                 }
  414.         else
  415.                 {
  416.             KEY_SCAN = 0xff;
  417.         }

  418.                 if(KEY_SCAN!=0xff)
  419.                 {                                   
  420.                                         NUM=coding(KEY_SCAN);
  421.                                         switch(NUM)
  422.                                         {
  423.                                                 case 'A':         ;                                         break;
  424.                                                 case 'B':        ;                                     break;
  425.                                                 case 'C':         ;                                         break;
  426.                                                 case 'D':         ;                                        break;   
  427.                                                 case '*': Cancel();                                break;      //取消當前輸入
  428.                                                 case '#': Ensure();                         break;           //確認鍵,
  429.                                                 default:
  430.                                                 {        
  431.                                                         if(N<6)                                                           //當輸入的密碼少于6位時,接受輸入并保存,大于6位時則無效。
  432.                                                         {
  433. //                                                                  unsigned        char temp;
  434.                                                                 OneAlam();                                                                //按鍵提示音                                                
  435.                                                                 for(j=N;j<=N;j++)
  436.                                                                 {
  437.                                                                         GotoXY(9+j,2);
  438.                                                                         LCD_Write(LCD_DATA,'*');
  439.                                                                 }
  440. /*                                                           if(K1==0)
  441.                                                            {
  442.                                                                         GotoXY(9+N,2);
  443.                                                                         temp=NUM+0x30           ;
  444.                                                                         LCD_Write(LCD_DATA,temp);
  445.                                                                                                   
  446.                                                                 }*/
  447.                                                                 InputData[N]=NUM;
  448.                                                                 N++;
  449.                                                         }
  450.                                                         else                                                                                //輸入數據位數大于6后,忽略輸入
  451.                                                         {
  452.                                                                 N=6;
  453.                                                                  
  454.                                                         }
  455.                             break;
  456.                                                 }
  457.                                         }
  458.                         }
  459.                 keyscan();
  460.         }
  461. }

  462. //*********************************中斷服務函數**************************************
  463. void  time0_int(void) interrupt 1
  464. {
  465.          TL0=0xB0;
  466.          TH0=0x3C;
  467.          countt0++;
  468.           if(countt0==20)
  469.            {
  470.                 countt0=0;
  471.                 second++;
  472.                 if(second==10)
  473.                 {
  474.                                 P3=0xf0;
  475.                                 TL0=0xB0;
  476.                                  TH0=0x3C;
  477.                                 second=0;
  478.                                 ErrorCont=0;                        //密碼錯誤輸入次數清零
  479.         GotoXY(0,2);
  480.                                 Print(start_line);
  481.         TR0=0;                                //關定時器
  482.                 }
  483.                         
  484.            }
  485. }
復制代碼

回復

使用道具 舉報

ID:289777 發表于 2018-5-14 22:18 | 顯示全部樓層
wulin 發表于 2018-5-6 17:15
這是改過的程序

十分感謝
回復

使用道具 舉報

ID:329641 發表于 2018-5-14 22:41 | 顯示全部樓層
是不是定時器沒設定好?
回復

使用道具 舉報

ID:324844 發表于 2020-5-3 22:49 | 顯示全部樓層
我有一個問題,那個延時函數是怎么回事兒啊,如果認為125是1ms,短延時只有8us,長延時是2.5ms,他的5ms延時有44ms,他的400ms延時是290ms,看不懂求問
回復

使用道具 舉報

ID:420836 發表于 2020-5-4 00:41 | 顯示全部樓層
謝謝您的幫助! 我學到很多
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产视频欧美 | 免费一级欧美在线观看视频 | 免费看黄色小视频 | 一区二区三区四区在线视频 | 国产精品久久久久久久久久久免费看 | 日韩欧美在线免费 | 精品欧美一区二区三区久久久 | 亚洲精品久久久一区二区三区 | 国产成人精品免费视频大全最热 | 波多野结衣一区二区 | 国产一级电影在线 | 亚洲精品久久久久久国产精华液 | 日韩在线免费 | 亚av在线| 国产成人久久av免费高清密臂 | 啪啪免费网 | 日本字幕在线观看 | 国产精品成人一区二区三区夜夜夜 | 欧美视频一区二区三区 | 成年无码av片在线 | 国产成人午夜精品影院游乐网 | 国产午夜视频 | 亚洲福利在线观看 | 91成人在线视频 | 91日韩在线 | 国产成人精品一区二区三区 | 精品成人 | 国内精品久久久久久 | 免费国产视频 | 蜜桃精品噜噜噜成人av | 又爽又黄axxx片免费观看 | 农村真人裸体丰满少妇毛片 | 日韩精品中文字幕在线 | 亚洲成人精品国产 | 欧美精品三区 | 麻豆视频在线免费观看 | 久久一区二区三区免费 | 亚洲一区二区中文字幕在线观看 | 97成人在线 | 久久久免费电影 | 精品区|