STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用
如果有什么不懂的地方欢迎私聊博主,欢迎小白,博主必一一解答。
在 STM32 中,GPIO(通用输入输出)是与外部硬件接口进行交互的主要方式之一。STM32 HAL 库提供了简洁的接口来配置和控制 GPIO 引脚。下面是使用 STM32 HAL 库进行 GPIO 操作的详细教程。
1. 环境准备
确保您已经按照以下步骤准备好开发环境:
- STM32CubeIDE 已安装。
- 创建了 STM32 项目,配置了目标 STM32 微控制器或开发板。
2. 配置 GPIO 外设
在 STM32CubeIDE 中,我们通过 STM32CubeMX 来配置 GPIO 引脚。
步骤:
- 打开 STM32CubeIDE,选择新建一个 STM32 项目。
- 在
Pinout & Configuration
页面,选择您要使用的 GPIO 引脚。例如,选择GPIOA
上的引脚如PA5
(通常用作 LED 灯),并设置为GPIO_Output
,或GPIOA
上的引脚如PA0
设置为GPIO_Input
。 - 在 Configuration 选项卡中,设置引脚的模式、输出类型等。
- 对于输出引脚,选择
Push-Pull
,并设置速率。 - 对于输入引脚,选择
Pull-up
或Pull-down
,以决定输入信号的默认状态。
- 对于输出引脚,选择
- 在 Project 设置中,选择项目名称和代码生成选项(选择 STM32CubeIDE 为 IDE,选择 HAL 库作为中间件)。
- 点击 Generate Code,STM32CubeMX 会生成初始化代码。
3. HAL 库的 GPIO 操作
生成代码后,您可以开始在 main.c
文件中编写应用程序,利用 STM32 HAL 库操作 GPIO 引脚。
GPIO 输入输出操作
1.初始化 GPIO
STM32CubeMX 会自动生成用于初始化 GPIO 的代码,您只需调用 HAL_GPIO_Init()
函数。例如,在 main.c
中可以看到类似这样的初始化代码,我以注释的方式,解释了代码。
// main.c
#include "main.h"int main(void)
{HAL_Init(); // 初始化 HAL 库SystemClock_Config(); // 配置系统时钟MX_GPIO_Init(); // 初始化 GPIOwhile (1){// 在主循环中进行其他任务}
}void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 GPIOA 时钟// 配置 PA5 为输出GPIO_InitStruct.Pin = GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 设置输出速度HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化 GPIOA5// 配置 PA0 为输入GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿中断模式GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化 GPIOA0
}
GPIO 输出操作
要设置 GPIO 引脚的输出状态(高电平或低电平),您可以使用 HAL_GPIO_WritePin()
函数。例如:
// 设置 PA5 为高电平(点亮 LED)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // 高电平// 设置 PA5 为低电平(熄灭 LED)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 低电平
GPIO 输入操作
要读取 GPIO 引脚的输入状态,可以使用 HAL_GPIO_ReadPin()
函数。例如,读取 PA0
的状态:
GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);if (pinState == GPIO_PIN_SET) {// 引脚 PA0 为高电平
} else {// 引脚 PA0 为低电平
}
GPIO 中断操作
STM32 HAL 库还支持 GPIO 中断。通过 STM32CubeMX 配置中断模式,例如将 PA0 设置为上升沿触发的中断。下面介绍中断的概念。
额外(中断是什么?)
中断(Interrupt)是微控制器(单片机)处理外部事件或任务的一种机制。它允许微控制器在执行程序的过程中,能够中断当前的工作,立即响应外部事件,然后在处理完事件后恢复到原来的工作状态。中断是实时操作系统(RTOS)和高效嵌入式系统设计中常用的一种技术。
中断的工作原理
当一个中断发生时,微控制器会:
-
暂停当前程序:当前正在执行的代码(包括主程序或其他中断服务程序)会被暂停。微控制器保存当前的执行状态(程序计数器、寄存器值等)。
-
跳转到中断处理函数(ISR):程序计数器会被修改,跳转到对应的中断服务程序地址。该中断服务程序通常是用户编写的代码,用来处理特定的中断事件。
-
处理中断:在中断服务程序中,微控制器执行相应的代码以响应中断,比如读取传感器数据、处理外部设备的请求等。
-
恢复执行:中断处理完毕后,微控制器恢复执行原来的程序,继续之前被暂停的操作。
回归正题 ,将 PA0 设置为上升沿触发的中断
在代码中,您需要启用和配置外部中断:
// 在 MX_GPIO_Init 函数中启用中断
HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0); // 设置中断优先级
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn); // 启用 EXTI0_1 中断
中断服务程序(ISR)通常放在 stm32f1xx_it.c
中:
// 中断回调函数
void EXTI0_1_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // 处理外部中断
}// 回调函数,当发生中断时调用
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if (GPIO_Pin == GPIO_PIN_0) {// 对 PA0 引脚的中断进行处理}
}
4. 使用外设和其他功能
- 配置和使用多个 GPIO 引脚:通过 STM32CubeMX 配置多个 GPIO 引脚进行输入、输出或中断操作。
- 控制 LED:在
main.c
中使用HAL_GPIO_WritePin()
控制连接到开发板的 LED。 - 配置按键:配置外部按键,并在中断或轮询模式下读取按键状态。
5. 示例代码:点亮 LED
下面是一个完整的示例,展示如何通过 GPIO 控制 LED:
#include "main.h"// 主函数
int main(void)
{HAL_Init(); // 初始化 HAL 库SystemClock_Config(); // 配置系统时钟MX_GPIO_Init(); // 初始化 GPIOwhile (1){// 点亮 LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);HAL_Delay(500); // 延时 500ms// 熄灭 LEDHAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);HAL_Delay(500); // 延时 500ms}
}// GPIO 初始化函数
void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE(); // 启用 GPIOA 时钟// 配置 PA5 为输出(LED)GPIO_InitStruct.Pin = GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出GPIO_InitStruct.Pull = GPIO_NOPULL; // 无上下拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 设置输出速度HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化 GPIOA5
}
6. 小结
- GPIO 初始化:通过 STM32CubeMX 配置引脚,并使用 HAL 库函数进行初始化。
- 输入输出操作:使用
HAL_GPIO_WritePin()
控制输出,使用HAL_GPIO_ReadPin()
读取输入。 - 中断处理:通过 STM32CubeMX 配置中断,并在中断回调函数中处理外部中断。
相关文章:
STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用
如果有什么不懂的地方欢迎私聊博主,欢迎小白,博主必一一解答。 在 STM32 中,GPIO(通用输入输出)是与外部硬件接口进行交互的主要方式之一。STM32 HAL 库提供了简洁的接口来配置和控制 GPIO 引脚。下面是使用 STM32 HA…...

