介绍什么是矩阵键盘 矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组,由于电路设计时需要更多的外部输入,单独的控制一个按键需要浪费很多的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;
- }
复制代码
转载自: 跋扈洋
|