菜鸟学STM32之按键输入

微信公众号:小樊Study
关注共同学习,问题或建议,请公众号留言!!!

跑马灯实验我们学习了STM32F4的IO口作为输出的使用,这次我们将向大家介绍如何使用 STM32F4的IO口作为输入用,今天我们将利用开发板的4个按键,来控制开发板的两个LED的亮灭和蜂鸣器的开关。通过本次学习,你将了解到STM32F4的IO口作为输入口的使用方法。

硬件连接


KEY0、KEY1 和 KEY2 是低电平有效的,而 KEY_UP 是高电平有效的,并且外部都没有上下拉电阻,所以,需要在STM32F4内部设置上下拉

 

软件设计

key.c

 1#include "key.h"
2#include "delay.h" 
3//////////////////////////////////////////////////////////////////////////////////     
4
5
6//按键初始化函数
7void KEY_Init(void)
8
{
9
10    GPIO_InitTypeDef  GPIO_InitStructure;
11
12  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
13
14  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚
15  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
16  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
17  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
18  GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
19
20
21  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//WK_UP对应引脚PA0
22  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;//下拉
23  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0
24
25
26//按键处理函数
27//返回按键值
28//mode:0,不支持连续按;1,支持连续按;
29//0,没有任何按键按下
30//1,KEY0按下
31//2,KEY1按下
32//3,KEY2按下 
33//4,WKUP按下 WK_UP
34//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
35u8 KEY_Scan(u8 mode)
36
{     
37    static u8 key_up=1;//按键按松开标志
38    if(mode)key_up=1;  //支持连按         
39    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
40    {
41        delay_ms(10);//去抖动 
42        key_up=0;
43        if(KEY0==0)return 1;
44        else if(KEY1==0)return 2;
45        else if(KEY2==0)return 3;
46        else if(WK_UP==1)return 4;
47    }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;      
48     return 0;// 无按键按下
49}


这段代码包含 2 个函数,void KEY_Init(void)和 u8 KEY_Scan(u8 mode),KEY_Init 是用来初始化按键输入的 IO 口的。实现 PA0、PE2~4 的输入设置
KEY_Scan 函数,则是用来扫描这 4 个 IO 口是否有按键按下。KEY_Scan 函数,支持两种扫描方式,通过 mode 参数来设置。
当 mode 为 0 的时候,KEY_Scan 函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。
当 mode 为 1 的时候,KEY_Scan 函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。
有了 mode 这个参数,大家就可以根据自己的需要,选择不同的方式。这里要提醒大家,因为该函数里面有 static 变量,所以该函数不是一个可重入函数,在有 OS 的情况下,这个大家要留意下。同时还有一点要注意的就是,该函数的按键扫描是有优先级的,最优先的是 KEY0,第二优先的是 KEY1,接着 KEY2,最后是 KEY3(KEY3 对应 KEY_UP 按键)。该函数有返回值,如果有按键按下,则返回非 0 值,如果没有或者按键不正确,则返回 0。

key.h

 1#ifndef __KEY_H
2#define __KEY_H     
3#include "sys.h" 
4
5/*下面方式是通过位带操作方式读取IO*/
6
7#define KEY0         PEin(4)     //PE4
8#define KEY1         PEin(3)     //PE3 
9#define KEY2         PEin(2)     //P32
10#define WK_UP     PAin(0)     //PA0
11
12
13
14#define KEY0_PRES     1
15#define KEY1_PRES    2
16#define KEY2_PRES    3
17#define WKUP_PRES   4
18
19void KEY_Init(void);    //IO初始化
20u8 KEY_Scan(u8);          //按键扫描函数    
21
22#endif


main.c

 1#include "sys.h"
2#include "delay.h"
3#include "usart.h"
4#include "led.h"
5#include "beep.h"
6#include "key.h"
7
8
9
10
11int main(void)
12

13
14  u8 key;           //保存键值
15    delay_init(168);  //初始化延时函数
16    LED_Init();             //初始化LED端口 
17    BEEP_Init();      //初始化蜂鸣器端口
18    KEY_Init();       //初始化与按键连接的硬件接口
19    LED0=0;                 //先点亮红灯
20    while(1)
21    {
22        key=KEY_Scan(0);        //得到键值
23        if(key)
24        {                          
25            switch(key)
26            {                
27                case WKUP_PRES: //控制蜂鸣器
28                    BEEP=!BEEP;
29                    break;
30                case KEY0_PRES: //控制LED0翻转
31                    LED0=!LED0;
32                    break;
33                case KEY1_PRES: //控制LED1翻转   
34                    LED1=!LED1;
35                    break;
36                case KEY2_PRES: //同时控制LED0,LED1翻转 
37                    LED0=!LED0;
38                    LED1=!LED1;
39                    break;
40            }
41        }else delay_ms(10); 
42    }
43
44}

主函数代码比较简单,先进行一系列的初始化操作,然后在死循环中调用按键扫描函数KEY_Scan()扫描按键值,最后根据按键值控制 LED 和蜂鸣器的翻转。

下载验证

在下载完之后,我们可以按 KEY0、KEY1、KEY2和 KEY_UP 来看看 DS0 和 DS1 以及蜂鸣器的变化,是否和我们预期的结果一致?

 

下面的是我的公众号二维码图片,欢迎关注。

图注:小樊Study图注:小樊Study

猜你喜欢

转载自www.cnblogs.com/fw-qql/p/12747910.html