标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别

点亮一个LED灯:是直接控制输出引脚,GPIO初始化推挽输出即可

按键控制LED:是按键输入信号从而控制输出引脚,GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入

但是控制GPIO本质还是1.RCC时钟使能  2.结构体配置GPIO寄存器  3.控制GPIO

标准库写法

led.c

1.RCC时钟使能  2.结构体配置GPIO寄存器  3.控制GPIO(我们这里封装成函数ON;OFF;swtich)

#include "stm32f10x.h"                  // Device header
#include "delay.h"
void LED_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//1.RCC时钟使能GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);			 	//2.结构体配置GPIO寄存器GPIO_SetBits (GPIOA,GPIO_Pin_1 | GPIO_Pin_2);			//3.控制GPIO值为1
}/*** @brief  LED1灯亮* @param  无* @retval 无*/
void LED1_ON(void)
{GPIO_ResetBits (GPIOA,GPIO_Pin_1);			//控制LED1亮
}/*** @brief  LED2灯亮* @param  无* @retval 无*/
void LED2_ON(void)
{GPIO_ResetBits (GPIOA,GPIO_Pin_2);			//控制LED2亮
}/*** @brief  LED灭* @param  无* @retval 无*/
void LED1_OFF(void)
{GPIO_SetBits (GPIOA,GPIO_Pin_1);			//控制LED1灭
}/*** @brief  LED灭* @param  无* @retval 无*/
void LED2_OFF(void)
{GPIO_SetBits (GPIOA,GPIO_Pin_2);			//控制LED2灭
}/*** @brief  LED1灯状态切换* @param  无* @retval 无*/
void LED1_switch(void)
{if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 1){GPIO_ResetBits (GPIOA,GPIO_Pin_1);}else{GPIO_SetBits (GPIOA,GPIO_Pin_1);}
}/*** @brief  LED2灯状态切换* @param  无* @retval 无*/
void LED2_switch(void)
{if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == Bit_SET){GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);}else{GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);}
}

led.h

#ifndef __LED_H
#define __LED_Hvoid LED_Init(void);
void LED1_ON(void);
void LED2_ON(void);
void LED1_OFF(void);
void LED2_OFF(void);
void LED1_switch(void);
void LED2_switch(void);#endif

key.c

这里按键获取函数采用的是delay检测,是阻塞式的函数,这不好等学到定时器中断我们再用定时器定时检测

    if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
    {
        Delay_ms(20);    //按下消抖
        while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
        Delay_ms(20);    //松开消抖
        keynum = 1;
    }

#include "stm32f10x.h"                  // Device header
#include "DELAY.h"
void KEY_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//1.RCC时钟使能GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);			 	//2.结构体配置GPIO寄存器}/*** @brief  按键获取函数* @param  无* @retval 按键值1->PB1,2->pb11*/
uint8_t KEY_Getstate(void)
{uint8_t keynum = 0;if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0){Delay_ms(20);	while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);Delay_ms(20);keynum = 1;}if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0){Delay_ms(20);	while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0);Delay_ms(20);	keynum = 2;}		return keynum;
}

key.h

#ifndef __KEY_H
#define __KEY_Hvoid KEY_Init(void);
uint8_t KEY_Getstate(void);
#endif

main()

定义一个变量把按键状态接收,通过不同按键值来控制LED状态

#include "stm32f10x.h"                  // Device header
#include "Delay.h"  
#include "LED.h"
#include "KEY.h"uint8_t keynum;
int main ()
{KEY_Init();LED_Init();while(1){keynum = KEY_Getstate();if(keynum == 1){LED1_switch();}else if(keynum == 2){LED2_switch();}}
}

标准库写完了,接下来我们写HAL库

HAL库分三步

1.建工程

2.设配置

3.写代码

HAL库写法

一. 关于建工程请参考:江科大学习笔记之——HAL库点亮一个LED灯-CSDN博客在里面有详细步骤,简单易懂

二.配置设置

这里我设置错了应该是PB11,你们自己注意一下

ctrl+s生成代码

三.写代码

为了方便我们把LED,KEY单独拿出来放在System文件夹下

在cubeIDE里面想建立自己的.C.H文件步骤如下

1.建立文件夹

2.

 鼠标右键点击文件名–Properties

3. 进入Includes 添加文件的路径

同时还要增加源文件的路径

好准备工作做完了,上面cube ide的模块化是我自己在网上找半天才找到的方法:

