|
1. 能設(shè)定一組4位的數(shù)字開(kāi)啟密碼(設(shè)定密碼功能) 2. 用LED小燈代替鎖開(kāi)啟顯示,輸入密碼正確,則小燈亮起(開(kāi)鎖功能) 3. 如果3次密碼錯(cuò)誤,則進(jìn)行鳴叫報(bào)警,并在1分鐘之內(nèi)不能再次輸入(報(bào)警功能) 4. 密碼輸入顯示在數(shù)碼管上,輸入正確顯示on,輸入錯(cuò)誤顯示err(顯示功能) 5. 可在以上功能上擴(kuò)展。
整體要做的事情有: 1.初始化硬件 2.函數(shù)功能的實(shí)現(xiàn) 2.1按鍵掃描實(shí)現(xiàn) 2.2按鍵處理 2.3時(shí)間處理函數(shù)
設(shè)計(jì)思路為:先進(jìn)行各種變量的初始化,然后循環(huán)執(zhí)行三個(gè)子函數(shù),其中在初始化函數(shù)里打開(kāi)定時(shí)器,定時(shí)器裝載初值溢出時(shí)間為2ms,進(jìn)入中斷執(zhí)行一次數(shù)碼管顯示函數(shù),由于人眼的余暉效應(yīng),人眼看到的是8個(gè)數(shù)碼管持續(xù)同時(shí)亮,當(dāng)有按鍵按下時(shí)則會(huì)進(jìn)入按鍵掃描函數(shù),繼而得到鍵值進(jìn)入按鍵服務(wù)函數(shù),繼而進(jìn)入時(shí)間服務(wù)函數(shù),由于定時(shí)器每2ms顯示一次數(shù)碼管,所以有按鍵按下時(shí),可以及時(shí)的顯示按鍵對(duì)應(yīng)的操作。
總結(jié):做了一個(gè)簡(jiǎn)單的密碼鎖,主要的顯示功能是用過(guò)定時(shí)中斷進(jìn)行操作的,其余的函數(shù)都是為了服務(wù)中斷函數(shù)而設(shè)置的,對(duì)于最后的結(jié)果分析,達(dá)到了設(shè)計(jì)要求的基本功能,即設(shè)定密碼功能、開(kāi)鎖功能、報(bào)警功能、顯示功能。除此之外還增加了撤銷功能,關(guān)閉和打開(kāi)屏幕功能,確認(rèn)功能修改密碼功能以及其他小的細(xì)節(jié)功能。
單片機(jī)源程序如下:
- #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] =//共陰數(shù)碼管碼表
- {
- 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//-,關(guān),I,N,P,E,R
- };
- unsigned char dis_code[8] = 0;//顯示數(shù)組
- unsigned char dig_show_tmp = 0;//顯示臨時(shí)變量
- unsigned char now_window;//當(dāng)前顯示窗口
- #define inputpassword 10;//輸入密碼狀態(tài)
- unsigned char password_now[7]={2,2,3,4,5,6};//輸入當(dāng)前密碼保存數(shù)組
- unsigned char password[7]={1,2,3,1,2,3};//密碼保存
- signed char curr_bit;//輸入當(dāng)前位
- unsigned char curr_bit_tmp;//輸入當(dāng)前位備份
- unsigned char i;//臨時(shí)計(jì)數(shù)變量
- unsigned char cnt_50ms;//中斷50ms計(jì)數(shù)
- unsigned char time_50ms_flag;//50ms標(biāo)志
- unsigned char open_del;//開(kāi)鎖成功延時(shí)計(jì)數(shù)
- unsigned char open_flag;//鎖狀態(tài)標(biāo)志
- sbit relay = P1^0;//繼電器
- /*******************************************************************************
- * 函 數(shù) 名 : delay_ms
- * 函數(shù)功能 : 延時(shí)函數(shù),延時(shí)1ms
- * 輸 入 : cnt
- * 輸 出 : 無(wú)
- * 說(shuō) 名 : 該函數(shù)是在12MHZ晶振下,12分頻單片機(jī)的延時(shí)。
- *******************************************************************************/
- void delay_ms(unsigned int cnt) //
- {
- unsigned int x;
- for( ; cnt>0; cnt--)
- {
- for(x=110; x>0; x--);//軟件延時(shí)為1MS
- }
- }
- /******************************************************
- ** 函數(shù)名:time_init
- ** 描述 :定時(shí)器初始化
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void time_init(void)
- {
- TMOD |= 0x01;//time0 工作方式為1
- TH0 = 0xf8;//裝載初值
- TL0 = 0x2f;//裝載初值,為2ms(65535-63535)
- TR0 = 1;//開(kāi)啟定時(shí)器
- ET0 = 1;//打開(kāi)中斷
- EA=1;
- }
- /******************************************************
- ** 函數(shù)名:key_scan
- ** 描述 :按鍵掃描
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void key_scan(void)
- {
- static unsigned char key_in_flag = 0;//按鍵按下標(biāo)志
- unsigned char key_l,key_h;//存儲(chǔ)掃描到行列值。
- key_value = 20;//按鍵值清除
- P3 = 0xf0;
- if((P3 & 0xf0) != 0xf0)//按鍵按下
- {
- delay_ms(5);//按鍵消抖動(dòng)
- if(((P3 & 0xf0) != 0xf0) && (key_in_flag == 1))
- {
- key_in_flag = 0;//松手檢測(cè)防止一直觸發(fā)
- 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;//(按鍵松開(kāi)標(biāo)志)
- }
- }
- 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個(gè)數(shù)碼管后,重新從第一個(gè)開(kāi)始掃描
- {
- dis_step=1;
- }
- }
- /******************************************************
- ** 函數(shù)名:alm
- ** 描述 :定時(shí)閃爍函數(shù)
- ** 輸入 : 無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :中斷調(diào)用
- ******************************************************/
- void time_service(void)
- {
- if(time_50ms_flag)//50ms時(shí)間到標(biāo)志
- {
- time_50ms_flag = 0;//50ms時(shí)間到標(biāo)志清零
- if (relay==0)//開(kāi)鎖后延時(shí)關(guān)鎖
- {
- open_del++;
- if(open_del >= 20 * 5) //5秒
- {
- open_del = 0;
- relay = 1; //關(guān)閉密碼鎖
- 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)//輸入錯(cuò)誤顯示
- {
- open_del++;
- if(open_del >= 20 * 2)
- {
- open_del = 0;
- open_flag = 0;
- relay = 1; //關(guān)閉密碼鎖
- 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;
- }
- }
- }
- }
- /******************************************************
- ** 函數(shù)名:key_service
- ** 描述 :按鍵服務(wù)函數(shù)
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :主程序
- ******************************************************/
- 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://按下確認(rèn)鍵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//輸入錯(cuò)誤顯示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設(shè)置密碼
- {
- password[0] = 2;
- password[1] = 2;
- password[2] = 2;
- password[3] = 2;
- password[4] = 2;
- password[5] = 2;
- }
- break;
- case 11://B設(shè)置密碼
- {
- password[0] = 3;
- password[1] = 3;
- password[2] = 3;
- password[3] = 3;
- password[4] = 3;
- password[5] = 3;
- }
- break;
- case 12://C設(shè)置密碼
- {
- password[0] = 4;
- password[1] = 4;
- password[2] = 4;
- password[3] = 4;
- password[4] = 4;
- password[5] = 4;
- }
- break;
- }
- }
- /******************************************************
- ** 函數(shù)名:init_all_hardware
- ** 描述 :初始化所有硬件,及其變量參數(shù)。
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ** 調(diào)用 :主程序
- ******************************************************/
- void init_all_hardware(void)
- {
- delay_ms(100);
- time_init();//定時(shí)器初始化
- 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和定時(shí)器
- while(1)
- {
- key_scan();//按鍵掃描
- key_service();//按鍵服務(wù)處理函數(shù)
- time_service();//時(shí)間處理函數(shù)
- }
- }
- /******************************************************
- ** 函數(shù)名:time0_interrupt
- ** 描述 :按鍵掃描函數(shù)
- ** 輸入 :無(wú)
- ** 輸出 :無(wú)
- ******************************************************/
- void time0_interrupt() interrupt 1
- {
- TF0 = 0;//清除標(biāo)志
- TR0 = 0;
- dis_dri();//動(dòng)態(tài)掃描數(shù)碼管
- if (++cnt_50ms>25)
- {
- cnt_50ms = 0;
- time_50ms_flag = 1;
- }
- TR0 = 1;
- TH0 = 0xf8;
- TL0 = 0x2f;//裝載初值2ms(65535-63535)
- }
復(fù)制代碼
所有資料51hei提供下載:
密碼鎖代碼.rar
(31.78 KB, 下載次數(shù): 22)
2020-5-22 16:19 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|