跳到主要内容

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 配置示例:

c
#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 库提供的函数来设置引脚的状态。以下是一个简单的写操作示例:

c
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 引脚读取外部信号的状态。以下是一个简单的读操作示例:

c
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 的状态。

c
#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 的其他外设功能,如定时器、中断等。

附加资源

练习

  1. 修改上面的代码,使得 LED 灯以不同的频率闪烁。
  2. 尝试使用 GPIO 的输入模式读取按钮的状态,并根据按钮的状态控制 LED 灯。