【毫米波雷达(七)】自动驾驶汽车中的精准定位——RTK定位技术
一、什么是RTK? RTK,英文全名叫做Real-time kinematic,也就是实时动态。这是一个简称,全称其实应该是RTK(Real-time kinematic,实时动态)载波相位差分技术。 二、RTK的组装 如上图所示&#x…...

Transformer和BERT的区别
Transformer和BERT的区别比较表: 两者的位置编码: 为什么要对位置进行编码? Attention提取特征的时候,可以获取全局每个词对之间的关系,但是并没有显式保留时序信息,或者说位置信息。就算打乱序列中token…...
linux 加载uPD720201固件
硬件 jetson orin nano jetpack 35.5.0 uPD720201是瑞萨推出的怕pcie扩展usb3.0芯片,支持flash主动加载与在系统被动加载 本文介绍如何做到没接flash情况下由系统加载固件 在uPD720201没接spi flash时候nano启动会报XhciDxe错误而自动重启,首先需要在ue…...
C语言中的信号量semaphore详解
在C语言中,**信号量(Semaphore)**是一种常用的同步机制,用于控制多个线程或进程对共享资源的访问。信号量可以实现类似于锁的效果,但更为灵活,适用于并发编程场景。 1. 什么是信号量 信号量可以看作是一个…...
0087__DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区
DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区-CSDN博客...
Windows换机华为擎云(银河麒麟V10+麒麟9000C CPU)后,使用selenium的程序怎么办(20241030)
原本的 seleniumChrome 已无法正常工作。chromedriver 报错:不支持 Linux/aarch64。 1、尝试Firefox、edge驱动。Firefox有一个geckodriver版本与Firefox版本的对照表,我看了一下,感觉他们是始终跟进新技术的。银河麒麟的很多库都是几年前的…...
linux 下 signal() 函数的用法,信号类型在哪里定义的?
--------------------------------------------------- author: hjjdebug date: 2024年 11月 07日 星期四 14:47:33 CST description: linux 下 signal() 函数的用法 --------------------------------------------------- signal 是linux 下最基础的进程通讯机制…...

