定時中斷法實現1ms定時掃描,主程序執行按鍵識別矩陣鍵盤接在P0口,八位一體數顯的位控由P2口完成經過三極管方向驅動共陽級,P1口通過245驅動段碼,在仿真圖里面用反相器4069替代三極管驅動
單片機源程序如下:
- #include<reg51.h>
- sbit SPEAK=P3^7;
- sbit LED_RED=P3^6; // 紅色LED點亮表示密碼錯誤
- sbit LED_GREEN=P3^5;// 綠色LED點亮表示密碼正確
- bit flag=0; // 標志位
- unsigned char data buffer[8]={0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF}; //緩存器存放輸入的密碼,初始"-"
- unsigned char data keycode[8]={1,2,3,4,5,6,7,8}; // 原始密碼
- unsigned char code led[]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
- 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E };//共陽數顯段碼
- void delay(unsigned int i) // 延時
- {
- unsigned int k;
- for(k=0;k<i;k++);
- }
- // 1毫秒中斷,8位一體數顯掃描輸出顯示函數
- unsigned char wei=0x01,j=0;
- void timer_0 ()interrupt 1
- {
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- P1=0XFF;
- if(buffer[j]==0xBF)P1=0XBF; // 若顯示"-",則直接輸出不查表
- else if(buffer[j]==0xff)P1=0Xff; // 此處為密碼輸入時設置的消隱信號
- else P1=led[buffer[j]]; // 若顯示數字,則根據號碼查表
- P2=~(wei<<j);
- j++;
- if(j==8){j=0; wei=0x01;}
- }
- //鍵盤掃描函數 具有返回值
- char key_scan()
- {
- unsigned char i,temp,m,n;
- bit find=0;
- P0=0x0f; // 向所有列線輸出高電平
- i=P0;
- i&=0x0f; // 屏蔽高四位,取行信號
- if(i!=0x0f) //判斷是否有按鍵按下
- {
- delay(120);
- i=P0;
- i&=0x0f;
- if(i!=0x0f)
- {
- for(i=0;i<4;i++) //逐列判斷
- {
- P0=~(0x10<<i); // 列輸出低電位,如果有按鍵按下則對應讀入的數據為低電平
- temp=~P0;
- temp=temp&0x0f; // 屏蔽高四位讀行值,若有按鍵按下,則取反后出現高電平
- if(temp!=0)
- {
- m=i;
- find=1;
- switch(temp)
- {
- case 0x01:n=0;break;
- case 0x02:n=1;break;
- case 0x04:n=2;break;
- case 0x08:n=3;break;
- default:break;
- }
- break;
- }
- }
- }
- }
- if(find==0)return -1;
- else return(n*4+m);
- }
- // 8位密碼輸入函數
- void key_num()
- {
- unsigned char key,i,m,n=0;
- while(1) // 此方法可以檢測排除非0-9號按鍵
- {
- key=key_scan();
- if(key==-1)continue;
- else if(key>=0&&key<=9)
- {
- for(m=8;m>0;m--)
- buffer[m]=buffer[m-1]; // 為了達到號碼移位輸入的效果,采用后一個寫入前一個地址的方法
- buffer[0]=key; // 新輸入的號碼永遠放在第0個位置
- P0=0X0F;
- while(P0!=0X0F); // 按鍵彈起檢測
- n++;
- }
-
- if(n==8){n=0;break;}
- }
-
- for(i=0;i<8;i++) // 8位密碼與原始密碼進行比對,完全一致的時候標志位置1
- {
- if(buffer[i]!=keycode[7-i]) // 此處由于輸入密碼移位,所以逆取
- {
- flag=0; // 一旦出現密碼比對不正確,立刻終止比對,并標志位置0
- break;
- }
- else flag=1;
- }
- }
- // 重設密碼函數
- void key_reset()
- {
- unsigned char key,i,n=0;
- LED_GREEN=0; // 紅綠均點亮,表示重設密碼
- LED_RED=0;
- while(1)
- {
- key=key_scan();
- if(key==-1)continue;
- else if(key!=-1)
- {
- if(key>=0&&key<=9)
- {
- keycode[n]=key;
- buffer[n]=0xff; // 密碼輸入的時候,顯示器消隱
- P0=0X0F; // 鍵盤重新讀入行數據
- while(P0!=0x0f); // 如果行數據未出現低電平,表明按鍵全部彈起,此處一定要做按鍵彈起檢測,否則多次加載數據
- n++;
- }
- }
- if(n==8){n=0;break;}
- }
- while(1)
- {
- key=key_scan();
- P0=0X0F; // 鍵盤重新讀入行數據
- while(P0!=0x0f);
- if(key==11)break; // 11按鍵按下退出
- }
- LED_GREEN=1; // 紅綠均滅,表示重設密碼結束,可以輸入密碼打開密碼鎖
- LED_RED=1;
- for(i=0;i<8;i++) // 緩存區域數據全部清除,用"-"替代
- {
- buffer[i]=0xBF;
- }
- }
- // 輸入密碼結果函數
- unsigned char k=0;
- void key_result() // 密碼輸入結果顯示,正確時蜂鳴器響綠色LED點亮,密碼錯誤,紅色LED點亮
- {
- unsigned char key,i;
- if(flag==0)
- {
- k++;
- if(k!=3) //密碼輸入未達到三次,可繼續輸入
- { LED_RED=0;
- LED_GREEN=1;
- delay(50000);
- for(i=0;i<8;i++) // 緩存區域數據全部清除,用"-"替代
- {
- buffer[i]=0xBF;
- }
- }
- else // 密碼錯誤為三次,鎖定,11號按鍵解鎖
- {
- k=0;
- while(1)
- {
- key=key_scan();
- P0=0X0F; // 鍵盤重新讀入行數據
- while(P0!=0x0f);
- LED_RED=~LED_RED; //紅綠LED閃爍蜂鳴器鳴響報警
- LED_GREEN=~LED_GREEN;
- SPEAK=~SPEAK;
- delay(1000);
- if(key==11)
- {
- LED_GREEN=1;
- LED_RED=1;
- SPEAK=1;
- break; // 11按鍵按下退出
- }
- }
- for(i=0;i<8;i++) // 緩存區域數據全部清除,用"-"替代
- {
- buffer[i]=0xBF;
- }
- }
- }
-
- else // 密碼輸入正確可重置密碼或直接退出
- {
- LED_GREEN=0;
- LED_RED=1;
- SPEAK=0;
- delay(50000);
- SPEAK=1;
- k=0; // 密碼錯誤次數也要清零,否則會出現密碼正確但不重設退出后兩次密碼錯誤就報警
- flag=0;// 標志位清零
- for(i=0;i<8;i++) // 緩存區域數據全部清除,用"-"替代
- {
- buffer[i]=0xBF;
- }
-
- while(1)
- {
- key=key_scan();
- P0=0X0F; // 鍵盤重新讀入行數據
- while(P0!=0x0f); // 等待按鍵彈起
- if(key==10) {key_reset();break;} // 按下10號鍵,重設密碼
- else if(key==11){LED_RED=1;LED_GREEN=1;break;} // 11號按鍵按下退出,其他按鍵無效
- continue; //此處為了防止其他按鍵的按下而設置
- }
- }
- }
- void main()
- {
- TMOD=0X01;// 初始化,開啟1毫秒定時器中斷
- ET0=1;
- EA=1;
- TH0=(65536-1000)/256;
- TL0=(65536-1000)%256;
- TR0=1;
- LED_RED=1;
- LED_GREEN=1;
- SPEAK=1;
-
- while(1)
- {
- key_num();
- key_result();
- }
- }
復制代碼
下載:
八位數碼管密碼鎖.zip
(83.68 KB, 下載次數: 92)
2020-8-16 11:38 上傳
點擊文件名下載附件
|