STM32 GPIO 读写操作
介绍
GPIO(General Purpose Input/Output,通用输入输出)是 STM32 微控制器中最基本的外设之一。它允许微控制器与外部设备进行数字信号的交互。通过 GPIO,STM32 可以读取外部信号(如按钮状态)或控制外部设备(如 LED 灯)。
在本文中,我们将学习如何配置 STM32 的 GPIO 引脚,并实现基本的读写操作。我们将从 GPIO 的基础概念开始,逐步深入到实际的代码实现。
GPIO 基础
GPIO 引脚可以配置为输入或输出模式。在输入模式下,GPIO 引脚可以读取外部信号的状态(高电平或低电平)。在输出模式下,GPIO 引脚可以驱动外部设备(如点亮 LED 或控制继电器)。
GPIO 模式
STM32 的 GPIO 引脚可以配置为以下几种模式:
- 输入模式:用于读取外部信号。
- 输出模式:用于驱动外部设备。
- 复用功能模式:用于将 GPIO 引脚配置为其他外设的功能(如 UART、SPI 等)。
- 模拟模式:用于将 GPIO 引脚配置为模拟输入(如 ADC)。
GPIO 速度
GPIO 引脚的速度决定了其输出信号的切换速度。STM32 提供了多种速度选项,通常用于高速信号传输的场景。
GPIO 上拉/下拉电阻
GPIO 引脚可以配置为上拉或下拉电阻,以确保在未连接外部设备时引脚处于已知状态。
GPIO 配置
在 STM32 中,GPIO 的配置通常通过 HAL 库(Hardware Abstraction Layer)来完成。以下是一个基本的 GPIO 配置示例:
#include "stm32f4xx_hal.h"
void GPIO_Config(void) {
// 启用 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置 GPIO 引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5; // 选择引脚 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); // 初始化 GPIOA
}
在上面的代码中,我们配置了 GPIOA 的第 5 引脚为推挽输出模式,并且不使用上拉或下拉电阻。
GPIO 写操作
在配置好 GPIO 引脚后,我们可以通过 HAL 库提供的函数来设置引脚的状态。以下是一个简单的写操作示例:
void GPIO_Write(void) {
// 设置 GPIOA 的第 5 引脚为高电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
// 设置 GPIOA 的第 5 引脚为低电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}
在上面的代码中,我们使用 HAL_GPIO_WritePin
函数来控制 GPIOA 的第 5 引脚的状态。GPIO_PIN_SET
表示将引脚设置为高电平,GPIO_PIN_RESET
表示将引脚设置为低电平。
GPIO 读操作
除了写操作,我们还可以通过 GPIO 引脚读取外部信号的状态。以下是一个简单的读操作示例:
void GPIO_Read(void) {
// 读取 GPIOA 的第 5 引脚的状态
GPIO_PinState pinState = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);
if (pinState == GPIO_PIN_SET) {
// 引脚为高电平
} else {
// 引脚为低电平
}
}
在上面的代码中,我们使用 HAL_GPIO_ReadPin
函数来读取 GPIOA 的第 5 引脚的状态。GPIO_PIN_SET
表示引脚为高电平,GPIO_PIN_RESET
表示引脚为低电平。
实际案例:控制 LED
让我们通过一个实际案例来展示如何使用 GPIO 控制 LED 灯。假设我们有一个 LED 灯连接到 GPIOA 的第 5 引脚,并且我们希望每隔 1 秒切换一次 LED 的状态。
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"
void SystemClock_Config(void);
void GPIO_Config(void);
void Delay(uint32_t ms);
int main(void) {
// 初始化 HAL 库
HAL_Init();
// 配置系统时钟
SystemClock_Config();
// 配置 GPIO
GPIO_Config();
while (1) {
// 切换 LED 状态
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
// 延时 1 秒
Delay(1000);
}
}
void GPIO_Config(void) {
// 启用 GPIOA 时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置 GPIO 引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
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);
}
void Delay(uint32_t ms) {
// 简单的延时函数
HAL_Delay(ms);
}
在上面的代码中,我们使用 HAL_GPIO_TogglePin
函数来切换 GPIOA 的第 5 引脚的状态,从而实现 LED 灯的闪烁效果。
总结
通过本文,我们学习了如何在 STM32 微控制器上进行 GPIO 的读写操作。我们从 GPIO 的基础概念入手,逐步讲解了 GPIO 的配置、读取和写入操作,并通过实际案例展示了如何控制 LED 灯。
在实际项目中,GPIO 的配置和使用可能会更加复杂。建议读者在掌握基础知识后,进一步学习 STM32 的其他外设功能,如定时器、中断等。
附加资源
练习
- 修改上面的代码,使得 LED 灯以不同的频率闪烁。
- 尝试使用 GPIO 的输入模式读取按钮的状态,并根据按钮的状态控制 LED 灯。