矩形键盘
介绍
什么是矩阵键盘
- 介绍
- 什么是矩阵键盘
- 矩阵键盘的原理
- 驱动电路图
- 软件程序实现
矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组,由于电路设计时需要更多的外部输入,单独的控制一个按键需要浪费很多的IO资源,所以就有了矩阵键盘,常用的矩阵键盘有4X4和8X8,其中用的最多的是4X4。
矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。 在行线和列线的每一个交叉点上,设置一个按键。这样键盘中按键的个数是4×4个。 这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。由于单片机IO端口具有线与的功能,因此当任意一个按键按下时,行和列都有一根线被线与,通过运算就可以得出按键的坐标从而判断按键键值。 原理如同矩阵数列的行列式。
按4*4矩阵搭建的按键矩阵还是比较简单的,也有的人为了保证电路的稳定性,加上二极管保护和上拉电阻,但是一般要求不太高的电路就不需要加了,向下面设置的电路那样就可以了。
在这里宏定义一些GPIO的信息。
KEY.h
#ifndef _KEY_H
#define _KEY_H
#include "stm32f10x.h"
//引脚
#define S0 GPIO_Pin_0
#define S1 GPIO_Pin_1
#define S2 GPIO_Pin_2
#define S3 GPIO_Pin_3
#define S4 GPIO_Pin_4
#define S5 GPIO_Pin_5
#define S6 GPIO_Pin_6
#define S7 GPIO_Pin_7
//GPIO寄存器
#define KEY_PORT GPIOB
//时钟
#define RCC_APB2_KEY RCC_APB2Periph_GPIOB
//函数定义
void InitKey(void);
int NumKey(void);
//延时
void Delay( uint32_t count )
{
for(; count!=0; count--);
}
#endif /* _KEY_H */
在这里存放两个函数,一个是初始化矩形键盘GPIO口的函数,在函数里把前四个定义为推挽输出,后四个GPIO口定义为下拉输入。 另一个函数是键盘扫描函数,通过函数返回值确定是举行键盘的哪一个按键被按下。
KEY.c
#include "KEY.h"
void InitKey(void)//初始化KEY的GPIO
{
//打开GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2_KEY,ENABLE);
//把S0,S1,S2,S3配置为推挽输出
GPIO_InitTypeDef GPIOInit;
GPIOInit.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIOInit.GPIO_Speed=GPIO_Speed_50MHz;
GPIOInit.GPIO_Pin=S0|S1|S2|S3;
GPIO_Init(KEY_PORT,&GPIOInit);
//把S4,S5,S6,S7配置为下拉输入
GPIOInit.GPIO_Mode=GPIO_Mode_IPU;
GPIOInit.GPIO_Pin=S4|S5|S6|S7;
GPIO_Init(KEY_PORT,&GPIOInit);
//0--3输出高,4--7输出低
GPIO_SetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
GPIO_ResetBits(GPIOC,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
}
int NumKey(void) //扫描键值
{
int KeyVal=0; //键值,后面自己设定的,用来设置按键的序号
u16 KeyWrite=0; //写给GPIO的值
GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0 | 0xf));//0--3全部输出高
if((KEY_PORT->IDR&0x00f0)==0x0000) //如果4--7全为0,表示没有按键按下,返回值设置为-1
return -1;
else
{
Delay(0xF);//消抖
if((KEY_PORT->IDR&0x00f0)==0x0000) //如果4-7全为0,表示刚才是抖动造成的
return -1;
}
GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x1));//让0-3输出0001
switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
{
case 0x0010: KeyVal=16;break;
case 0x0020: KeyVal=12;break;
case 0x0040: KeyVal=8; break;
case 0x0080: KeyVal=4; break;
}
GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x2));//让0-3输出0010
switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
{
case 0x0010: KeyVal=15;break;
case 0x0020: KeyVal=11;break;
case 0x0040: KeyVal=7; break;
case 0x0080: KeyVal=3; break;
}
GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x4));//让0-3输出0100
switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
{
case 0x0010: KeyVal=14;break;
case 0x0020: KeyVal=10;break;
case 0x0040: KeyVal=6; break;
case 0x0080: KeyVal=2; break;
}
GPIO_Write(KEY_PORT,(KEY_PORT->ODR & 0xfff0|0x8));//让0-3输出1000
switch(KEY_PORT->IDR&0x00f0)//对4--7进行判断
{
case 0x0010: KeyVal=13;break;
case 0x0020: KeyVal=9;break;
case 0x0040: KeyVal=5; break;
case 0x0080: KeyVal=1; break;
}
return KeyVal;
}
想了解更多嵌入式知识,欢迎关注我的项目实战专栏。 还可关注公众号,了解更多。