STM32F4 | 按键输入实验
创始人
2024-04-24 16:28:29
0

文章目录

    • 一、STM32F4 IO 口简介
    • 二、硬件设计
    • 三、软件设计
    • 四、实验现象
    • 五、STM32CubeMX 配置 IO 口输出

  这一章,我们将通过 ALIENTEK阿波罗 STM32 开发板上载有的 4 个按钮( KEY_UPKEY0KEY1KEY2),来控制板上的 2 个 LEDDS0DS1),其中 KEY_UP 控制 DS0DS1 互斥点亮; KEY2 控制 DS0,按一次亮,再按一次灭; KEY1 控制 DS1,效果同 KEY2KEY0 则同时控制 DS0DS1,按一次,他们的状态就翻转一次。

一、STM32F4 IO 口简介

  这部分内容可参考STM32F4 | GPIO工作原理和配置。STM32F4IO 口做输入使用的时候,是通过调用函数 HAL_GPIO_ReadPin ()来读取 IO 口的状态的。

二、硬件设计

  本实验用到的硬件资源有:

  • 指示灯 DS0DS1
  • 4 个按键:KEY0KEY1KEY2、和 KEY_UP

在阿波罗 STM32 开发板上的按键 KEY0 连接在 PH3 上、KEY1 连接在 PH2 上、KEY2 连接在 PC13 上、KEY_UP 连接在 PA0上。如图所示:
在这里插入图片描述
这里需要注意的是:KEY0KEY1KEY2 是低电平有效的(按下是低电平),而 KEY_UP 是高电平有效的(按下是高电平),并且外部都没有上下拉电阻,所以,需要在 STM32F429 内部设置上下拉。输入模式配置如下

  • PH3:上拉输入
  • PH2:上拉输入
  • PC13:上拉输入
  • PA0:下拉输入

三、软件设计

  我们直接复制上一个实验的工程模板,将复制过来的模板文件夹重新命名为“2-按键实验”。在HARDWARE->KEY 文件夹下面新建key.c 文件以及头文件 key.h
  打开key.c文件,代码如下:

