当前位置: 首页 > news >正文

STM32小实验四--按键控制LED灯

1.实验目的

按下 KEY1,翻转 LED1 状态;按下 KEY2 ,翻转 LED2 状态。

2.硬件清单

  • STM32
  • ST-Link

3.原理图

在这里插入图片描述

4.代码

在Drivers/BSP新建文件夹命名为key在这个文件夹中新建key.c和key.h。

4.1key.c

#include "key.h"
#include "sys.h"
#include "delay.h"
//初始化GPIO口
void key_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOA_CLK_ENABLE();                   //使能GPIOA时钟//初始化GPIO函数gpio_initstruct.Mode = GPIO_MODE_INPUT;             //输入模式gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;      //两个按键的引脚gpio_initstruct.Pull = GPIO_PULLUP;                 //上拉gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;       //高速HAL_GPIO_Init(GPIOA, &gpio_initstruct);
}//按键扫描函数
uint8_t key_scan(void)
{//检测按键1是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET ){//消抖delay_ms(10);//再次判断按键1是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET ){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){}//返回按键的值return 1;}}//检测按键2是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET ){//消抖delay_ms(10);//再次判断按键2是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET ){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){}//返回按键的值return 2;}}//如果前面情况都不是返回默认值return 0;}

初始化GPIO和之前一样,但是模式改为输入模式(gpio_initstruct.Mode = GPIO_MODE_INPUT),gpio_initstruct.Pull = GPIO_PULLUP,这个模式是根据原理图,按键未被按下时的状态是什么,这个就是什么,因为如果按下是上拉,那么初始化时就要设置为下拉。
按键扫描函数编写的步骤:
1.检测按键是否被按下
使用HAL_GPIO_ReadPin库函数读取电平,根据原理图当按下按钮时为低电平,所以使用if语句判断HAL_GPIO_ReadPin是否等于GPIO_PIN_RESET也就是低电平。
2.消抖
就是直接延时10ms。
3.再次判断按键是否被按下
和第一次检测按键是否被按下一样。
4.如果确实是按下的状态,等待按键松开
等待按键松开的方法是使用while循环如果按键没有松开(为低电平)就一直在while循环里,如果按键松开(为高电平)就跳出while循环。
5.返回按键的值
然后使用return返回数值
6.如果前面情况都不是返回默认值
如果没有按下按键就return 0。
检测按键2是否被按下就和按键1一样只需要将pin值修改即可

4.2key.h

#ifndef __KEY_H__
#define __KEY_H__#include "sys.h"void key_init(void);
uint8_t key_scan(void);#endif

.h文件就是将函数名写进去就行,需要注意的是第二个函数的返回值是uint8_t是包含在stm32f1xx.h这个头文件中的,所以要#include “stm32f1xx.h”,又因为sys.h中也有stm32f1xx.h,所以我直接就#include "sys.h"了。

4.3main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"int main(void)
{HAL_Init();                         /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();key_init();uint8_t key_num = 0; while(1){ key_num = key_scan();if(key_num == 1){led1_toggle();}if(key_num == 2){led2_toggle();}}
}

这里面就是调用上面写好的函数,将返回值保存到key_num变量中,然后判断它的值,再进行具体操作。
注意尽量不要直接key_scan() == 1或key_scan() == 2,这样判断,因为这样判断就相当于每循环一次将要调用两次key_scan()函数,这样按键操作就有很大的延迟,所以我们之间调用一次将返回值存到一个变量中就行。
完结

http://www.lryc.cn/news/595557.html

相关文章:

  • Neo4j 5.x版本的导出与导入数据库
  • 车载软件架构 --- 软件开发面临的问题
  • DAY17 常见聚类算法
  • Spring AI 集成阿里云百炼与 RAG 知识库,实现专属智能助手(框架思路)
  • SpringSecurity 详细介绍(认证和授权)
  • 广东省省考备考(第五十二天7.21)——数量、判断推理(听课后强化训练)
  • 【qml-3】qml与c++交互第二次尝试(类型方式)
  • Android MTK平台预置多张静态壁纸
  • LinkedList与链表(单向)(Java实现)
  • 跨端分栏布局:从手机到Pad的优雅切换
  • 遗像照片尺寸要求及手机制作打印方法
  • DIDCTF-2021第三届长安杯(检材一)
  • LeetCode 每日一题 2025/7/14-2025/7/20
  • Android Studio 的 Gradle 究竟是什么?
  • 力扣刷题 -- 100.相同的树
  • 4.Java创建对象有几种方式?
  • repmgr+pgbouncer实现对业务透明的高可用切换
  • ANSYS 2025 R1软件下载及安装教程|附安装文件
  • 【实战】Dify从0到100进阶--文档解读(10)参数提取HTTP节点
  • 2025年一区SCI-回旋镖气动椭圆优化算法Boomerang Aerodynamic Ellipse-附Matlab免费代码
  • IFN影视官网入口 - 4K影视在线看网站|网页|打不开|下载
  • 【智能协同云图库】智能协同云图库第二期:基于腾讯云 COS 对象存储—开发图片各功能模块
  • next.js刷新页面时二级菜单展开状态判断
  • 234、回文链表
  • lesson20:Python函数的标注
  • CMake与catkin_make的find_package()命令使用说明
  • 基于Vue与CloudBase AI Toolkit的色觉识别Web应用开发报告:VibeCoding新范式实践
  • 14.7 Alpaca格式深度解析:3倍指令准确率提升的LLM微调秘诀
  • 工业仪表识别(一)环境安装
  • 数据结构-哈希表(一)哈希函数、哈希表介绍、优缺点