1. 能設定一組4位的數字開啟密碼(設定密碼功能) 2. 用LED小燈代替鎖開啟顯示,輸入密碼正確,則小燈亮起(開鎖功能) 3. 如果3次密碼錯誤,則進行鳴叫報警,并在1分鐘之內不能再次輸入(報警功能) 4. 密碼輸入顯示在數碼管上,輸入正確顯示on,輸入錯誤顯示err(顯示功能) 5. 可在以上功能上擴展。
整體要做的事情有: 1.初始化硬件 2.函數功能的實現 2.1按鍵掃描實現 2.2按鍵處理 2.3時間處理函數
設計思路為:先進行各種變量的初始化,然后循環執行三個子函數,其中在初始化函數里打開定時器,定時器裝載初值溢出時間為2ms,進入中斷執行一次數碼管顯示函數,由于人眼的余暉效應,人眼看到的是8個數碼管持續同時亮,當有按鍵按下時則會進入按鍵掃描函數,繼而得到鍵值進入按鍵服務函數,繼而進入時間服務函數,由于定時器每2ms顯示一次數碼管,所以有按鍵按下時,可以及時的顯示按鍵對應的操作。
總結:做了一個簡單的密碼鎖,主要的顯示功能是用過定時中斷進行操作的,其余的函數都是為了服務中斷函數而設置的,對于最后的結果分析,達到了設計要求的基本功能,即設定密碼功能、開鎖功能、報警功能、顯示功能。除此之外還增加了撤銷功能,關閉和打開屏幕功能,確認功能修改密碼功能以及其他小的細節功能。
單片機源程序如下:
- #include "reg52.H"
- #include "stdio.h"
- #include "intrins.h"
- unsigned char key_value;
- #define DIG_SEG P0//段選
- #define DIG_PLA P2//位選
- unsigned char code dig_tab[24] =//共陰數碼管碼表
- {
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0、1、2、3、4、5、6、7、
- 0x7f,0x6f,0x77,0x00,0x39,0x5e,0x79,0x71,//8、9、A、B、C、D、E、F、
- 0x40,0x00,0x30,0x37,0x73,0x79,0x70//-,關,I,N,P,E,R
- };
- unsigned char dis_code[8] = 0;//顯示數組
- unsigned char dig_show_tmp = 0;//顯示臨時變量
- unsigned char now_window;//當前顯示窗口
- #define inputpassword 10;//輸入密碼狀態
- unsigned char password_now[7]={2,2,3,4,5,6};//輸入當前密碼保存數組
- unsigned char password[7]={1,2,3,1,2,3};//密碼保存
- signed char curr_bit;//輸入當前位
- unsigned char curr_bit_tmp;//輸入當前位備份
- unsigned char i;//臨時計數變量
- unsigned char cnt_50ms;//中斷50ms計數
- unsigned char time_50ms_flag;//50ms標志
- unsigned char open_del;//開鎖成功延時計數
- unsigned char open_flag;//鎖狀態標志
- sbit relay = P1^0;//繼電器
- /*******************************************************************************
- * 函 數 名 : delay_ms
- * 函數功能 : 延時函數,延時1ms
- * 輸 入 : cnt
- * 輸 出 : 無
- * 說 名 : 該函數是在12MHZ晶振下,12分頻單片機的延時。
- *******************************************************************************/
- void delay_ms(unsigned int cnt) //
- {
- unsigned int x;
- for( ; cnt>0; cnt--)
- {
- for(x=110; x>0; x--);//軟件延時為1MS
- }
- }
- /******************************************************
- ** 函數名:time_init
- ** 描述 :定時器初始化
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void time_init(void)
- {
- TMOD |= 0x01;//time0 工作方式為1
- TH0 = 0xf8;//裝載初值
- TL0 = 0x2f;//裝載初值,為2ms(65535-63535)
- TR0 = 1;//開啟定時器
- ET0 = 1;//打開中斷
- EA=1;
- }
- /******************************************************
- ** 函數名:key_scan
- ** 描述 :按鍵掃描
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void key_scan(void)
- {
- static unsigned char key_in_flag = 0;//按鍵按下標志
- unsigned char key_l,key_h;//存儲掃描到行列值。
- key_value = 20;//按鍵值清除
- P3 = 0xf0;
- if((P3 & 0xf0) != 0xf0)//按鍵按下
- {
- delay_ms(5);//按鍵消抖動
- if(((P3 & 0xf0) != 0xf0) && (key_in_flag == 1))
- {
- key_in_flag = 0;//松手檢測防止一直觸發
- key_l = P3;//掃描得到行值
- P3 = 0x0f;
- key_h= P3;////掃描得到列值
- switch(key_l|key_h)
- {
- //獲取按鍵值
- case 0xee: key_value = 1;break;
- case 0xed: key_value = 2;break;
- case 0xeb: key_value = 3;break;
- case 0xe7: key_value = 10;break;
- case 0xde: key_value = 4;break;
- case 0xdd: key_value = 5;break;
- case 0xdb: key_value = 6;break;
- case 0xd7: key_value = 11;break;
- case 0xbe: key_value = 7;break;
- case 0xbd: key_value = 8;break;
- case 0xbb: key_value = 9;break;
- case 0xb7: key_value = 12;break;
- case 0x7e: key_value = 13;break;
- case 0x7d: key_value = 0;break;
- case 0x7b: key_value = 14;break;
- case 0x77: key_value = 15;break;
- }
- }
- }
- else
- {
- key_in_flag = 1;//(按鍵松開標志)
- }
- }
- void dis_dri(void)
- {
- static unsigned char dis_step = 1;
- DIG_SEG = 0x00;
- switch(dis_step)
- {
- case 1: //顯示第1位
- {
- dig_show_tmp=dig_tab[dis_code[0]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfe;
- }
- break;
- case 2: //顯示第2位
- {
- dig_show_tmp=dig_tab[dis_code[1]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfd;
- }
- break;
- case 3: //顯示第3位
- {
- dig_show_tmp=dig_tab[dis_code[2]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xfb;
- }
- break;
- case 4: //顯示第4位
- {
- dig_show_tmp=dig_tab[dis_code[3]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xf7;
- }
- break;
- case 5: //顯示第5位
- {
- dig_show_tmp=dig_tab[dis_code[4]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xef;
- }
- break;
- case 6: //顯示第6位
- {
- dig_show_tmp=dig_tab[dis_code[5]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xdf;
- }
- break;
- case 7: //顯示第7位
- {
- dig_show_tmp=dig_tab[dis_code[6]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0xbf;
- }
- break;
- case 8: //顯示第8位
- {
- dig_show_tmp=dig_tab[dis_code[7]];
- DIG_SEG = dig_show_tmp;
- DIG_PLA = 0x7f;
- }
- break;
- }
- dis_step++;
- if(dis_step>8) //掃描完8個數碼管后,重新從第一個開始掃描
- {
- dis_step=1;
- }
- }
- /******************************************************
- ** 函數名:alm
- ** 描述 :定時閃爍函數
- ** 輸入 : 無
- ** 輸出 :無
- ** 調用 :中斷調用
- ******************************************************/
- void time_service(void)
- {
- if(time_50ms_flag)//50ms時間到標志
- {
- time_50ms_flag = 0;//50ms時間到標志清零
- if (relay==0)//開鎖后延時關鎖
- {
- open_del++;
- if(open_del >= 20 * 5) //5秒
- {
- open_del = 0;
- relay = 1; //關閉密碼鎖
- dis_code[0] = 17;
- dis_code[1] = 17;
- dis_code[2] = 17;
- dis_code[3] = 17;
- dis_code[4] = 17;
- dis_code[5] = 17;
- dis_code[6] = 19;
- dis_code[7] = 18;
- }
- }
- if (open_flag)//輸入錯誤顯示
- {
- open_del++;
- if(open_del >= 20 * 2)
- {
- open_del = 0;
- open_flag = 0;
- relay = 1; //關閉密碼鎖
- dis_code[0] = 17;
- dis_code[1] = 17;
- dis_code[2] = 17;
- dis_code[3] = 17;
- dis_code[4] = 17;
- dis_code[5] = 17;
- dis_code[6] = 19;
- dis_code[7] = 18;
- }
- }
- }
- }
- /******************************************************
- ** 函數名:key_service
- ** 描述 :按鍵服務函數
- ** 輸入 :無
- ** 輸出 :無
- ** 調用 :主程序
- ******************************************************/
- void key_service(void)
- {
- switch (key_value)
- {
- case 1: case 2:case 3:
- case 4: case 5:case 6:
- case 7: case 8:case 9:case 0:
- {
- password_now[curr_bit] = key_value;
- if (++curr_bit>6)//輸入6位密碼
- {
- curr_bit = 6;
- }
- curr_bit_tmp = curr_bit;
- for(i=0;i<curr_bit_tmp;i++)//顯示
- dis_code[i] = 16;//顯示一桿
- }
- break;
- case 14://退格鍵#
- {
- password_now[curr_bit] = 20;
- if (--curr_bit<0)
- curr_bit = 0;
- dis_code[curr_bit] = 17;//不顯示
- }
- break;
- case 15://按下確認鍵D
- {
- if(
- password_now[0] == password[0]&&
- password_now[1] == password[1]&&
- password_now[2] == password[2]&&
- password_now[3] == password[3]&&
- password_now[4] == password[4]&&
- password_now[5] == password[5]
- )//密碼比較
- {
- dis_code[0] = 17;//輸入正確open
- dis_code[1] = 17;
- dis_code[2] = 19;
- dis_code[3] = 21;
- dis_code[4] = 20;
- dis_code[5] = 0;
- dis_code[6] = 17;
- dis_code[7] = 17;
- relay = 0;
- }
- else//輸入錯誤顯示ERR
- {
- dis_code[0] = 17;
- dis_code[1] = 17;
- dis_code[2] = 22;
- dis_code[3] = 22;
- dis_code[4] = 21;
- dis_code[5] = 17;
- dis_code[6] = 17;
- dis_code[7] = 17;
- open_flag = 1;
- }
- for(i = 0;i < 6;i++)
- {
- password_now[i] = 0;
- curr_bit = 0;
- curr_bit_tmp = 0;
- }
- }
- break;
- case 10://A設置密碼
- {
- password[0] = 2;
- password[1] = 2;
- password[2] = 2;
- password[3] = 2;
- password[4] = 2;
- password[5] = 2;
- }
- break;
- case 11://B設置密碼
- {
- password[0] = 3;
- password[1] = 3;
- password[2] = 3;
- password[3] = 3;
- password[4] = 3;
- password[5] = 3;
- }
- break;
- case 12://C設置密碼
- {
- password[0] = 4;
- password[1] = 4;
- password[2] = 4;
- password[3] = 4;
- password[4] = 4;
- password[5] = 4;
- }
- break;
- }
- }
- /******************************************************
- ** 函數名:init_all_hardware
- ** 描述 :初始化所有硬件,及其變量參數。
- ** 輸入 :無
- ** 輸出 :無
- ** 調用 :主程序
- ******************************************************/
- void init_all_hardware(void)
- {
- delay_ms(100);
- time_init();//定時器初始化
- key_value = 20;
- dis_code[0] = 17;
- dis_code[1] = 17;
- dis_code[2] = 17;
- dis_code[3] = 17;
- dis_code[4] = 17;
- dis_code[5] = 17;
- dis_code[6] = 19;
- dis_code[7] = 18;//顯示IN
- now_window = inputpassword;//跳入輸入密碼
- cnt_50ms = 0;
- time_50ms_flag = 0;
- open_del = 0;
- relay = 1;
- curr_bit = 0;
- open_flag = 0;
- }
- void main(void)
- {
- init_all_hardware();//初始化硬件,IO和定時器
- while(1)
- {
- key_scan();//按鍵掃描
- key_service();//按鍵服務處理函數
- time_service();//時間處理函數
- }
- }
- /******************************************************
- ** 函數名:time0_interrupt
- ** 描述 :按鍵掃描函數
- ** 輸入 :無
- ** 輸出 :無
- ******************************************************/
- void time0_interrupt() interrupt 1
- {
- TF0 = 0;//清除標志
- TR0 = 0;
- dis_dri();//動態掃描數碼管
- if (++cnt_50ms>25)
- {
- cnt_50ms = 0;
- time_50ms_flag = 1;
- }
- TR0 = 1;
- TH0 = 0xf8;
- TL0 = 0x2f;//裝載初值2ms(65535-63535)
- }
復制代碼
所有資料51hei提供下載:
密碼鎖代碼.rar
(31.78 KB, 下載次數: 22)
2020-5-22 16:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|