#include "key.h"
#include "delay.h"/*
函数名称:KEY_Init
函数功能:初始化按键输入实验所用到的IO口
输	  入:无
输     出:无
*/
void KEY_Init(void)
{//定义结构体变量GPIO_InitTypeDef GPIO_Initure;//使能按键对应IO口的时钟__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();//初始化IO口;H2和H3是上拉输入,C13是上拉输入;A0是下拉输入//初始化GPIOAGPIO_Initure.Pin = GPIO_PIN_0;	//PA0GPIO_Initure.Mode = GPIO_MODE_INPUT; //输入GPIO_Initure.Pull = GPIO_PULLDOWN;	//下拉GPIO_Initure.Speed = GPIO_SPEED_HIGH;	//高速HAL_GPIO_Init(GPIOA,&GPIO_Initure);//初始化GPIOCGPIO_Initure.Pin = GPIO_PIN_13;	//PC13GPIO_Initure.Mode = GPIO_MODE_INPUT; //输入GPIO_Initure.Pull = GPIO_PULLUP;	//上拉GPIO_Initure.Speed = GPIO_SPEED_HIGH;	//高速HAL_GPIO_Init(GPIOC,&GPIO_Initure);//初始化GPIOH//由于GPIOH与GPIOC的Mode、Pull、Speed配置一样,因此可以省略GPIO_Initure.Pin = GPIO_PIN_2 | GPIO_PIN_3;	//PH2,PH3HAL_GPIO_Init(GPIOH,&GPIO_Initure);}/*
函数名称:KEY_Scan
函数功能:按键处理函数
输   入:mode:0,表示不支持连续按;mode:1,表示支持连续按
输   出:0,表示没有任何按键按下;...
注意:此函数有响应优先级,KEY0>KEY1>KEY2>KEY_UP
*/
u8 KEY_Scan(u8 mode)
{static u8 key_up = 1;	//按键松开标志if (mode==1)	key_up=1;	//支持连按if (key_up && (KEY0==0 || KEY1==0 || KEY2==0 || KEY_UP==1)){delay_ms(10); //延时key_up=0; //标记这次key已经按下if (KEY0==0)		return KEY0_PRES;else if (KEY1==0)	return KEY1_PRES;else if (KEY2==0)	return KEY2_PRES;else if (KEY_UP==1) return KEYUP_PRES;}//KEY键没有按下else if (KEY0==1 || KEY1==1 || KEY2==1 || KEY_UP==0){key_up=1;}return 0;	//无按键按下
}

  KEY_Scan 函数,则是用来扫描这 4 个 IO 口是否有按键按下。KEY_Scan 函数,支持两种扫描方式,通过 mode 参数来设置。

  • mode 为 0 的时候,KEY_Scan 函数将不支持连续按,扫描某个按键,该按键按下之后必须要松开,才能第二次触发,否则不会再响应这个按键,这样的好处就是可以防止按一次多次触发,而坏处就是在需要长按的时候比较不合适。
  • mode 为 1 的时候,KEY_Scan 函数将支持连续按,如果某个按键一直按下,则会一直返回这个按键的键值,这样可以方便的实现长按检测。

  其头文件key.h为:

#ifndef _KEY_H
#define _KEY_H#include "sys.h"//STM32F4的IO口做输入使用的时候,是通过调用函数HAL_GPIO_ReadPin ()来读取 IO口的状态的
#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 KEY_UP HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) //WKUP 按键 PA0//宏定义独立按键按下的值
#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define KEYUP_PRES 4//声明函数
void KEY_Init(void);
u8 KEY_Scan(u8 mode);#endif

  打开主函数main.c,代码如下:

/*
实验2:按键输入实验
实验现象:`KEY_UP` 控制 `DS0`,`DS1` 互斥点亮;`KEY2` 控制 `DS0`,按一次亮,再按一次灭;`KEY1` 控制 `DS1`,效果同 `KEY2`;`KEY0` 则同时控制 `DS0` 和 `DS1`,按一次,他们的状态就翻转一次。
*/
#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); //设置时钟180MHzdelay_init(180);	//初始化延时函数uart_init(115200);	//初始化USARTLED_Init();		//初始化LEDKEY_Init();		//初始化按键while (1){key = KEY_Scan(0);	//单次按键扫描switch (key){case KEYUP_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 翻转LED1=!LED1;LED0=!LED0;break;}delay_ms(10);}}

四、实验现象

  使用 USB 线将开发板和电脑连接成功后(电脑能识别开发板上 CH340 串口),把编译后产生的.hex 文件烧入到芯片内。
在这里插入图片描述

实验现象KEY_UP 控制 DS0DS1 互斥点亮;KEY2 控制 DS0,按一次亮,再按一次灭;KEY1 控制 DS1,效果同 KEY2KEY0 则同时控制 DS0DS1,按一次,他们的状态就翻转一次。

  • 按下KEY1
    在这里插入图片描述

  • 按下KEY2
    在这里插入图片描述

  • 按下KEY0
    在这里插入图片描述

  • 按下KEY_UP
    在这里插入图片描述

五、STM32CubeMX 配置 IO 口输出

  阿波罗开发板上有 4 个按键,分别连接四个 IO 口 PA0PC13PH2PH3。其中 WK_UP 按键按下后对应的 PA0 输入为高电平,所以默认情况下,该 IO 口(PA0)要初始化为下拉输入,其他 IO 口初始化为上拉输入即可。
  使用 STM32CubeMX 打开光盘工程模板(双击工程目录的 Template.ioc),我们首先在 IO 口引脚图上,依次设置四个 IO 口为输入模式 GPIO_Input。这里我们以 PA0 为例,操作方法如下图所示:
在这里插入图片描述
同样的方法,我们依次配置 PC13PH2PH3 为输入模式。然后我们进入Configuration->GPIO 配置界面,配置四个 IO 口详细参数。在配置界面点击 PA0 可以发现,当我们在前面设置 IO 口为输入 GPIO_Input 之后,其配置参数只剩下模式 GPIO Mode 和上下拉GPIO Pull-up/Pull-down,并且模式值中只有输入模式 Input Mode 可选。这里,我们配置 PA0 为下拉输入,其他三个 IO 口配置为上拉输入即可。配置方法如下图所示:
在这里插入图片描述
配置完成 IO 口参数之后,接下来我们同样生成工程。打开生成的工程会发现,main.c 文件中添加了函数 MX_GPIO_Init 函数,内容如下:

/** Configure pins as * Analog * Input * Output* EVENT_OUT* EXTI
*/
void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin : PC13 */GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pin : PA0 */GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/*Configure GPIO pins : PH2 PH3 */GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);}

该函数实现的功能和按键输入实验中 KEY_Init 函数实现的功能一模一样。将该函数内容替换按键输入实验中的 KEY_Init 函数内容,替换后会发现实现现象完全一致

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...