(七)按键
1.关键——延时消抖
- 使用软件消抖的方法:
一般来说一个简单的按键消抖就是先读取按键的状态,如果得到按键按下之后,延时10ms,再次读取按键的状态,如果按键还是按下状态,那么说明按键已经按下。
2.编程操作
建立“key.h”和“key.c”文件
-
“key.h”的程序编写
#ifndef _key_H #define _key_H #include "stm32f4xx.h" #define Key_UP_Pin GPIO_Pin_0 #define Key_LEFT_Pin GPIO_Pin_4 #define Key_DOWN_Pin GPIO_Pin_3 #define Key_RIGHT_Pin GPIO_Pin_2 #define Key_UP_Port GPIOA #define Key_Port GPIOE #define Key_UP PAint(0) #define Key_LEFT PEint(4) #define Key_DOWN PEint(3) #define Key_RIGHT PEint(2) #endif
-
“key.c”的程序编写
#include "key.h" void Key_Init() { //结构体变量的定义和使能端口时钟可以直接对两组端口操作 GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量,此行必须要在GPIO端口时钟使能程序的上方 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOA,ENABLE);//使能对应的GPIO端口时钟 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入模式 GPIO_InitStructure.GPIO_Pin=Key_UP_Pin; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉 GPIO_Init(Key_UP_Port,&GPIO_InitStructure); //初始化结构体 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN; //输入模式 GPIO_InitStructure.GPIO_Pin=Key_LEFT_Pin|Key_DOWN_Pin|Key_RIGHT_Pin; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉 GPIO_Init(Key_Port,&GPIO_InitStructure); //初始化结构体 } u8 Key_Scan(u8 mode) { //mode取值为0或1 static u8 key=1; //经过static定义的变量在函数之中只初始化一次,即使再度进入该函数也不会被再次初始化 if(key==1&&(Key_UP==1||Key_LEFT==0||Key_DOWN==0||Key_RIGHT==0)) { delay_ms(10); key=0; if(Key_UP==1) { return Key_UP_O; } else if(Key_LEFT==0) { return Key_LEFT_O; } else if(Key_DOWN==0) { return Key_DOWN_O; } else { return Key_RIGHT_O; } } else if(Key_UP==0&&Key_LEFT==1&&Key_DOWN==1&&Key_RIGHT==1) { key=1; } if(mode) { key=1; } return 0; }
注:键盘扫描函数因参数mode的不同有单次扫描和循环扫描之分,及其原因如下:
- 在main程序中,一般使用while使要执行的程序不断循环,而单次键盘的扫描指的就是当按键判断被按下后执行对应功能,当再次因while进入程序时,即使再度按下按键,也不会执行对应按键的功能;而键盘的循环扫描会始终保证按键对应功能的执行。
-
在“key.h”中声明“key.c”中定义的函数,最终效果如下:
#ifndef _key_H #define _key_H #include "stm32f4xx.h" #define Key_UP_Pin GPIO_Pin_0 #define Key_LEFT_Pin GPIO_Pin_4 #define Key_DOWN_Pin GPIO_Pin_3 #define Key_RIGHT_Pin GPIO_Pin_2 #define Key_UP_Port GPIOA #define Key_Port GPIOE #define Key_UP PAint(0) #define Key_LEFT PEint(4) #define Key_DOWN PEint(3) #define Key_RIGHT PEint(2) void Key_Init(void); u8 Key_Scan(u8 mode); #endif
-
在main中编写总程序
#include "system.h" #include "zs_pro_standard.h" #include "SysTick.h" #include "key.h" int main() { u8 key; // u8 i; IpO_Init(); SysTick_Init(168); Key_Init(); while(1) { key=Key_Scan(1); switch(key) { case Key_UP_O: led1=1;break; case Key_LEFT_O: led2=1;break; case Key_DOWN_O: led1=1,led2=1;break; case Key_RIGHT_O: led1=0,led2=0;break; } // i++; // if(i%20==0) // { // led1=!led1; // } // delay_ms(10); } }