STM32F4 | 按键输入实验

news2024/12/27 2:31:20

文章目录

    • 一、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->LED 文件夹下面新建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是下拉输入
	//初始化GPIOA
	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);
	
	//初始化GPIOC
	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);
	
	//初始化GPIOH
	//由于GPIOH与GPIOC的Mode、Pull、Speed配置一样,因此可以省略
	GPIO_Initure.Pin = GPIO_PIN_2 | GPIO_PIN_3;	//PH2,PH3
	HAL_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); //设置时钟180MHz
	delay_init(180);	//初始化延时函数
	uart_init(115200);	//初始化USART
	LED_Init();		//初始化LED
	KEY_Init();		//初始化按键
	
	while (1)
	{
		key = KEY_Scan(0);	//单次按键扫描
		
		switch (key)
		{
			case KEYUP_PRES: //控制 LED0,LED1 互斥点亮
				LED1=!LED1;
				LED0=!LED0;
				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 函数内容,替换后会发现实现现象完全一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/86976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

成功的项目管理需要做好哪些方面?

每一个项目都代表了为公司建立同行竞争优势和提高利润的方式,成功交付的项目会将公司与那些竞争激烈的公司区分开来。而项目的成功取决于不同的因素。这也是项目经理所需要关注的问题,在每一个项目成功标准方面保持一致可以消除项目失败的风险&#xff0…

【数据库课程设计】SQLServer数据库课程设计(学生宿舍管理),课设报告+源码+数据库关系图

数据库课程设计——学生宿舍管理,需要全部源码可以关注私信我,把邮箱发在评论区前言一、课题背景和开发环境1、课题背景2、开发环境二、系统功能及示意图1、系统实现功能2、功能示意图2.1学生模块2.2管理人员模块三、概念结构设计1、管理员分配宿舍E_R图…

传染病模型3

一、研究方向 建立传染病的数学模型描述传染病的传播过程 分析感染人数的变化规律,预测传染病高峰的到来 探索控制、根除、预防传染病传播蔓延的手段 二、舱室 流行病学中的一大类模型,称为“舱室”模型,它是将人群分成若干个“舱室…

为什么机器码、汇编不可移植,而C语言可以移植?

1、机器码不可移植的原因 机器码(二进制)是处理器能直接识别的语言,不同的机器码代表不同的运算指令,处理器可以识别哪些机器码是由处理器的硬件设备决定的,不同的处理器机器码可能不同。 比如在ARM处理器上加法可能…

Linux 线程池

文章目录线程池的定义使用线程池的原因基于POSIX实现的线程池基于block队列的线程池实现基于ring队列的线程池实现设计单例模式线程池线程池的定义 线程池就一堆已经创建好的任务线程,初始它们都处于空闲等待状态,当有新的任务需要处理的时候&#xff0…

大话设计模型 Task01:设计原则

目录1. 单一职责原则(SRP)使用动机如何使用2. 开闭原则(OCP)使用动机如何使用使用原则3. 依赖倒置原则(DIP)使用动机使用原则4. 里氏替换原则(LSP)使用动机5. 迪米特法则&#xff08…

12、MInio文件系统的使用小记一

前言:文档存储从最初的文本文档发展到现在的图片视频存储,存储容器也从数据库演变成了文件系统,目前市面上提供云存储的公司很多,百度腾讯阿里华为等,这些公司都有成熟的文件存储方案及restapi接口,很方便&…

Docker-网络配置

目录 一,网络模式 1.bridge模式(默认模式) 2.host模式 二,bridge模式 三,host模式 网络模式与数据卷容器挂载的操作 三,如何创建自定义网络 一,网络模式 Docker在创建容器时有四种网络模式…

Sulfo CY5-马来酰亚胺|Cyanine5 MAL菁染料CY5标记

Sulfo CY5-马来酰亚胺|Cyanine5 MAL菁染料CY5标记 Cyanine5 maleimide是单一活性染料,有选择性的与硫醇基团(比如蛋白和多肽的半胱氨酸)结合以进行标记。我们使用水溶的Sulfo-Cyanine5 maleimide标记抗体和其他敏感蛋白。Cyanine5是Cy5的类似…

web前端设计与开发期末作品_期末大作业【使用HTML制作汽车首页】

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

校园二手商品交易平台的设计与实现(J2EE)

目 录 摘要 I Abstract II 目录 III 1 绪论 1 1.1 课题研究背景及意义 1 1.2 本课题主要工作 1 2 系统相关技术 3 2.1 J2EE技术 3 2.2 MVC模式 4 2.3 B/S结构 4 2.4 数据库技术 4 3 系统需求分析 6 3.1 用户功能需求 6 3.2 系统可行性分析 6 3.2.1 技术可行性 6 3.2.2 经济可行…

Qt扫盲-QComboBox理论总结

QComboBox理论总结1. 简述2. 显示内容3. 信号4. 常用功能5. model/view 使用1. 简述 QComboBox 提供了一种以占用最小屏幕空间的方式向用户显示选项列表的方法。QCombox是显示当前项目的选择小部件,可以弹出可选项目的列表。QComBox其实就是一个下拉列表。选择的项…

做短视频开直播要不要买流量?

我是卢松松,点点上面的头像,欢迎关注我哦! 做短视频要不要买流量,开直播要不要买流量,买了流量以后是不是就要一直买,不买就没有免费流量了? 在这儿给大家普及一下这件事: 在买流量之前呢&…

一种多臂PEG衍生物——8-Arm peg-Biotin,8-Arm PEG-Biotin,八臂PEG生物素

英文名称:8-Arm peg-Biotin 中文名称:八臂-聚乙二醇-生物素 8臂PEG生物素是一种多臂PEG衍生物,在连接到一个六甘油核心的八个臂的每个末端具有生物素基团。PEG生物素可通过与链霉亲和素和抗生物素结合进行聚乙二醇化,具有高亲和…

python语言Django框架搭建学生信息管理系统

1.系统介绍 本系统是基于Django 2.2.3开发的,面向学生信息管理系统。 系统以学生个体为核心向外拓展诸如宿舍、班级、学生组织等一系列组,诸如请假、签到、通知发布等一系列应用。 计划内实现功能有:班级、学生、宿舍三大项为基础的信息管理系统,早检、晨跑、卫检及相应…

ASFormer:Transformer for Action Segmentation论文阅读笔记

摘要 为了解决动作分割类问题,作者设计了一个高效的基于transformer的动作分割任务模型,ASFormer,该模型具有以下三个特征: (i)由于特征的高局部性,作者明确地引入了局部连通性归纳先验。它将假…

经典文献阅读之--Swin Transformer

0. 简介 Transfomer最近几年已经霸榜了各个领域,之前我们在《经典文献阅读之–Deformable DETR》这篇博客中对DETR这个系列进行了梳理,但是想着既然写了图像处理领域的方法介绍,正好也按照这个顺序来对另一个非常著名的Swin Transformer框架…

Qt-Web混合开发-QWebEnginePage权限管理(3)

Qt-Web混合开发-使用QWebEnginePage打开摄像头演示权限管理🏳️‍🌈 文章目录Qt-Web混合开发-使用QWebEnginePage打开摄像头演示权限管理🏳️‍🌈1、概述🚩2、实现效果🥽3、实现功能🔊4、关键代…

PodSummPreSumm

PodSumm:播客音频摘要 论文地址 简介 最近播客的流行给现有的内容发现和推荐系统带来了巨⼤的机遇和⼀系列独特的挑战。与听音乐不同,播客通常需要听众长时间积极关注。演讲者的演讲风格、幽默类型或制作质量等主观属性可能会影响听众的偏好&#xff…

CVPR2022 | 动作识别框架新范式 STRM,用最小的样本获得最高的精度

论文题目:Spatio-temporal Relation Modeling for Few-shot Action Recognition 论文连接:https://arxiv.org/abs/2112.05132v2 代码连接:https://github.com/Anirudh257/strm 综述 我们提出了一种few-shot动作识别框架STRM,它…