• 菜鸟学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
  • 相关阅读:
    python socket 二进制
    全面介绍内存管理机制
    glog修改
    mysql c api
    http twisted
    IOCP 模型1
    IOCP 模型2 AcceptEx
    python
    Python Twisted
    Java 拾遗
  • 原文地址:https://www.cnblogs.com/fw-qql/p/12747910.html
Copyright © 2020-2023  润新知