📄 keyscan_led.c
字号:
/*4×4键盘扫描及6位LED显示程序*/
/*LED显示时,P2为位选码,P3为段选码*/
/*键盘扫描时,P0高四位(行线)为输出,低四位(列线)为输入*/
#include "reg51.h"
#define KEY P0
const unsigned char NUM_LED[17]= //共阴七段码,a为低位,dp为高位
{
0x3f,0x06,0x5b,0x4f,0x66,//0~4
0x6d,0x7d,0x07,0x7f,0x6f,//5~9
0x77,0x7c,0x39,0x5e,0x79,//a~e
0x71,0x00 //f,全不显示
};
unsigned char led_buf[4];
unsigned char key_get; //得到的键值
unsigned char key_cnt; //已得到的键数量
unsigned char key_press;
const unsigned char key_map[16]= //设置键盘的逻辑值与程序计算键值的映射
{ //按手机键盘设置
1,2,3,0x0a,
4,5,6,0x0b,
7,8,9,0x0c,
0x0e,0,0x0f,0x0d
};
void init_key(void) /*初始化*/
{
unsigned char i;
key_get=0;key_cnt=0xff;//-1
key_press=0;//flag=0;
for(i=0;i<4;i++)
led_buf[i]=0;//led_buf[i]=16;//不显示
}
void display() /*LED显示*/
{
unsigned char ctr=0x04; //从第三个数码管显示(前两个不能用)
unsigned char i;
int j;
for(i=0;i<4;i++) //四位数码管只需移动3次
{
P2=ctr; //送位选码
P3=NUM_LED[led_buf[i]];//送段选码
for(j=0;j<1000;j++); //延时
ctr=ctr<<1;
}
P2=0; //可避免显示完最后一位后,延时较长造成显示亮度不均匀
}
void key_scan(void) /*键盘扫描*/
{
int i,j;
unsigned char scancode=0xef;//高位扫描
//KEY=0x0f;//00001111B
//for(i=0;i<1000;i++); //延时
if(KEY==0x0e) //00001110
j=0; //在第0列(列输入)
else if(KEY==0x0d) //00001101
j=1; //在第1列(列输入)
else if(KEY==0x0b) //00001011
j=2; //在第2列(列输入)
else if(KEY==0x07) //00000111
j=3; //在第3列(列输入)
KEY=scancode;//11101111B
for(i=0;i<4;i++) //在第i行
{
if(KEY!=scancode)
break;
else
{scancode=(scancode<<1)|0x0f;//扫描码左移一位,低四位为1
KEY=scancode;
}
}
key_get=key_map[i*4+j];
}
unsigned char key_event() /*确定键盘事件,能判断键盘是否松开*/
{
unsigned char flag=0;
int i;
KEY=0x0f;
for(i=0;i<50;i++); //延时去抖动
if((key_press==0)&&(KEY<0x0f))//有按键
{
key_press=1;
key_scan();
}
else if((key_press==1)&&(KEY==0x0f))//已松开按键
{
key_press=0;
flag=1;
}
return flag;
}
void main(void) /*主程序*/
{
int i;
init_key();
while(1)
{
if(key_event())//扫描到了按键
{
for(i=3;i>0;i--) //移位,保存
led_buf[i]=led_buf[i-1];
led_buf[0]=key_get;
//for(i=0;i<15000;i++); //延时去抖动
}
display();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -