1、实物图
2、原理图
3、基本原理
使用8个I/O口来进行16个按键的控制读取,用4条I/O线作为行线,4条I/O线作为列线组成键盘,当某个按键按下时,进行行列扫描,从而判断是第几行第几列的按键,进而进行整体按键值的确定。
4、优点
使用8个I/O口来进行16个按键的控制读取,可以减小I/O口的使用,有效地提高单片机系统中I/O口的利用率
5、扫描方式——行列扫描
定义一组IO口作为矩阵键盘的引脚,高四位连接列,低四位连接行。先令IO口的高四位(四个列)输出低电平,低四位(四个行)输出高电平,假设有按键按下,从I/O口的低四位读取键盘状态,判断低四位的四行哪一行变成了低电平,就知道是第几行;再令I/O口的高四位(四个列)输出高电平,低四位(四个行)输出低电平,从I/O口的高四位读取键盘状态,判断高四位的四列哪一列变成了低电平,就知道是第几列,将两次读取结果相加组合起来就可以得到当前按键的特征编码,使用上述方法就可以得到16个按键的特征编码,然后再利用特征编码重新给每个按键赋一个对应的键值。
6、程序
/****
*******矩阵键盘扫描函数
*******返回值:键值
*****/
uchar matrix_keyboard_pro(void) //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l; //行列值中间变量
MATRIX_KEYBOARD_DATA=0x0f; //列线输出全为0
cord_h=MATRIX_KEYBOARD_DATA&0x0f; //读入行线值
if(cord_h!=0x0f) //先检测有无按键按下
{
Delay_function(10); //去抖
if((MATRIX_KEYBOARD_DATA&0x0f)!=0x0f)
{
cord_h=MATRIX_KEYBOARD_DATA&0x0f; //读入行线值
MATRIX_KEYBOARD_DATA=cord_h|0xf0; //输出当前列线值
cord_l=MATRIX_KEYBOARD_DATA&0xf0; //读入列线值
while((MATRIX_KEYBOARD_DATA&0xf0)!=0xf0); //等待松开并输出
return(cord_h+cord_l); //返回组合码值
}
}
return(0xff); //没有按键按下,返回0xff
}
/****
*******矩阵键盘键值编码为数值函数
*******返回值:键值数值
*****/
uchar Matrix_Keyboard_Scan(void)
{
switch(matrix_keyboard_pro())
{
case (0xee): return 1; break; //K1按下
case (0xde): return 2; break; //K2按下
case (0xbe): return 3; break; //K3按下
case (0x7e): return ‘A’; break; //K4按下
case (0xed): return 4; break; //K5按下
case (0xdd): return 5; break; //K6按下
case (0xbd): return 6; break; //K7按下
case (0x7d): return ‘B’; break; //K8按下
case (0xeb): return 7; break; //K9按下
case (0xdb): return 8; break; //K10按下
case (0xbb): return 9; break; //K11按下
case (0x7b): return ‘C’; break; //K12按下
case (0xe7): return ‘*’; break; //K13按下
case (0xd7): return 0; break; //K14按下
case (0xb7): return ‘#’; break; //K15按下
case (0x77): return ‘D’; break; //K16按下
default: return 0xff; break; //没有按键按下
}
}
7、软件流程
定义一组IO口作为矩阵键盘的引脚,高四位连接列,低四位连接行。先令IO口的高四位(四个列)输出低电平,低四位(四个行)输出高电平,判断低四位是否发生改变即是否有按键按下,如果改变,则进行延时消抖,再判断低四位是否发生改变,如果改变,则保存此时行状态值,接下来,令IO口的高四位(四个列)输出高电平,低四位(四个行)输出低电平,保存此时列状态值,等待列状态值恢复,再返回两次读取结果相加组合起来值即当前按键的特征编码,最后再利用特征编码重新给每个按键赋一个对应的键值。