GD32零基础教程第四节(按键控制LED灯)

2024-04-09 00:52

本文主要是介绍GD32零基础教程第四节(按键控制LED灯),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、按键电路图分析及控制原理
  • 二、按键控制LED灯代码编写
  • 三、模块化封装按键代码
  • 总结


前言

本篇文章将带大家来学习按键的使用,按键其实也就是GPIO的控制,只不过按键的使用需要将GPIO配置为输入模式。

一、按键电路图分析及控制原理

在单片机中,按键通常用于实现用户交互和控制功能。

按键元件:

按键通常由一个机械开关组成,当按键被按下时,开关闭合,允许电流流过。

在板子上有一个用户按键,可供用户使用。

根据原理图可知这个按键接到了PA0引脚,当按键被按下时WK_UP接到了VCC,所以当按键被按下时表现为高电平,但是按键没有被按下时电平状态是不确定的。

所以这里需要接入下拉电阻,下面是接下拉电阻的原因:

稳定的逻辑状态:

当按键未被按下时,输入端口需要保持一个确定的逻辑状态,以确保系统正确地读取输入信号。接下拉电阻将输入端口连接到地(GND),使得在按键未被按下时,输入端口被拉低到逻辑低电平(0),从而保持稳定的逻辑状态。
防止悬空状态:

如果没有接下拉电阻,当按键未被按下时,输入端口将处于悬空状态,容易受到外部环境的干扰而导致不确定的电平状态。这可能导致系统误判按键状态,引发错误的操作或行为。

在这里插入图片描述
在这里插入图片描述

二、按键控制LED灯代码编写

1.使能对应的GPIO引脚:

rcu_periph_clock_enable(RCU_GPIOA);//使能GPIOA时钟

2.将GPIO引脚设置为输入模式,并且设置一个下拉电阻:

gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);

3.读取GPIO引脚的状态:

FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)

函数参数:
gpio_periph:要操作的GPIO外设,通常是使用宏定义指定的GPIOx(x表示具体的GPIO端口,如GPIOA、GPIOB等)。
pin:要获取状态的GPIO引脚,通常是使用宏定义指定的引脚编号(如GPIO_PIN_0、GPIO_PIN_1等)。

返回值:
FlagStatus类型,是一个枚举类型,可能的取值有:
RESET:表示引脚未置位,即为低电平状态。
SET:表示引脚被置位,即为高电平状态。

具体代码:

#include "gd32f4xx.h"//包含了该系列芯片的寄存器定义、常量定义和函数声明等信息
#include "gd32f4xx_libopt.h"//GD32F4 系列芯片的外设库选项配置文件
#include "systick.h"//配置和使用 SysTick 定时器的功能文件#include "led.h"static int flag = 0;//定义一个变量来表示LED灯当前的状态int main(void)
{systick_config();//配置系统主频168M,外部8M晶振,配置在#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)LED_Init();//初始化LED灯模块LED_OFF();//关闭LED灯rcu_periph_clock_enable(RCU_GPIOA);//使能GPIOA时钟gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);//PA0配置成下拉输入	while(1){if(1 == gpio_input_bit_get(GPIOA, GPIO_PIN_0)){delay_1ms(10);//延时消抖if(1 == gpio_input_bit_get(GPIOA, GPIO_PIN_0)){flag = !flag;//翻转LED灯电平状态if(flag == 1){LED_ON();//点亮LED灯}else if(flag == 0){LED_OFF();//关闭LED灯}}}}
}

这里主要需要讲解的就是这个延时消抖部分:

按键需要延时消抖是因为机械按键在按下或释放的过程中会产生短暂的电气接触和断开,导致在按键信号上出现不稳定的波动。这种波动称为按键抖动(Bouncing),可能会导致系统误判按键操作,认为按键被按下了多次或产生了错误的按键事件。因此,需要延时消抖来确保稳定地检测按键状态。

按键被按下的理想状态:

在这里插入图片描述

按键被按下的实际状态:

在这里插入图片描述

三、模块化封装按键代码

在HardWare文件夹中创建key.c和key.h两个文件来保存按键的代码:

key.c:

