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

GPIO初始化及调用

下面把 HAL 库标准外设库(SPL) 初始化 GPIO 点亮/熄灭 LED 的完整步骤、示例代码和常用 API 逐一说清楚。用例默认 PC13 接 LED(蓝板常见;低电平点亮,高电平熄灭——若板子相反,只把写 1/0 对调即可)。

一、HAL 库:GPIO 初始化与点亮/熄灭 LED

步骤(通用顺序)

  1. 使能端口时钟 __HAL_RCC_GPIOx_CLK_ENABLE()

  2. 填写 GPIO_InitTypeDef 结构体(Pin/Mode/Speed …)

  3. HAL_GPIO_Init(GPIOx, &init) 完成配置

  4. HAL_GPIO_WritePin / TogglePin / ReadPin 控制或读引脚
    (可选)5) 若需 EXTI:还要配置中断优先级并使能 NVIC,使用 HAL_GPIO_EXTI_IRQHandler/HAL_GPIO_EXTI_Callback

示例代码(HAL)

led.h

#ifndef __LED_H__
#define __LED_H__#include "stm32f1xx_hal.h"/* ====== 硬件相关宏定义 ====== */
#define LED_GPIO_PORT      GPIOC        // LED 所在的端口(此处为 GPIOC)
#define LED_GPIO_PIN       GPIO_PIN_13  // LED 引脚号(PC13)/* ====== LED 控制函数声明 ====== */
void LED_Init(void);     // 初始化 LED 引脚
void LED_On(void);       // 点亮 LED
void LED_Off(void);      // 熄灭 LED
void LED_Toggle(void);   // 翻转 LED 状态#endif

led.c:

#include "led.h"/*** @brief  初始化 LED 引脚* @note   配置为推挽输出,默认熄灭(PC13高电平)*/
void LED_Init(void)
{/* 1. 使能 GPIOC 时钟(如果不打开,GPIO 寄存器无法操作) */__HAL_RCC_GPIOC_CLK_ENABLE();/* 2. 配置 GPIO 参数 */GPIO_InitTypeDef gpio = {0};              // 定义配置结构体并清零gpio.Pin   = LED_GPIO_PIN;                // 选择 PC13gpio.Mode  = GPIO_MODE_OUTPUT_PP;         // 推挽输出模式gpio.Speed = GPIO_SPEED_FREQ_LOW;         // 低速输出(足够驱动 LED)HAL_GPIO_Init(LED_GPIO_PORT, &gpio);      // 初始化 GPIOC 的 13 引脚/* 3. 缺省熄灭 LED(PC13 高电平 = 灭) */HAL_GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PIN, GPIO_PIN_SET);
}/*** @brief 点亮 LED*/
void LED_On(void)
{HAL_GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PIN, GPIO_PIN_RESET); // PC13 输出低电平
}/*** @brief 熄灭 LED*/
void LED_Off(void)
{HAL_GPIO_WritePin(LED_GPIO_PORT, LED_GPIO_PIN, GPIO_PIN_SET);   // PC13 输出高电平
}/*** @brief 翻转 LED 状态*/
void LED_Toggle(void)
{HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PIN);                // HAL 内部用 BSRR 实现
}

main.c

#include "stm32f1xx_hal.h"
#include "led.h"/* 系统时钟配置函数(具体实现依赖 CubeMX 或手写) */
static void SystemClock_Config(void);int main(void)
{/* 1. HAL 库初始化:包括时钟源、SysTick 配置等 */HAL_Init();/* 2. 配置系统时钟(比如 HSE=8MHz → SYSCLK=72MHz) */SystemClock_Config();/* 3. 初始化 LED 引脚 */LED_Init();/* 4. 主循环:控制 LED 闪烁 */while (1){LED_On();       // 点亮HAL_Delay(300); // 延时 300 msLED_Off();      // 熄灭HAL_Delay(300); // 延时 300 msLED_Toggle();   // 翻转状态HAL_Delay(300); // 延时 300 ms}
}/* ===== 系统时钟配置函数(此处仅示意,实际需根据工程生成) ===== */
static void SystemClock_Config(void)
{/* 如果使用 CubeMX,一般会自动生成这里的代码。自己手写时,需要配置 HSE/PLL,把 SYSCLK 提升到 72MHz。如果不写,默认 SystemInit() 可能只运行在 8MHz HSI。 */
}

HAL 结构体/参数要点(F1)

  • Pin:引脚位图,可或起来(如 GPIO_PIN_0 | GPIO_PIN_1)。

  • Mode

    • GPIO_MODE_OUTPUT_PP / _OD(推挽/开漏)

    • GPIO_MODE_INPUTGPIO_MODE_ANALOG

    • GPIO_MODE_AF_PP / _AF_OD(复用推挽/开漏)

    • GPIO_MODE_IT_RISING/FALLING/RISING_FALLING(外部中断)

    • GPIO_MODE_EVT_*(事件)

  • SpeedGPIO_SPEED_FREQ_LOW/MEDIUM/HIGH(≈2/10/50 MHz)

注:F1 的 HAL 不带 Pull 字段(上拉/下拉由 CRL/CRH 的 CNF 决定;若要上拉/下拉,需把 Mode 设为输入并用 ODR 置 1/0 完成上/下拉,或直接用 HAL 的 GPIO_MODE_INPUT + 后续写 ODR)。

二、标准外设库(SPL):GPIO 初始化与点亮/熄灭 LED

步骤

  1. 使能端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx, ENABLE)

  2. GPIO_InitTypeDef(Pin/Mode/Speed)

  3. GPIO_Init(GPIOx, &init)

  4. GPIO_SetBits / ResetBits / WriteBit 控制

