lieqiang的stm32学习之二 led与矩阵键盘
在上一次的实验中,我们学习了led灯的初始化与流水灯的制作,这次我们来做由矩阵键盘控制led灯的开关
所需硬件
较第一次比较,这次我们会多一个矩阵键盘
其中R(Row)代表行,C(Column)代表列。
硬件连接
这里我们用R1 R2 R3分别连接PE7 PE8 PE9,C1 C2 C3接GND
程序写作
这里我们看到,矩阵键盘有四行四列,,我们需要至少三个键来控制三个灯的开关,我这里选择的是PE7 PE8 PE9三个GPIO口来接受我们键盘的按键情况,所以上面的R1 R2 R3分别是接的PE7 PE8 PE9三个口上面。
关于按键的小贴士(消抖)
在使用按键的时候,我们需要对按键进行消抖处理,理论上我们按下与松开按键的情况应是下面所示。
实际上的图案确实下面的情况
所以我们需要对按键进行消抖处理,消抖思路是,对按键进行延时处理,当检测到按键值为0时,延时一段时间,在检测是不是还是为0,若为0,则按键按下,若不为0,则按键没被按下。
如下便是按键消抖及判断那个按键按下的函数
int key_scan(){
static u8 flag = 1;//之前没有按键被按下
if(flag ==1&&(KEY0 == 0 || KEY1 ==0 || KEY2 ==0)){
delay_ms(10);//按键消抖
flag = 0;
if(KEY0==0){
return 1;
}else if(KEY1==0){
return 2;
}else if(KEY2==0){
return 3;
}
}else if(KEY0==1&&KEY1==1&&KEY2==1) flag=1; //判断是否有键按下且确定是哪一个键按下
return 0;
}
写key.h与key.c
由于我们在读取矩阵键盘的输入时使用了PE7 PE8 PE9三个口,所以我们需要对PE7 PE8 PE9三个口进行初始化,如下
void key_init(){
GPIO_InitTypeDef GPIO_Initstructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//打开PE时钟
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IPU; //设置为上拉模式
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7; //驱动PE8和PE9和PE7三个端口
GPIO_Init(GPIOE,&GPIO_Initstructure); //驱动PE两个端口
}
再加上按键消抖函数,便形成了key.c文件
#include "key.h"
#include "stm32f10x.h"
#include "delay.h"
void key_init(){
GPIO_InitTypeDef GPIO_Initstructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//打开PE时钟
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IPU; //设置为上拉模式
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8 | GPIO_Pin_7; //驱动PE8和PE9和PE7三个端口
GPIO_Init(GPIOE,&GPIO_Initstructure); //驱动PE两个端口
}
int key_scan(){
static u8 flag = 1;//之前没有按键被按下
if(flag ==1&&(KEY0 == 0 || KEY1 ==0 || KEY2 ==0)){
delay_ms(10);//按键消抖
flag = 0;
if(KEY0==0){
return 1;
}else if(KEY1==0){
return 2;
}else if(KEY2==0){
return 3;
}
}else if(KEY0==1&&KEY1==1&&KEY2==1) flag=1; //判断是否有键按下且确定是哪一个键按下
return 0;
}
我们再key.c之中用到的一些自定义变量都在key.h中进行的定义,如下
#ifndef _KEY_H
#define _KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_9)//定义PE9为KEY0
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_8)//定义PE8为KEY1
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_7)//定义PE7为KEY2
void key_init(); //初始化GPIO的函数
int key_scan(); //读取键盘键值的函数
#endif
(注意这里.h文件的格式书写)
这里因为含有GPIO_ReadInputDataBit的函数,其包含在 #include "sys.h"中
书写主函数
上面我们已经写了key.h 与 led.h 了·,于是我们再主函数中直接使用
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
int main(void)
{
u8 key = 0;//Initialize button
key_init();
led_init();
delay_init();
while(1)
{
key = key_scan();
if(key){
switch(key){
case 1:
PEout(1)=!PEout(1);
break;
case 2:
PEout(0)=!PEout(0);
break;
case 3:
PBout(9)=!PBout(9);
break;
}
}
}
}
这里我们的逻辑时通过判断key的返回值 进而来判断那个灯需要开或者关