/*** @file    key.c* @brief   KEY功能函数实现文件* @author  花落已飘* @date    2024-04-08*/#include "key.h"
#include "systick.h" // 包含用于延时的头文件/*** @brief 初始化按键* @note  使能按键对应 GPIO 端口的时钟,并设置按键引脚为输入模式,并启用下拉电阻*/
void KEY_Init(void)
{KEY_PORT_CLK_EN(); // 使能按键对应 GPIO 端口的时钟gpio_mode_set(KEY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, KEY_PIN); // 设置按键引脚为输入模式,并启用下拉电阻
}/*** @brief 获取按键状态* @note  如果按键被按下,进行延时消抖后再次检测按键状态* @return 按键状态,KEY_PRESS 表示按键被按下,KEY_RELEASE 表示按键未被按下*/
int GetKeyStatus(void)
{KEY_STATUS key_status = KEY_RELEASE; // 初始化按键状态为释放状态if (1 == gpio_input_bit_get(GPIOA, GPIO_PIN_0)) // 如果检测到按键被按下{delay_1ms(10); // 延时消抖,等待按键稳定if (1 == gpio_input_bit_get(GPIOA, GPIO_PIN_0)) // 再次检测按键状态{key_status = KEY_PRESS; // 如果按键仍然处于按下状态,则更新按键状态为按下}else{key_status = KEY_RELEASE; // 如果按键已经释放,则更新按键状态为释放}}return key_status; // 返回按键状态
}

key.h:

#ifndef KEY_H
#define KEY_H#include "gd32f4xx.h"        // 包含了该系列芯片的寄存器定义、常量定义和函数声明等信息
#include "gd32f4xx_libopt.h" // GD32F4 系列芯片的外设库选项配置文件#define KEY_PORT     GPIOA     // 按键所在的 GPIO 端口
#define KEY_PIN      GPIO_PIN_0 // 按键所在的引脚编号
#define KEY_CLOCK    RCU_GPIOA // 按键对应的时钟使能#define KEY_PORT_CLK_EN()  rcu_periph_clock_enable(KEY_CLOCK) // 使能按键对应 GPIO 端口的时钟typedef enum
{KEY_PRESS = 0,   // 按键被按下KEY_RELEASE      // 按键未被按下
} KEY_STATUS;         // 定义按键状态枚举类型/*** @brief 初始化按键 GPIO 端口* @note  初始化按键所在的 GPIO 端口为输入模式,并设置上下拉电阻为下拉*/
void KEY_Init(void);/*** @brief 获取按键状态* @note  如果按键被按下,进行延时消抖后再次检测按键状态* @return 按键状态,KEY_PRESS 表示按键被按下,KEY_RELEASE 表示按键未被按下*/
int GetKeyStatus(void);#endif

main.c中调用:

#include "gd32f4xx.h"//包含了该系列芯片的寄存器定义、常量定义和函数声明等信息
#include "gd32f4xx_libopt.h"//GD32F4 系列芯片的外设库选项配置文件
#include "systick.h"//配置和使用 SysTick 定时器的功能文件//硬件初始化代码
#include "led.h"
#include "key.h"static int flag = 0;//定义一个变量来表示LED灯当前的状态int main(void)
{systick_config();//配置系统主频168M,外部8M晶振,配置在#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)LED_Init();//初始化LED灯模块KEY_Init();//初始化KEY按键模块LED_OFF();//关闭LED灯while(1){if(KEY_PRESS == GetKeyStatus()){flag = !flag;if(flag == 1){LED_ON();}else if(flag == 0){LED_OFF();}}}
}

总结

本篇文章就讲解到这里,主要是按键的输入模式的使用。

但是在这里代码还是有非常多不足的地方,比如延时会阻塞程序的运行,降低CPU的执行效率。

以及没有及时的读取按键的数据导致数据的丢失等问题,后面的文章也会讲解到解决这些问题的方法。

链接:https://pan.baidu.com/s/10J6bdHrFWlSY-SFLW8hlNw
提取码:abvi

这篇关于GD32零基础教程第四节(按键控制LED灯)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/886803

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b

【电机控制】数字滤波算法(持续更新)

文章目录 前言1. 数字低通滤波 前言 各种数字滤波原理,离散化公式及代码。 1. 数字低通滤波 滤波器公式 一阶低通滤波器的输出 y [ n ] y[n] y[n] 可以通过以下公式计算得到: y [ n ] = α x [ n ] + ( 1 − α ) y [ n − 1 ] y[n] = \alpha x[n] + (1 - \alpha) y[n-1]

物联网之流水LED灯、正常流水灯、反复流水灯、移动流水灯

MENU 硬件电路设计软件程序设计正常流水LED灯反复流水LED灯移动流水LED灯 硬件电路设计 材料名称数量直插式LED1kΩ电阻杜邦线(跳线)若干面包板1 每一个LED的正极与开发板一个GPIO引脚相连,并串联一个电阻,负极接GND。 当然也可以选择只使用一个电阻。 软件程序设计 正常流水LED灯 因为要用到多个GPIO引脚,所以最好把所有的GPI

OpenStack离线Train版安装系列—3控制节点-Keystone认证服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—1控制节点-环境准备

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

OpenStack离线Train版安装系列—10.控制节点-Heat服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版