小弟最近一直在做一个动态电子密码锁的程序,就是密码每隔5分钟变化一次的电子锁,程序编了七七八八,理论上没有什么问题了,可是程序应用到单片机上的时候就出现了问题,一个问题就是矩阵键盘输入的时候没有显示,第二个就是矩阵键盘一旦有输入之后,密码就初始化了,不知道是为什么。可能和最近困扰我很久的一个问题有关,我就一并向大家请教请教;
我的程序中有一个定时中断用来调用密码变更程序的,然后在输入这个模块除了问题,因为我想的是在主程序中不断扫描键盘,一旦有按键按下之后就调用键盘扫描程序,相当于是电平触发,但是按下去的时间比较长,岁就会导致按一次调用多次扫描程序,就按一次得到好几个相同的数据。后来我自己想,我在探测到有键按下去到时候调用键盘扫描程序,然后知道是那个键之后,停在那边等键弹起,相当于一个下降沿,然后再回到主程序,并且我现在就是这么做的,但是问题又有了,程序停留在等待下降沿的时候定时中断好像除了问题,而且还是显示不出来,愁死我了,希望有人能够帮帮我。下面附上小弟的程序草稿
//*******************************************动态电子密码锁*********************************************//
//P1接
#include <reg51.h>
//**************************************************变量定义*******************************************//
char DelayCNT;
char a=1,b=2,c=3;//定义变量
unsigned int i,n,m=0,codenum=1,num=0 ;
unsigned int LedOut[10];
unsigned int dis_buf[4]=0;
unsigned int key,temp,keytimes=0;//keytimes 表示第几个按键
//**************************************************函数申明****************************************//
void delay(unsignedi);
void codechange(void);
void display1(void);//密码算法结果显示
void display2(void);//矩阵键盘输入显示
void keyscan(void);
void keydown(void);
void codecmp(void);
void beep(void);
//此表为 LED 的字模, 共阴数码管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段码控制
//此表为8个数码管位选控制, 共阴数码管 1-8个 -
unsigned char code dispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F}; //位选控制 查表的方法控
//******************************************密码算法*******************************************************//
void codechange(void){
a=a+2;
b=b*3;
codenum=a*b+3;
}
//*******************************************显示程序****************************************************************//
void display1(void){
LedOut[0]=Disp_Tab[codenum%10000/1000]; //钥匙密码的显示
LedOut[1]=Disp_Tab[codenum%1000/100]|0x80;
LedOut[2]=Disp_Tab[codenum%100/10];
LedOut[3]=Disp_Tab[codenum%10];
for( i=0; i<9; i++)
{
P0 = LedOut
;
P1 = dispbit; //使用查表法进行位选
delay(150); //扫描间隔时间 太长会数码管会有闪烁感
}
}
void display2(void){
//*******************************************输入密码显示**************************************************************、、
LedOut[4]=Disp_Tab[dis_buf[0]];
LedOut[5]=Disp_Tab[dis_buf[1]]|0x80;
LedOut[6]=Disp_Tab[dis_buf[2]];
LedOut[7]=Disp_Tab[dis_buf[3]];
for( i=0; i<9; i++)
{
P0 = LedOut;
P1 = dispbit; //使用查表法进行位选
delay(150); //扫描间隔时间 太长会数码管会有闪烁感
}
}
//*********************************************键盘扫描*****************************************//
void keyscan(void)
{ temp = 0;
P1=0xF0; //高四位输入 列为高电平 行为低电平
delay(2); //延时
temp=P1; //读P1口
temp=temp&0xF0; //屏蔽低四位
temp=~((temp>>4)|0xF0);
if(temp==1) // p1.4 被拉低
key=1; //第1个按键键值
else if(temp==2) // p1.5 被拉低
key=2; //第2个按键键值
else if(temp==4) // p1.6 被拉低
key=3; //第3个按键键值
else if(temp==8) // p1.7 被拉低
key=4; //第4个按键键值
else
key = 16;
P1=0x0F; //低四位输入 行为高电平 列为低电平
delay(1); //延时
temp=P1; //读P1口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1) //第一行 p1.0 被拉低
key=key+0;
else if(temp==2) //第二行 p1.1 被拉低
key=key+4;
else if(temp==4) //第三行 p1.2 被拉低
key=key+8;
else if(temp==8) //第四行 p1.3 被拉低
key=key+12;
else
key = 16;
dis_buf[keytimes] = key; //键值入显示缓存
dis_buf[keytimes] = dis_buf[keytimes] & 0x0f;
}
//********************************************** 判断键是否按下**********************//
void keydown(void)
{
P2=0xF0; //将高4位全部置1 低四位全部置0
if(P2!=0xF0) //判断按键是否按下 如果按钮按下 会拉低P2其中的一个端口
{
keydown(); //调用按键扫描程序
beep();
while(P2!=0xF0);
m=1;
keytimes++;
}
}
/************主函数**********************/
main()
{
TMOD= 0X10; //定时器1的工作方式1
EA= 1; //开启总中断
ET1= 1; //开启定时器1
TH1= 0x3c; //高位赋初值
TL1= 0xb0; //低位赋初值 3cb0是15535,则计时为(65535-15535=50000)us,即50ms
TR1= 1; //启动定时器 T1
num= 0;
for(i=0;i<20;i++){
keydown();
display1();
display2();
if(num==5){
num=0;
codechange();
}
}
}
//*********************************************中断**********************************************
//********************************************* 定时中断***************************************//
void int_1()interrupt 3
{
unsigned char n;
TH1= 0x3c;
TL1= 0xb0; //3cb0是15535,则计时为(65535-15535=50000)us,即50ms
TR1= 1;
n++;
if(n==20) //1s num加1
{
num++ ;
n= 0;
}
}
/*******************延时函数**********************************************/
void delay(unsigned int i)
{ char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--);
}
此帖出自小平头技术问答
一周热门 更多>