STM32CubemxIDE 导入自定义的.c和.h文件_stm32cubeide添加源文件-CSDN博客

本想问别人但是想想还是提高自己解决问题的能力吧,所以我就花了更多时间去自己搜索解决方法。

现在开始写代码

模块代码的逻辑都一样只是把标准库的函数我就不多赘述了,换成了HAL库的函数

led.c

这里LED灯的熄灭与点亮有,电平翻转函数HAL_GPIO_TogglePin,关于HAL库的函数可以看:

HAL库函数合集-CSDN博客


#include "gpio.h"/*** @brief  LED1灯亮* @param  无* @retval 无*/
void LED1_ON(void)
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//控制LED1亮
}/*** @brief  LED2灯亮* @param  无* @retval 无*/
void LED2_ON(void)
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);	//控制LED2亮
}/*** @brief  LED灭* @param  无* @retval 无*/
void LED1_OFF(void)
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);//控制LED1灭
}/*** @brief  LED灭* @param  无* @retval 无*/
void LED2_OFF(void)
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);//控制LED2灭
}/*** @brief  LED1灯状态切换* @param  无* @retval 无*/
void LED1_switch(void)
{HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
}/*** @brief  LED2灯状态切换* @param  无* @retval 无*/
void LED2_switch(void)
{HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);
}

led.h

#ifndef __LED_H
#define __LED_Hvoid LED1_ON(void);
void LED2_ON(void);
void LED1_OFF(void);
void LED2_OFF(void);
void LED1_switch(void);
void LED2_switch(void);#endif

key,c


#include "gpio.h"
/*** @brief  按键获取函数* @param  无* @retval 按键值1->PB1,2->pb11*/
uint8_t KEY_Getstate(void)
{uint8_t keynum = 0;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0){HAL_Delay(20);while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0);HAL_Delay(20);keynum = 1;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == 0){HAL_Delay(20);while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11) == 0);HAL_Delay(20);keynum = 2;}		return keynum;
}

key.h

#ifndef __KEY_H
#define __KEY_Huint8_t KEY_Getstate(void);
#endif

main()

这里就定义了uint8_t keynum;

