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)
|