享元模式及其运用场景:结合工厂模式和单例模式优化内存使用
介绍 享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享对象来减少内存使用,尤其是对于大量相似对象的场景。享元模式通常与工厂模式和单例模式结合使用,从而有效地控制和复用对象的创建。在享元模式中&am…...
【物联网技术】ESP8266 WIFI模块在STA模式下实现UDP与电脑/手机网络助手通信——UDP数据透传
前言:完成ESP8266 WIFI模块在STA模式下实现UDP与电脑/手机网络助手通信——实现UDP数据透传 STA模式,通俗来说就是模块/单片机去连接路由器/热点来通信。 UDP协议,是传输层协议,UDP没有服务器和客户端的说法。 本实验需要注意,wifi模块/单片机与电脑/手机需要连接在同一个…...

【SQL Server】华中农业大学空间数据库实验报告 实验一 数据库
实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法,认识界面,了解其两个基本操作系统文件,并能熟练区分与应用交互式与T-SQL式两种方法在SQL Server中如何进行操作;学习有关数据库的基本操作,包括:…...

操作系统页面置换算法Java实现(LFU,OPT,LRU,LFU,CLOCK)
FIFO先进先出算法 java import java.util.LinkedList; import java.util.Queue; public class Main { //先进先出的思想 是 用一个队列去模拟数据 如果当前不存在就是发生缺页中断了 就需要添加 如果已经满了 将队头的元素出队 即可 //先进先出 就是一个数组 frameCount publi…...

Request和Response
前言 这一节主要讲的是Request和Response还有一些实例 1. 介绍 就是这两个参数 WebServlet("/demo7") public class ServletDemo7 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExcepti…...

【青牛科技】GC8549替代LV8549/ONSEMI在摇头机、舞台灯、打印机和白色家电等产品上的应用分析
引言 在现代电子产品中,控制芯片的性能直接影响到设备的功能和用户体验。摇头机、舞台灯、打印机和白色家电等领域对控制精度、功耗和成本等方面的要求日益提高。LV8549/ONSEMI等国际品牌的芯片曾是这些产品的主要选择,但随着国内半导体技术的进步&…...

(十二)JavaWeb后端开发——MySQL数据库
目录 1.数据库概述 2.MyQSL 3.数据库设计 DDL 4.MySQL常见数据类型 5.DML 1.数据库概述 数据库:DataBase(DB),是存储和管理数据的仓库 数据库管理系统:DataBase ManagementSystem(DBMS),操纵和管理数据库的大型软件 SQL&a…...
pnpm管理多工作区依赖
pnpm是一个支持多包仓库的一个包管理工具,那么怎么可以在项目根目录下执行pnpm install的时候,也能同步让所有的工作区都能够通安装依赖呢? 方式一,在执行pnpm install指令的时候,添加recursive参数: pnpm install --recursive 方式二,在项目的根目录下通过pnpm的配置文件p…...

如何在本地Linux服务器搭建WordPress网站结合内网穿透随时随地可访问
文章目录 前言1. 安装WordPress2. 创建WordPress数据库3. 安装相对URL插件4. 安装内网穿透发布网站4.1 命令行方式:4.2. 配置wordpress公网地址 5. 配置WordPress固定公网地址 前言 本文主要介绍如何在Linux Ubuntu系统上使用WordPress搭建一个本地网站,…...

二、应用层,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》
文章目录 零、前言一、应用层协议原理1.1 网络应用的体系结构1.1.1 客户-服务器(C/S)体系结构1.1.2 对等体(P2P)体系结构1.1.3 C/S 和 P2P体系结构的混合体 1.2 进程通信1.2.1 问题1:对进程进行编址(addressing)&#…...

面粉直供系统|基于java和小程序的食品面粉直供系统设计与实现(源码+数据库+文档)
面粉直供系统 目录 基于java和小程序的食品面粉直供系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&#x…...
十四:java web(6)-- Spring Spring MVC
目录 Spring MVC 1.1 Spring MVC 概述 1.1.1 什么是 MVC 模式 1.1.2 Spring MVC 工作原理 1.2 Spring MVC 核心组件 1.2.1 DispatcherServlet 1.2.2 控制器(Controller) 1.2.3 请求映射(RequestMapping) 1.2.4 视图解析器…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...