示例代码(SPL)

led.h:

#ifndef __LED_H__
#define __LED_H__#include "stm32f10x.h"/* ====== 硬件相关宏定义 ====== */
#define LED_GPIO_PORT      GPIOC                  // LED 所在端口
#define LED_GPIO_PIN       GPIO_Pin_13            // LED 引脚 PC13
#define LED_GPIO_CLK       RCC_APB2Periph_GPIOC   // GPIOC 时钟/* ====== LED 控制函数声明 ====== */
void LED_Init(void);     // 初始化 LED 引脚
void LED_On(void);       // 点亮 LED
void LED_Off(void);      // 熄灭 LED
void LED_Toggle(void);   // 翻转 LED 状态#endif

led.c:

#include "led.h"/*** @brief  初始化 LED 引脚* @note   PC13 配置为推挽输出,默认熄灭*/
void LED_Init(void)
{/* 1. 使能 GPIOC 时钟 */RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);/* 2. 配置 PC13 为推挽输出 */GPIO_InitTypeDef gpio;gpio.GPIO_Pin   = LED_GPIO_PIN;      // 选择引脚gpio.GPIO_Speed = GPIO_Speed_2MHz;   // 输出速度 2MHzgpio.GPIO_Mode  = GPIO_Mode_Out_PP;  // 推挽输出GPIO_Init(LED_GPIO_PORT, &gpio);/* 3. 缺省熄灭 LED(PC13 高电平 = 灭) */GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);
}/*** @brief 点亮 LED*/
void LED_On(void)
{GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN); // 低电平
}/*** @brief 熄灭 LED*/
void LED_Off(void)
{GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);   // 高电平
}/*** @brief 翻转 LED 状态*/
void LED_Toggle(void)
{if (GPIO_ReadOutputDataBit(LED_GPIO_PORT, LED_GPIO_PIN))GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN); // 如果当前是 1 → 清零elseGPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);   // 如果当前是 0 → 置 1
}

main.c:

#include "stm32f10x.h"
#include "led.h"/* 时钟配置函数 */
static void Clock_Config(void);int main(void)
{/* 1. 配置系统时钟(如果需要) */Clock_Config();/* 2. 初始化 LED 引脚 */LED_Init();/* 3. 主循环:控制 LED 闪烁 */while (1){LED_On();   // 点亮for(volatile int i=0;i<600000;i++);  // 简单延时LED_Off();  // 熄灭for(volatile int i=0;i<600000;i++);LED_Toggle(); // 翻转状态for(volatile int i=0;i<600000;i++);}
}/*** @brief  时钟配置* @note   SPL 启动文件里默认调用 SystemInit(),会把 HSE/PLL 配置成 72MHz。*         如果已经够用,这里可以留空。*/
static void Clock_Config(void)
{/* 一般用默认 SystemInit 即可 */
}

SPL 结构体/参数要点

  • GPIO_Mode

    • GPIO_Mode_AIN(模拟输入)

    • GPIO_Mode_IN_FLOATING(浮空输入)

    • GPIO_Mode_IPD / GPIO_Mode_IPU(下拉/上拉输入)

    • GPIO_Mode_Out_PP / _Out_OD(通用推挽/开漏输出)

    • GPIO_Mode_AF_PP / _AF_OD(复用推挽/开漏输出)

  • GPIO_SpeedGPIO_Speed_2MHz / 10MHz / 50MHz(仅对输出/复用输出有效)

三、图里 HAL GPIO 其他函数的作用(并给出 SPL 对应函数)

HAL 函数作用(要点)关键参数SPL/等价做法
HAL_GPIO_Init(GPIOx, &init)根据 Pin/Mode/Speed 配置端口(本质写 CRL/CRH)GPIOx:端口;Pin 位图;ModeSpeedGPIO_Init(GPIOx, &init)
HAL_GPIO_DeInit(GPIOx, GPIO_Pin)复位指定引脚到缺省(模拟输入),清除 EXTI 绑定GPIO_Pin 位图GPIO_DeInit(GPIOx)(注意 SPL 是“整个端口复位”;单独复位需手写寄存器)
HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PinState)通过 BSRR 原子置 1/清 0GPIO_PinStateGPIO_PIN_SET/RESETGPIO_WriteBit/SetBits/ResetBitsGPIOx->BSRR/BRR
HAL_GPIO_TogglePin(GPIOx, GPIO_Pin)翻转输出(对 ODR 异或)GPIO_Pin 位图无直接 API,可 GPIO_WriteBit(GPIOx,pin, (BitAction)!GPIO_ReadOutputDataBit(...)) 或操作 ODR
HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)IDR,返回 GPIO_PIN_SET/RESETGPIO_PinGPIO_ReadInputDataBit(GPIOx, pin)
HAL_GPIO_LockPin(GPIOx, GPIO_Pin)通过 LCKR 锁定配置,直到下次复位(防误改)GPIO_Pin 位图GPIO_PinLockConfig(GPIOx, pin)
HAL_GPIO_EXTI_IRQHandler(GPIO_Pin)通用 EXTI 线中断处理:清挂起位并调用回调GPIO_Pin:哪条线触发SPL:在 EXTIxx_IRQHandlerEXTI_GetITStatus/EXTI_ClearITPendingBit,然后自己回调
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)弱定义(__weak)回调,用户重写做业务GPIO_Pin:触发的线SPL:自己写回调或在 IRQHandler 里直接处理

