|
- //程序:ex4_12.c
- //功能:一位数码管显示的密码锁,假定密码为8,可以输入的数字有0~9 ,A~F
- #include <reg51.h> //包含头文件reg51.h,定义51单片机的专用寄存器
- char scan_key (void); //键盘扫描函数
- void delay (unsigned int i); //延时函数声明
- sbit P30=P3^0; //位定义,控制发光二极管,其亮灭表示锁的打开和锁定状态
- void main() //主函数
- {
- unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e}; //0~9、A~F的共阳极显示码
- unsigned char led1[]={0xbf,0x8c,0x86}; //" "、"P"和"E"的共阳极显示码
- unsigned char i;
- P1=led1[0]; //数码管显示" "
- P30=1; //开锁指示灯关闭
- P0=0xff; //P0口低四位做输入口,先输出全1
- while(1)
- {
- i=scan_key(); //调用键盘函数
- if(i==-1)
- continue; //没有键按下,继续循环
- else if(i!=8){ //按键不是密码8
- P1=led[i]; //显示按下键的数字号
- delay(50000); //延时
- P1=led1[2]; //显示E
- delay(50000); //延时
- P1=led1[0]; //显示" "
- }
- else //按键是密码8
- {
- P1=led[i]; //显示按下键的数字号
- delay(50000); //延时
- P1=led1[1]; //显示P
- P30=0; //开锁
- delay(50000); //延时
- P1=led1[0]; //数码管显示" "
- P30=1; //开锁指示灯关闭
- }
- }
- }
- //函数名:scan_key
- //函数功能:判断是否有键按下,如果有键按下,逐列扫描法得到键值
- //形式参数:无
- //返回值:键值0~15,-1表示无键按下
- char scan_key ( )
- {
- char i, temp,m,n;
- bit find=0; //有键按下标志位
- P2=0xf0; //向所有的列线上输出低电平
- i=P0; //读入行值
- i&=0x0f; //屏蔽掉高四位
- if(i!=0x0f) //行值不为全1,有键按下
- {
- delay(1200); //延时消抖
- i=P0; //再次读入行值
- i&=0x0f; //屏蔽掉高四位
- if(i!=0x0f)
- { //第二次判断有键按下
- for(i=0;i<4;i++)
- {
- P2=0xfe<<i; //逐列送出低电平
- temp=~P0; //读行值,并取反,全1→全0
- temp=temp&0x0f; //屏蔽掉行值高4位
- if(temp!=0x00) //判断有无键按下,为0则无键按下,否则有键按下
- { m=i; //保存列号至m变量
- find=1; //置找到按键标志
- switch(temp) //判断哪一行有键按下,记录行号到n变量
- { case 0x01:n=0;break; //第0行有键按下
- case 0x02: n=1;break; //第1行有键按下
- case 0x04: n=2;break; //第2行有键按下
- case 0x08: n=3;break; //第3行有键按下
- default:break;
- }
- break; //有键按下,退出for循环
- }
- }
- }
- }
- if(find==0) return -1; //无键按下则返回-1
- else return(n*4+m); //否则返回键值,键值=列号*4+行号
- }
- //函数名:delay
- //函数功能:实现软件延时
- //形式参数:无符号整型变量i,控制空循环的循环次数
- //返回值:无
- void delay(unsigned int i) //延时函数
- {
- unsigned int k;
- for(k=0;k<i;k++);
- }
复制代码
|
评分
-
查看全部评分
|