矩阵键盘——基于stm32单片机

目录

基本原理

矩阵按键原理图

初始化

识别键码

GPIO_Write()函数和GPIO_ReadInputData()函数

读取列数

读取行数

返回键码


基本原理

了解矩阵键盘之前,应当要对基本按键的检测要有认识:如下图

矩阵键盘——基于stm32单片机_第1张图片 图源up主  江协科技

 右边按键一端接低电平,一段接PB1。设置PB1为上拉输入,相当于按键两端分别置0和1(低电平和高电平)。按键未按下时,对PB1检测,PB1电平就为高(1)。那么当按键按下时,PB1与地导通,此时对PB1检测,PB1电平就为低(0)。

按键按下可以看作对按键两端进行“与”的操作,即有0则都为0。(检测时)

所以,通过检测原来高电平的引脚是否变低则可以判断按键是否按下。

矩阵按键原理图

矩阵键盘——基于stm32单片机_第2张图片

 

初始化

这里我初始化是将高四位引脚设置为上拉输入,低四位引脚设置为推挽输出。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
uint16_t keyz=0;

void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );
	
	GPIO_InitTypeDef GPIO_KEY0_3;
	GPIO_KEY0_3.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_KEY0_3.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 |GPIO_Pin_3 ;
	GPIO_KEY0_3.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init (GPIOA ,&GPIO_KEY0_3);
	
	GPIO_InitTypeDef GPIO_KEY1_4;
	GPIO_KEY1_4.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_KEY1_4.GPIO_Pin=GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6 |GPIO_Pin_7 ;
	GPIO_KEY1_4.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init (GPIOA ,&GPIO_KEY1_4);
}	

识别键码

GPIO_Write()函数和GPIO_ReadInputData()函数

GPIO_Write()函数可以对多个引脚同时进行配置,此函数有两个参数,第一个为引脚分组,第二个为一个十六进制数。这个十六进制数就是按其对应的二进制对引脚电平进行配置。如GPIO_Write(GPIOA ,0xF0);为1111 0000,即对PA0-PA3引脚置低电平,对PA4-PA8引脚置高电平。

矩阵键盘——基于stm32单片机_第3张图片 十六进制转换表

 GPIO_ReadInputData()函数输出的是十六进制表示的引脚状态。

读取列数

当按键未按下时使用 GPIO_ReadInputData()函数读取按键,读取值为0xF0,即1111 0000;

高四位代表 列 对应引脚状态,低四位代表 行 对应引脚状态。

如果当按键按下时使用 GPIO_ReadInputData()函数读取按键,此时按下按键 列数 对应的引脚为0,再进行Lie=~GPIO_ReadInputData (GPIOA ); Lie=Lie&0xF0;    则得到列数。

读取行数

将行对应引脚电位逐次拉高,当轮到 按下按键对应行数时 ,由于按键两端都为1,则(GPIO_ReadInputData (GPIOA )&0xF0)!=0xF0;否则(GPIO_ReadInputData (GPIOA )&0xF0)==0xF0;由此可得行数。

u16 Key_Scan(void)
{
	uint8_t Hang,Lie,k,i;
	
	GPIO_Write(GPIOA ,0xF0);					    //将A0-A3口和A4-7口电位分别置成低电位和高电位
	//0xF0 转换成二进制为 1111 0000;
	if((GPIO_ReadInputData(GPIOA)&0xF0)!=0xF0)      //判断按键是否按下
	{
		Delay_ms (40);                              //按键消抖
		if((GPIO_ReadInputData(GPIOA)&0xF0)!=0xF0)  //再次判断
		{
			
			Hang=GPIO_ReadInputData (GPIOA );	    //给Hang赋上初值,读取按键按下后得到的代码,假设为1011 0000 (0xB0)
			Lie=~Hang;								//对Hang按位取反,即0100 1111
			Lie=Lie&0xF0;										 					//0100 1111 &1111 0000得到0100 0000 即为列数
			//得到列数
			for(i=0;i<4 && ((Hang&0xF0)!=0xF0);i++) //逐次将行拉高,判断列数中原来变低的位是否变高
			{																					//读到之前检测到为低的列变高则推出
				GPIO_Write (GPIOA ,0xF0|(0x01<

返回键码

u16 Key_Get(void)
{
	keyz =Key_Scan ();
	uint16_t Keyx=0;
	if (keyz!=0)
	{		
		switch(keyz)
		{
			case 0x81:Keyx=1;break;
			case 0x82:Keyx=2;break;
			case 0x84:Keyx=3;break;
			case 0x88:Keyx=4;break;
			case 0x41:Keyx=5;break;
			case 0x42:Keyx=6;break;
			case 0x44:Keyx=7;break;
			case 0x48:Keyx=8;break;
			case 0x21:Keyx=9;break;
			case 0x22:Keyx=10;break;
			case 0x24:Keyx=11;break;
			case 0x28:Keyx=12;break;
			case 0x11:Keyx=13;break;
			case 0x12:Keyx=14;break;
			case 0x14:Keyx=15;break;
			case 0x18:Keyx=16;break;
			default:break;
		}
	}
	return Keyx;
	
}

实例:单数遇到双数按键分别亮两个不同的灯mat key · 灵槐梦/stm32 - 码云 - 开源中国 (gitee.com)

矩阵键盘——基于stm32单片机_第4张图片

 

 

你可能感兴趣的:(嵌入式硬件,stm32,经验分享,单片机,笔记)