📄 key.c
字号:
//针对avr单片机编写,当然也可能移植到其他环境
#define KEY_PORT PORTC
#define KEY_PIN PINC
#define NO_KEY 255 //4x4键盘
#define KEY_MASK 0x07 //00000111
//在中断函数里调用,应该是10ms左右一次中断.因为这是消抖所需时间.
char read_keyboard()
{
static char key_state = 0;
static char key_value, key_line;
char key_return = NO_KEY;
unsigned char i;
switch(key_state)
{
case 0:
key_line = 0x08; //0b0000 1000;
for(i=1;i<=4;i++) //按键扫描
{
KEY_PORT = ~key_line; //输出行线电平
KEY_PORT = ~key_line; //输出两次
//delay_nms(2);
key_value = KEY_MASK & KEY_PIN; //读列电平
if(key_value == KEY_MASK)
{
key_line <<= 1; //没有按键,继续扫描
//delay_nms(2);
}
else
{
key_state++; //有键按下,停止扫描
break; //转消抖确认状态
}
}
break;
case 1:
{
switch((key_value | key_line)) //与状态0相同,确认按键
{
case 0x0e: //0b00001110:
key_return = K4_3;
break;
case 0x0d: //0b00001101:
key_return = K4_2;
break;
case 0x0b: //0b00001011:
key_return = K4_1;
break;
case 0x16: //0b00010110:
key_return = K3_3;
break;
case 0x15: //0b00010101:
key_return = K3_2;
break;
case 0x13: //0b00010011:
key_return = K3_1;
break;
case 0x26: //0b00100110:
key_return = K2_3;
break;
case 0x25: //0b00100101:
key_return = K2_2;
break;
case 0x23: //0b00100011:
key_return = K2_1;
break;
case 0x46: //0b01000110:
key_return = K1_3;
break;
case 0x45: //0b01000101:
key_return = K1_2;
break;
case 0x43: //0b01000011:
key_return = K1_1;
break;
}
key_state++; //转入按键释放状态
}
break;
case 2:
KEY_PORT = 0x07; //行线全部输出低电平
KEY_PORT = 0x07;
if((KEY_MASK & KEY_PIN) == KEY_MASK)
{
key_state = 0; //列线全部为高电平,返回状态0
}
break;
}
return(key_return);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -