有耐心的工程师帮忙看看
用的是PIC单片机,RA1,RA2,RA 3接行线,RB3、RB4、RB5接列线(带上拉的功能)
程序如下:(10ms执行一次)
//============= ============= ===========
//矩阵按键驱动
//============================ ==========
uchar read_keyboard(void)
{
static char key_state = 0, key_value, key_line;
uchar key_return = No_key,i,key_value_portb=0;
switch (key_state)
{
case 0:
key_line = 0b00001000; //0 B5 B4 B3 A3 A2 A1 0
for (i=1; i<=3; i++) // 扫描键盘
{
PORTA &= ~key_line; // 输出行线电平
PORTA &= ~key_line;
key_value_portb = PORTB;
key_value_portb = PORTB;
key_value_portb <<= 1;
key_value = Key_mask & key_value_portb; // 读列电平
if (key_value == Key_mask)
key_line >>= 1; // 没有按键,继续扫描
else
{
key_state++; // 有按键,停止扫描
break; // 转消抖确认状态
}
}
break;
case 1:
key_value_portb = PORTB;
key_value_portb = PORTB;
key_value_portb <<= 1;
if (key_value == (Key_mask & key_value_portb)) // 再次读列电平,
{
switch (key_line | key_value) // 与状态0的相同,确认按键
{ // 键盘编码,返回编码值
case 0b01100010:
key_return = KA1_B3; //9
break;
case 0b01010010:
key_return = KA1_B4 ; //8
break;
case 0b00110010:
key_return = KA1_B5; //7
break;
case 0b01100100:
key_return = KA2_B3; //6
break;
case 0b01010100:
key_return = KA2_B4; //5
break;
case 0b00110100:
key_return = KA2_B5; //4 //4
break;
case 0b01101000:
key_return = KA3_B3; // 3
break;
case 0b01011000:
key_return = KA3_B4; // 2
break;
case 0b00111000:
key_return = KA3_B5; // 1
break;
}
key_state++; // 转入等待按键释放状态
}
else
{
PORTA |= 0b00001110;
key_state--; // 两次列电平不同返回状态0,(消抖处理)
}
break;
case 2: // 等待按键释放状态
PORTA &= 0b11110001; // 行线全部输出低电平
PORTA &= 0b11110001; // 行线全部输出低电平
key_value_portb = PORTB;
key_value_portb = PORTB;
key_value_portb <<= 1;
if ( (Key_mask & key_value_portb) == Key_mask)
{key_state=0; PORTA |= 0b00001110;}// 列线全部为高电平返回状态0
break;
}
return key_return;
}
这程序没调通,自己也看不出哪有问题! |