简述矩阵键盘的扫描原理_矩阵键盘扫描的原理及设计

当设计中按键较多,但单片机I/O资源有限时,使用矩阵键盘是一个不错的选择。按键少的时候,矩阵键盘没有明显的优势。比如33矩阵键盘,占用6个I/O口,只支持9个键。但当按键较多时,矩阵键盘的优势就凸显出来了。例如,一个55矩阵键盘占用10个I/O端口,可以支持25个键。矩阵键盘的硬件设计非常简单,如图1所示,以55矩阵键盘为例,有5条蓝色行线和5条绿色列线(加上拉电阻),矩阵键盘是用按键代替跨越行列的节点构成的,其中二极管处的红色连接线可以用来检测按键是否被按下,或者作为中断信号使用(使用时没有必要,没有影响,本文不涉及)。

图1:矩阵键盘

如图2所示,单片机STM32F103CBT6的外围电路,彩色I/O口为矩阵键盘的行线PA1~PA5(蓝色)和列线PA6~PA10(绿色)。为了编程方便,矩阵键盘最好选择同一组I/O口。

图2:单片机外围电路

硬件设计是上面的部分,接下来说明程序部分。

矩阵键盘的扫描方式有很多种,其中行列反转扫描非常流行,不仅简单而且效率高,掌握这种方式就足够了。

行列反转扫描的逻辑:

所有行线输出为0(行线PA1~PA5配置为推挽输出,列线PA6~PA10配置为上拉输入)。

读入列线值。

输出列线值(行线PA1至PA5配置为上拉输入,列线PA6至PA10配置为推挽输出)。

读入行线值。

组合的行和列行值

对于STM32微控制器,直接操作寄存器会更容易,不需要配置I/O,所有代码如图3所示,可以作为一个模块使用。

图3:矩阵键盘的行列反转扫描

下面的代码与图3中的代码完全相同(便于浏览和复制)。

u16key。u16 key _ value=0xFFFFGPIOA-CRL=0x 88333334;GPIOA-CRH=0x 44444888;GPIOA-ODR=GPIOA-IDR0x ffc 1;cord _ l=GPIOA-IDR0x 07 c 0;if(cord_l!=0x07c 0){ delay _ ms(10);if(cord_l!=0x07c 0){ cord _ l=GPIOA-IDR0x07c 0;GPIOA-CRL=0x 33888884;GPIOA-CRH=0x 44444333;GPIOA-ODR=cord _ l |0x f83 f;delay _ us(1);cord _ h=GPIOA-IDR0x 003 e;cord _ h=1;cord _ l=1;key _ value=(cord _ l cord _ h)0x ffff;return(key _ value);} } return(0x ffff);}以下代码是端口配置寄存器的操作,PA组I/O有16个管脚:PA0 ~ PA15;3代表推挽输出,4代表浮动输入,8代表上拉输入;

GPIOA-CRL=0x 88333334;//低8位配置GPIOA-CRH=0x 44444888;//高8位在下面的代码中配置,GPIOA-ODR是用于写操作的端口输出数据寄存器;GPIOA-IDR是用于读操作的端口输入数据寄存器;

0xFFC1二进制:1111 1111 1100 0001,表示PA1~PA5应该置0。

0x07C0二进制:00001111100000,表示从PA6到PA10读取值。

GPIOA-ODR=GPIOA-IDR0x ffc 1;//线路输出都是0 cord _ l=GPIOA-IDR0x 07 c 0;//列反转后读入列线值的原理和上面完全一样,这里就不细说了。

最后,我们来谈谈行线和列线的组合值。如果按下S1键,二进制为(注意粗体字)。

0000 0000 0011 1100

cord_l:0000 0111 1000 0000

Cord_h=1意味着它是通过右移一位获得的:

0000 0000 0001 1110

Cord_l=1意味着它是通过右移一位获得的:

0000 0011 1100 0000

组合码(键值):key _ value=0000011 1101 1110,即0x 03 de;最后,该函数返回key_value的值,作为判断S1的键值。

PA0之所以右移一位,是因为在矩阵键盘中不使用,所以得到的键值左移一位。其实不一定要右移,只是得到的组合码不一样。右移是为了计算方便。

矩阵键盘的键值定义如下:

#定义S10x 03 de #定义S20x 03 be #定义S30x 037 e #定义S40x 02 Fe #定义S50x01FE #定义S60x03DD #定义S70x03BD #定义S80x037D#定义S90x02FD #定义S100x01FD #定义S110x03DB #定义S120x03BB #定义S130x037B #定义S140x02FB #定义S160x03D7#定义S170x 03 b #定义S180x0377 #定义S190x02f7 #定义S19

行列反转扫描的思想是在行线作为输出时读取列线的值;然后反过来,当列线作为输出时,读取行线的值,最后将两个值组合起来形成key的键值;

参与计算的十六进制数必须与同一组端口的行线或列线的位置相匹配,如0xFFC1: 1111 1111 1100 0001的二进制数,这意味着PA1~PA5要设置为0。

审计郭婷