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

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.xdnf.cn/news/15957.html

相关文章:

  • Android Navigation 组件:简化应用导航的利器
  • Nacos中feign.FeignException$BadGateway: [502 Bad Gateway]
  • Node.js- node管理工具nvm
  • ansible批量部署zabbix客户端
  • 过往记录系列 篇七:大A突破3500点历史梳理
  • 【MySQL】Linux配置MySQL Windows远程连接
  • day27 力扣332.重新安排行程 力扣51. N皇后 力扣37. 解数独 力扣455.分发饼干 力扣376. 摆动序列 力扣53. 最大子序和
  • 【爬虫】06 - 自动化爬虫selenium
  • 二分查找-35.搜索插入位置-力扣(LeetCode)
  • HTML前端颜色渐变动画完整指南
  • IFN影视官网入口 - 4K影视在线看网站|网页|打不开|下载
  • 数据结构-哈希表(一)哈希函数、哈希表介绍、优缺点
  • 解决 Ant Design v5.26.5 与 React 19.0.0 的兼容性问题
  • vue3实现可视化大屏布局
  • Redis入门教程(一):基本数据类型
  • k8s知识点
  • 3x3矩阵教程
  • 第十八节:第七部分:java高级:注解的应用场景:模拟junit框架
  • 如何用纯 HTML 文件实现 Vue.js 应用,并通过 CDN 引入 Element UI
  • Python 进阶(七):XML 基本操作
  • 【编程语言】C、C++、C#深度对比:三种语言的演进历程与应用场景
  • Java 大视界 -- 基于 Java 的大数据分布式计算在地球物理勘探数据处理与地质结构建模中的应用(356)
  • numpy库的基础知识
  • oracle 数据库中,将几张表的数据按指定日期范围实时同步至同一个数据库的备份表中。
  • CLIP与SIGLIP对比浅析
  • 小架构step系列21:参数和返回值的匹配
  • FastAPI 中,数据库模型(通常使用 SQLAlchemy 定义)和接口模型(使用 Pydantic 定义的 schemas)的差异
  • 【智能协同云图库】智能协同云图库第二期:基于腾讯云 COS 对象存储—开发图片各功能模块
  • SQLite以及Room框架的学习:用SQLite给新闻app加上更完善的登录注册功能
  • 蜂窝物联网模组市场新展望:中国企业继续保持最强竞争力