欢迎光临散文网 会员登陆 & 注册

【STM32F429单片机学习】单片机学习之按键实验

2023-04-02 20:39 作者:PID的橘子  | 我要投稿

按键实验文件组成

一、key.c(GPIO口的初始化、KEY的基本功能)

分析代码(颜色一样的为一步)

引入KEY、delay头文件(有声明与函数)

#include "key.h"
#include "delay.h"


定义按键初始化函数(其实就是初始化IO口同LED的方法)
void KEY_Init(void)
{

定义GPIO的结构体,因为HAL_GPIO_Init的入口参数为两个均为指针,其中之一为某个GPIO,另一个为结构体,结构体包含着pin的模式

    GPIO_InitTypeDef GPIO_Initure;

    使用某个外设一定要打开其时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟
    __HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
    __HAL_RCC_GPIOH_CLK_ENABLE();           //开启GPIOH时钟

    

设定IO 的输出模式等,因为这是按键实验所以要MODE为输入,KEY有时候低电平有效,有的时候高电平有效,这要看原理图来确定其工作方式,查阅原理图后,我将IO设置如下

    GPIO_Initure.Pin=GPIO_PIN_0;            //PA0
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLDOWN;        //下拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    
    GPIO_Initure.Pin=GPIO_PIN_13;           //PC13
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //输入
    GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    
    GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3
    HAL_GPIO_Init(GPIOH,&GPIO_Initure);
}

在我们初始化IO口,接下来就要设定他的具体功能了,初始化IO我认为好比给汽车点火,而定义功能函数(如下的scan函数)就好比开车出发,首先我们要想到某个KEY按下后,单片机怎么检测到是哪个KEY,仔细想想应该是通过扫描(scan)某个IO口的高低电平来实现,好比当KEY1按下后对应得IO有电平的变化,让单片机知道是那个KEY 按下了
u8 KEY_Scan(u8 mode)
{

设置静态参数(无符号8位整数u8,其范围0-255,所以不用u16 u32),且返回值也为u8,key_up=1,他的值在循环进入程序中不会改变,static(静态),我们把这个key_up=1定义为一个标识符,用来 标定按键未能按下

    static u8 key_up=1;     //按键松开标志

有两种模式mode=0 or 1 选择即可,我们这次mode=0

    if(mode==1)key_up=1;    //支持连按

这里的KEY0==1等,为宏定义其实背后就是一个HAL的READ函数可以读取IO口的高低电平(0 OR 1),这里在.h文件中定义,此代码为某个按键按下后也就是生效后,与我们的按键表示符 key_up=1 与一下,成立就表示按下 key_up=0,若无则   return 0

    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
    {
        delay_ms(10);
        key_up=0;

如果有按键按下那么判断一下到底哪个IO是什么样的电平,来返回一个事件符就是 return KEY0_PRES,首先KEY0_PRES在.h中定义为宏常量目的是建立起4个事件(哪个按钮被按下了),然后在mian.c中与swtich case 结合起来,执行对应的事件。

        if(KEY0==0)       return KEY0_PRES;
        else if(KEY1==0)  return KEY1_PRES;
        else if(KEY2==0)  return KEY2_PRES;
        else if(WK_UP==1) return WKUP_PRES;          
    }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
    return 0;   //无按键按下

}
二、led.c(GPIO口的初始化、LED灯的基本功能)

请看LED跑马灯实验讲解


三、key.h

保护头文件

#ifndef _KEY_H
#define _KEY_H

#include "sys.h"

定义宏变量也就是 HAL_GPIO_ReadPin读取的参数传递给KEY0 ,看到这是不是对KEY.C文件中的操作就明白了

#define KEY0        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3)  //KEY0按键PH3
#define KEY1        HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2)  //KEY1按键PH2
#define KEY2        HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13) //KEY2按键PC13
#define WK_UP       HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)  //WKUP按键PA0

定义宏常亮,就是为了分成四个实验 到时候与swtich case 联动
#define KEY0_PRES     1
#define KEY1_PRES        2
#define KEY2_PRES        3
#define WKUP_PRES   4

声明你在.c文件中的函数
void KEY_Init(void);
u8 KEY_Scan(u8 mode);

#endif
四、led.h

请看LED跑马灯实验讲解

五、main.c(GPIO口的初始化、LED灯的基本功能)

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"

定义主函数
int main(void)
{

调用函数

    u8 key;
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    LED_Init();                     //初始化LED
    KEY_Init();                     //初始化按键

    构造一个死循环
    while(1)
    {

key是一个返回值 switch通过判断KEY的值来选择事件

        key=KEY_Scan(0);            //按键扫描
                switch(key)
                {                
                    case  WKUP_PRES:    //控制LED0,LED1互斥点亮
                                LED1=!LED1;
                                LED0=!LED1;
                                break;
                    case  KEY2_PRES:    //控制LED0翻转
                                LED0=!LED0;
                                break;
                    case  KEY1_PRES:    //控制LED1翻转    
                                LED1=!LED1;
                                break;
                    case  KEY0_PRES:    //同时控制LED0,LED1翻转
                                LED0=!LED0;
                                LED1=!LED1;
                                break;
            }
        delay_ms(10);
    }
}



【STM32F429单片机学习】单片机学习之按键实验的评论 (共 条)

分享到微博请遵守国家法律