一.矩阵键盘原理
如图所示:
4X4的矩阵键盘分为4行4列,我们可以先送一列为低电平,其余几列为高电平,然后检测一次各行是否有低电平,如果检测到某一行为低电平,则我们就可以确定当下按的按键是哪行哪列的,用同样的方法再给其余的几列送低电平,再轮流检测一次各行是否有低电平,这样可以检测完全部按键。
二.代码
2.1 key.h
#ifndef _KEY16_H
#define _KEY16_H
#include "sys.h"
#define PG13 PGout(13)
#define PB8 PBout(8)
#define PB6 PBout(6)
#define PB4 PBout(4)
#define PB9 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9) //读取引脚值
#define PB7 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) //读取引脚值
#define PE2 HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) //读取引脚值
#define PB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_3) //读取引脚值
void KEY16_Init(void);
u8 KEY16_Scan(u8 mode);
void scanway(u8 mode);
#endif
2.2 key.c
输入引脚采用 的是上拉输入,即引脚空接时读入的是“1”。相反采用下拉输入时则引脚空接时读入的是“0”。
#include "KEY16.h"
#include "delay.h"
void KEY16_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟
__HAL_RCC_GPIOG_CLK_ENABLE(); //开启GPIOG时钟
__HAL_RCC_GPIOE_CLK_ENABLE(); //开启GPIOE时钟
GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_6|GPIO_PIN_4; //PB8、6、4
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_9|GPIO_PIN_7|GPIO_PIN_3; //PB9、7、3
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_2; //PE2
GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOE,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_13; //PG13
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOG,&GPIO_Initure);
}
void scanway(u8 mode)
{
if(mode==0)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8|GPIO_PIN_6|GPIO_PIN_4,GPIO_PIN_SET);
}
if(mode==1)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6|GPIO_PIN_4,GPIO_PIN_SET);
}
if(mode==2)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4|GPIO_PIN_8,GPIO_PIN_SET);
}
if(mode==3)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6|GPIO_PIN_8,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
}
}
u8 KEY16_Scan(u8 mode)
{
u8 keynum=0;
static u8 key_up=1,t1=0,t2=0,t3=0,t4=0;
if(mode==1) key_up=1;
scanway(0);
if(PG13==0)
{
if(key_up&&(PB9==0||PB7==0||PB3==0||PE2==0))
{
delay_ms(1);
key_up=0;
t1=1;
if(PB9==0) keynum=16;
else if(PB7==0) keynum=15;
else if(PB3==0) keynum=14;
else if(PE2==0) keynum=13;
}
else if(PB9==1&&PB7==1&&PB3==1&&PE2==1&&t1==1)
{
key_up=1;
t1=0;
}
}
scanway(1);
if(PB8==0)
{
if(key_up&&(PB9==0||PB7==0||PB3==0||PE2==0))
{
delay_ms(1);
key_up=0;
t2=1;
if(PB9==0) keynum=12;
else if(PB7==0) keynum=11;
else if(PB3==0) keynum=10;
else if(PE2==0) keynum=9;
}
else if(PB9==1&&PB7==1&&PB3==1&&PE2==1&&t2==1)
{
key_up=1;
t2=0;
}
}
scanway(2);
if(PB6==0)
{
if(key_up&&(PB9==0||PB7==0||PB3==0||PE2==0))
{
delay_ms(1);
key_up=0;
t3=1;
if(PB9==0) keynum=8;
else if(PB7==0) keynum=7;
else if(PB3==0) keynum=6;
else if(PE2==0) keynum=5;
}
else if(PB9==1&&PB7==1&&PB3==1&&PE2==1&&t3==1)
{
key_up=1;
t3=0;
}
}
scanway(3);
if(PB4==0)
{
if(key_up&&(PB9==0||PB7==0||PB3==0||PE2==0))
{
delay_ms(1);
key_up=0;
t4=1;
if(PB9==0) keynum=4;
else if(PB7==0) keynum=3;
else if(PB3==0) keynum=2;
else if(PE2==0) keynum=1;
}
else if(PB9==1&&PB7==1&&PB3==1&&PE2==1&&t4==1)
{
key_up=1;
t4=0;
}
}
return keynum;
}
2.3 main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "KEY16.h"
int main(void)
{
u8 x=0,t=0;
HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
uart_init(115200);
delay_init(180); //初始化延时函数
KEY16_Init();
while(1)
{
x=KEY16_Scan(0);
switch(x)
{
case 1:t=1;printf("%d",t);printf("\r\n"); break;
case 2:t=2;printf("%d",t);printf("\r\n"); break;
case 3:t=3;printf("%d",t);printf("\r\n"); break;
case 4:t=4;printf("%d",t);printf("\r\n"); break;
case 5:t=5;printf("%d",t);printf("\r\n"); break;
case 6:t=6;printf("%d",t);printf("\r\n"); break;
case 7:t=7;printf("%d",t);printf("\r\n"); break;
case 8:t=8;printf("%d",t);printf("\r\n"); break;
case 9:t=9;printf("%d",t);printf("\r\n"); break;
case 10:t=10;printf("%d",t);printf("\r\n"); break;
case 11:t=11;printf("%d",t);printf("\r\n"); break;
case 12:t=12;printf("%d",t);printf("\r\n"); break;
case 13:t=13;printf("%d",t);printf("\r\n"); break;
case 14:t=14;printf("%d",t);printf("\r\n"); break;
case 15:t=15;printf("%d",t);printf("\r\n"); break;
case 16:t=16;printf("%d",t);printf("\r\n"); break;
}
delay_ms(10);
}
}