我做的4*4矩阵按键,每次按键按下显示一个数字,0~F显示,数码管依次显示出按键按下的数值,但是为什么按键一按下,
单片机就停止工作了呢?能不能按键按下单片机继续工作,松开后再返回数值?这是程序,求大神解答
#include<reg51.h>
sbit P3_0 = P3^0;
code unsigned char seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管数字数组
code unsigned char key_scan[] = {0xef,0xdf,0xbf,0x7f};//让按键列线依次出现出现低电平,共需要4个扫描数据
code unsigned char key_num[] = {
0xee,0xed,0xeb,0xe7, //0 1 2 3
0xde,0xdd,0xdb,0xd7, //4 5 6 7
0xbe,0xbd,0xbb,0xb7, //8 9 10 11
0x7e,0x7d,0x7b,0x77 // 12 13 14 15
}; //按键按下的键值
code unsigned char led_num[] = {
0xe1,0xe2,0xe4,0xe8, //0 1 2 3
0xd1,0xd2,0xd4,0xd8, //4 5 6 7
0xb1,0xb2,0xb4,0xb8, //8 9 10 11
0x71,0x72,0x74,0x78 // 12 13 14 15
}; //按键按下的灯值
unsigned char XH[10];
unsigned char cp,cp1;
void delay(unsigned int x) //延时函数
{
while(x--);
}
void display(unsigned char xs) //显示函数
{
P0 = 0xff;
switch(cp)
{
case 0: P3_0 = 0;P3_0 = 1;P0 = 0x01;P3_0 = 0;P0 = seven_seg[xs];break;
case 1: P3_0 = 0;P3_0 = 1;P0 = 0x02;P3_0 = 0;P0 = 0xbf;break;
case 2: P3_0 = 0;P3_0 = 1;P0 = 0x04;P3_0 = 0;P0 = seven_seg[XH[1]];break;
case 3: P3_0 = 0;P3_0 = 1;P0 = 0x08;P3_0 = 0;P0 = seven_seg[XH[2]];break;
case 4: P3_0 = 0;P3_0 = 1;P0 = 0x10;P3_0 = 0;P0 = seven_seg[XH[3]];break;
case 5: P3_0 = 0;P3_0 = 1;P0 = 0x20;P3_0 = 0;P0 = seven_seg[XH[4]];break;
case 6: P3_0 = 0;P3_0 = 1;P0 = 0x40;P3_0 = 0;P0 = 0xbf;break;
case 7: P3_0 = 0;P3_0 = 1;P0 = 0x80;P3_0 = 0;P0 = seven_seg[cp1];break;
}
cp++;
if(cp >= 8)
cp = 0;
}
unsigned char key(void) //按键函数
{
unsigned char i,j;
for(i = 0;i < 4;i++)
{
P2 = key_scan[i];
if(P2 != key_scan[i])
{
delay(300); //消除按键抖动,有按键确实按下
if(P2 != key_scan[i]) //如果有按键按下,P2口不是原来扫描数据
for(j = 0;j < 16;j++) //让键盘行线输出扫描数据
{
if(P2 == key_num[j])
{
while(P2 == key_num[j]) ;
cp1++; //4个显示的数的数组
if(cp1 >= 4) cp1 = 4;
XH[cp1] = j;
return(j);
}
}
}
}
return(6);
}
void main(void) //主函数
{
unsigned char k; //定义一个变量k
while(1)
{
k = key(); //把扫描的值赋值给k
display(k); //显示k
P1 = led_num[k];
}
}
unsigned char key(void) //按键函数
{
unsigned char temp1,temp2,temp3; //临时变量
static bit sign=0; //按键自锁标志
static unsigned char count=0; //消抖计数变量
P2=0xf0; //先给P2赋一个初值
if(P2!=0xf0) //判断P2不等于所赋初值,说明有健按下
{
if(sign==0) //如果按键自锁标志为0
{
count++; //消抖计数
if(count>=100) //消抖计数自>=100,估算主循环周期调整
{ //摒弃Delay延时方式,
count=100; //防止溢出
sign=1; //按键自锁标志置1,键不抬起,按其他键无效
temp1=P2; //temp1保存高4位变化
P2=0x0f; //再给P2赋值0x0f
temp2=P2; //temp2保存低4位变化
temp3=temp2|temp1; //temp3=高4位+低4位
return temp3; //返回键值
}
}
}
else //按键抬起
{
sign=0; //按键自锁标志清0
count=0; //消抖计数清0
}
}
评分
查看全部评分
一周热门 更多>