EXTI 的初始化(两库都需要额外步骤)

  • HAL:把引脚 Mode 设为 GPIO_MODE_IT_*,然后用 HAL_NVIC_SetPriorityHAL_NVIC_EnableIRQ 开中断即可。

  • SPL:GPIO_EXTILineConfig(AFIO_PORTx, PinSourcex) + EXTI_Init(&cfg) + NVIC_Init(&nvic)

四、常见易错点与小技巧

  • 时钟别忘开:F1 的 GPIO 都在 APB2,HAL 用 __HAL_RCC_GPIOx_CLK_ENABLE();SPL 用 RCC_APB2PeriphClockCmd(...)

  • 蓝板 PC13 低电平点亮:别把“写 1 点亮”写反。

  • 原子操作首选 BSRR:HAL 的 WritePin/TogglePin 已经用 BSRR,SPL 用 GPIOx->BSRR/BRR 更安全。

  • 速度只对输出有效:输入模式时 Speed 无意义。

  • 锁定功能:量产固件防误改时可用 HAL_GPIO_LockPin / GPIO_PinLockConfig

  • 多脚同时配置Pin 可位或(如 GPIO_PIN_0|GPIO_PIN_1),一次初始化多个引脚。

http://www.dtcms.com/a/334944.html

相关文章:

  • Go语言指针与内存分配深度解析:从指针本质到 new、make 的底层实现
  • Spring三级缓存
  • 深入理解 Linux 线程:从概念到虚拟地址空间的全面解析
  • 机器学习的特征工程(特征构造、特征选择、特征转换和特征提取)详解
  • 028 动静态库 —— 动态库
  • 第3问 什么是数据指标?
  • 41 C++ STL模板库10-容器3-list
  • MATLAB R2010b系统环境(一)MATLAB简介
  • 云原生俱乐部-RH124知识点总结(3)
  • Dify实战应用指南(上传需求稿生成测试用例)
  • C/C++中的内存分区
  • Java8~Java21重要新特性
  • sharding-jdbc读写分离配置
  • “preinstall“: “npx only-allow pnpm“
  • C#多线程并发安全队列ConcurrentQueue
  • 防火墙虚拟系统配置实验
  • 自然语言处理——02 文本预处理(上)
  • B*算法深度解析:动态避障路径规划的革命性方法
  • AI安全增强核心技术:提示词防火墙、置信度过滤与知识蒸馏防御
  • 2-3〔O҉S҉C҉P҉ ◈ 研记〕❘ 漏洞扫描▸AppScan(WEB扫描)
  • XC6SLX45T-2FGG484C Xilinx AMD Spartan-6 FPGA
  • 16-集合的Stream编程
  • 基于STM32的智能书房系统设计与实现
  • BitLocker解密
  • docker compose安装mysql8
  • UE5多人MOBA+GAS 46、制作龙卷风技能
  • C/单片机内存管理,仿真keii
  • 第5问 对于数据分析领域,统计学要学到什么程度?
  • 第6问 数据分析领域主要的岗位有哪些?
  • 《从混乱到有序:AI 如何一步步梳理数据质量难题》文章提纲