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如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python远程控制MySQL的完整指南

《Python远程控制MySQL的完整指南》MySQL是最流行的关系型数据库之一,Python通过多种方式可以与MySQL进行交互,下面小编就为大家详细介绍一下Python操作MySQL的常用方法和最... 目录1. 准备工作2. 连接mysql数据库使用mysql-connector使用PyMySQL3.

如何搭建并配置HTTPD文件服务及访问权限控制

《如何搭建并配置HTTPD文件服务及访问权限控制》:本文主要介绍如何搭建并配置HTTPD文件服务及访问权限控制的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、安装HTTPD服务二、HTTPD服务目录结构三、配置修改四、服务启动五、基于用户访问权限控制六、

MySQL精准控制Binlog日志数量的三种方案

《MySQL精准控制Binlog日志数量的三种方案》作为数据库管理员,你是否经常为服务器磁盘爆满而抓狂?Binlog就像数据库的“黑匣子”,默默记录着每一次数据变动,但若放任不管,几天内这些日志文件就... 目录 一招修改配置文件:永久生效的控制术1.定位my.cnf文件2.添加核心参数不重启热更新:高手应

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

Spring Security+JWT如何实现前后端分离权限控制

《SpringSecurity+JWT如何实现前后端分离权限控制》本篇将手把手教你用SpringSecurity+JWT搭建一套完整的登录认证与权限控制体系,具有很好的参考价值,希望对大家... 目录Spring Security+JWT实现前后端分离权限控制实战一、为什么要用 JWT?二、JWT 基本结构

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制