搜索
写经验 领红包
 > 动物

5×5矩阵键盘扫描,一条龙化繁为简,值得拥有

本原创文章基于实践经验,提供严谨可靠的设计原理及思路。

设计中在遇到按键较多,但是单片机I/O资源有限时,采用矩阵键盘是一种很好的选择方案。在按键较少时,矩阵键盘没有明显的优势,比如3×3矩阵键盘占用I/O口6个,只支持9个按键;但是,按键较多时,矩阵键盘的优势就凸显出来了,比如5×5矩阵键盘占用I/O口10个,可支持25个按键;

❤矩阵键盘的硬件设计非常简单,如图1以5×5矩阵键盘为例,蓝色行线5条,绿色列线5条(加上拉电阻),用按键代替行列交叉的节点即组成了矩阵键盘,其中二极管处的红色连线可用来检测按键是否按下或作为中断信号的(可以不需要,使用时没有任何影响,本文不涉及)。

5×5矩阵键盘扫描,一条龙化繁为简,值得拥有

图1:矩阵键盘

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

5×5矩阵键盘扫描,一条龙化繁为简,值得拥有

图2:单片机外围电路

硬件的设计就是以上部分,接下来讲解程序部分,

矩阵键盘的扫描方法有多种,其中很青睐的是行列反转扫描,不仅简单而且效率高,而且只需要掌握该方法就足够了。

行列反转扫描的逻辑:

①行线输出全为0(行线PA1~PA5配置成推挽输出,列线PA6~PA10配置成上拉输入)

②读入列线值

③输出列线值(行线PA1~PA5配置成上拉输入,列线PA6~PA10配置成推挽输出)

④读入行线值

⑤组合行线列线值

对于STM32的单片机,直接操作寄存器会更简单,且无需再对I/O进行另外的配置,全部代码如图3所示,完全可以当做一个模块来使用。

5×5矩阵键盘扫描,一条龙化繁为简,值得拥有

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

以下代码与图3里面的代码完全一致(为方便浏览和拷贝)

/*----------------------5*5矩阵键盘扫描函数,返回扫描键值(行列反转扫描)-----------------------*/u16 Key_Scan(void){u16 cord_h,cord_l;u16 key_value = 0xFFFF;GPIOA->CRL = 0x88333334;GPIOA->CRH = 0x44444888;GPIOA->ODR = GPIOA->IDR & 0xFFC1;cord_l = GPIOA->IDR & 0x07C0;if(cord_l != 0x07C0){delay_ms(10);if(cord_l != 0x07C0){cord_l = GPIOA->IDR & 0x07C0;GPIOA->CRL = 0x33888884;GPIOA->CRH = 0x44444333;GPIOA->ODR = cord_l | 0xF83F;delay_us(1);cord_h = GPIOA->IDR & 0x003E;cord_h >>= 1;cord_l >>= 1;key_value = (cord_l + cord_h) & 0xFFFF;return(key_value);}}return(0xFFFF);}

❤以下代码为端口配置寄存器的操作,PA组I/O有16个引脚:PA0~PA15;3代表推挽输出,4代表浮空输入,8代表上拉输入;

GPIOA->CRL = 0x88333334; //低8位配置GPIOA->CRH = 0x44444888; //高8位配置

❤以下代码中,GPIOA->ODR为端口输出数据寄存器,用于写操作;GPIOA->IDR为端口输入数据寄存器,用于读操作;

0xFFC1的二进制:1111 1111 1100 0001,表示要对PA1~PA5置0。

0x07C0的二进制:0000 0111 1100 0000,表示要对PA6~PA10读值。

GPIOA->ODR = GPIOA->IDR & 0xFFC1;//行线输出全为0cord_l = GPIOA->IDR & 0x07C0; //读入列线值

行列反转后的原理与上面完全一样,这里就不一一阐述了。

❤最后讲一下组合行线列线值,假如S1按键按下去了,得到的二进制为(注意黑体字

cord_h:0000 0000 0011 1100

cord_l: 0000 0111 1000 0000

cord_h >>= 1 表示右移1位得到:

0000 0000 0001 1110

cord_l >> = 1 表示右移1位得到:

0000 0011 1100 0000

组合码(键值):key_value=0000 0011 1101 1110,即0x03DE;最后函数返回key_value值,该值就作为判断S1的键值。

❤之所以右移1位,是因为PA0没有用于矩阵键盘,所得到的键值也就被左移了1位,事实上,也可以不用右移,只是得到的组合码不同而已,右移是为了方便计算。

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

define S2 0x03BEdefine S4 0x02FEdefine S6 0x03DDdefine S8 0x037Ddefine S10 0x01FDdefine S12 0x03BBdefine S14 0x02FBdefine S16 0x03D7define S18 0x0377define S20 0x01F7define S22 0x03AFdefine S24 0x02EF#define S25 0x01EF

5×5矩阵键盘扫描,一条龙化繁为简,值得拥有

❤要点:

①行列反转扫描的思想是行线作为输出时,读出列线的值;然后反过来,列线作为输出时,读出行线的值,最后把两个值组合起来就是该按键的键值;

②参与计算的十六进制数一定要与行线或列线在同组端口的位置匹配,比如0xFFC1的二进制:1111 1111 1100 0001,表示要对PA1~PA5置0。

专注产品级的电子、电气的设计及应用,不定期更新硬核知识,欲了解更多信息敬请关注,谢谢欣赏。