目录
基本原理
矩阵按键原理图
初始化
识别键码
GPIO_Write()函数和GPIO_ReadInputData()函数
读取列数
读取行数
返回键码
了解矩阵键盘之前,应当要对基本按键的检测要有认识:如下图
右边按键一端接低电平,一段接PB1。设置PB1为上拉输入,相当于按键两端分别置0和1(低电平和高电平)。按键未按下时,对PB1检测,PB1电平就为高(1)。那么当按键按下时,PB1与地导通,此时对PB1检测,PB1电平就为低(0)。
按键按下可以看作对按键两端进行“与”的操作,即有0则都为0。(检测时)
所以,通过检测原来高电平的引脚是否变低则可以判断按键是否按下。
这里我初始化是将高四位引脚设置为上拉输入,低四位引脚设置为推挽输出。
#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_Write(GPIOA ,0xF0);为1111 0000,即对PA0-PA3引脚置低电平,对PA4-PA8引脚置高电平。
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)