然后写了while,其他都是生产的代码

  while (1){keynum = KEY_Getstate();if(keynum == 1){LED1_switch();}else if(keynum == 2){LED1_OFF();}
}
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t keynum;
/* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){keynum = KEY_Getstate();if(keynum == 1){LED1_switch();}else if(keynum == 2){LED1_OFF();}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

编译烧入现象和标准库一致

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot525基于MVC框架自习室管理和预约系统设计与实现(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装自习室管理和预约系统软件来发挥其高效地信息处理的作用&am…

Unity Canvas中显示粒子特效

首先在场景中新建一个粒子特效 修改一下参数 1.改变粒子特效的渲染层级,层级修改为UI层,由UI相机渲染 使用粒子特效的Sorting Layer ID和Order In Layer,Sorting Layer ID设置为UI(如果没有UI层则新建就好了),对UI进行排序 对于要显示在前的UI组件添加Canvas组件,设置O…

Linux下部署Redis集群 - 一主二从三哨兵模式

三台服务器redis一主二从三哨兵模式搭建 最近使用到了redis集群部署,使用一主二从三哨兵集群部署redis,将自己部署的过程中的使用心得分享给大家,希望大家以后部署的过程减少一些坑。 服务器准备 3台服务器 ,确定主redis和从red…

服务器端请求伪造之基本介绍

一.服务器端请求伪造漏洞基础 1.客户端请求 客户端请求指的是由客户端设备(如个人计算机、智能手机、平板电脑等)或软件(浏览器、各种APP)发出的请求,以获取指定的网页、图片、视频或其他资源。比如当用户在浏览器中输…

akamai3.0反爬教程逆向分析9个视频汇总

目录 一、akamai2.0文章二、akamai3.0每月疑似改版点二、9个视频汇总如下 一、akamai2.0文章 文章1cookie反爬之akamai_2.0-上文章2cookie反爬之akamai_2.0-上文章3cookie反爬之akamai_2.0-上文章中akamai2.0对应调试html与js文件 二、akamai3.0每月疑似改版点 详细文字与2.…

2024年12月 Scratch 图形化(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共25题,共50分) 第 1 题 小猫初始位置和方向如下图所示,下面哪个选项能让小猫吃到老鼠?( ) A. B. C.

【74LS160+74LS273DW锁存器8位的使用频率计】2022-7-12

缘由 想知道这个数字频率计仿真哪里出现错误了,一直无法运行哎,如何解决?-运维-CSDN问答

系统思考—信任

《基业长青》作者指出:“在人生的重要十字路口,选择信任是一场赌注。信任带来的好处可能巨大,而失去信任的代价却相对有限。但如果选择不信任,最优秀的人才可能因失望而离开。” 在企业管理中,信任不仅是人际关系的纽…

推理加速:投机采样经典方法

一 SpecInfer 基于模型 SpecInfer([2305.09781] SpecInfer: Accelerating Generative Large Language Model Serving with Tree-based Speculative Inference and Verification) SpecInfer 投机采样利用多个小型模型(SSM)快速生…

深入理解Java中的Set集合:特性、用法与常见操作指南

一、HashSet集合 1.HashSet集合的特点 2.HashSet常用方法 ①:add(Object o):向Set集合中添加元素,不允许添加重复数据。 ②:size():返回Set集合中的元素个数 ③.remove(Object o): 删除Set集合中的obj对…

黑马Java面试教程_P10_设计模式

系列博客目录 文章目录 系列博客目录前言1. 工厂方法模式1.1 概述1.2 简单工厂模式1.2.1 结构1.2.2 实现1.2.3 优缺点 1.3 工厂方法模式1.3.1 概念1.3.2 结构1.3.3 实现1.3.4 优缺点 1.4 抽象工厂模式1.4.1 概念1.4.2 结构1.4.3 实现1.4.4 优缺点1.4.5 使用场景 总结&#xff0…

开源架构的容器化部署优化版

上三篇文章推荐: 开源架构的微服务架构实践优化版(New) 开源架构中的数据库选择优化版(New) 开源架构学习指南:文档与资源的智慧锦囊(New) 我管理的社区推荐:【青云交社区…

SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)

一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…

【每日学点鸿蒙知识】导入cardEmulation、自定义装饰器、CallState状态码顺序、kv配置、签名文件配置

1、HarmonyOS 无法导入cardEmulation? 在工程entry mudule里的index.ets文件里导入cardEmulation失败 可以按照下面方式添加SystemCapability;在src/main/syscap.json(此文件需要手动创建)中添加如下内容 {"devices": {"gen…

Datawhale AI冬令营(第二期)动手学AI Agent--Task3:学Agent工作流搭建,创作进阶Agent

目录 一、工作流:制作复杂Agent的福音! 二、支付宝百宝箱中工作流介绍 三、设计工作流 3.1 准备功能模块 3.2组合工作流 3.3 模块测试需要注意什么 3.4迭代优化 四、高中学习小助手工作流设计 4.1 选题调研 4.2 功能模块设计 4.3 组合完整工作…

Postman[8] 断言

1.常见的断言类型 status code: code is 200 //检查返回的状态码是否为200 Response body: contain string //检查响应中包含指定字符串包含指定的值 response body:json value check/ /检查响应中其中json的值 Response body: is equal to string …

python openyxl 用法 教程

Python自动化办公:openpyxl教程(基础)-CSDN博客 https://zhuanlan.zhihu.com/p/342422919 https://openpyxl-chinese-docs.readthedocs.io/zh-cn/latest/tutorial.html 列标题,是这一列 对应的单元格的格式,默认是常规,设置之后…

深入解析 Wireshark 的 TLS 设置:应用场景与实操技巧

简述 在网络数据分析中,传输层安全(TLS)协议的流量解密和分析是一项重要的技能。Wireshark 提供了专门的设置选项,帮助用户处理 TLS 流量,例如解密会话、重组分片等。本文将详细解析上图所示的 Wireshark TLS 设置功能…

每天五分钟机器学习:凸集

本文重点 在SVM中,目标函数是一个凸函数,约束集合是一个凸集。因此,SVM问题可以转化为一个凸规划问题来求解。这使得SVM在实际应用中具有较高的计算效率和准确性。 凸集的定义 凸集是指一个集合中的任意两点之间的线段都完全包含在这个集合中。换句话说,给定集合C中的两…

stm32 智能语音电梯系统

做了个stm32智能语音控制的电梯模型,总结一下功能,源码用ST的HAL库写的,整体流程分明。 实物图 这个是整个板子的图片,逻辑其实并不复杂,只是功能比较多,在我看来都是一些冗余的功能,但也可能是…