2. GPIO 口

📌 本节学习目标
  • 理解 GPIO 的基本结构与工作原理
  • 掌握 GPIO 的 8 种工作模式
  • 学会使用寄存器配置 GPIO
  • 学会使用库函数配置 GPIO

2.1 GPIO 概述

GPIO(General Purpose Input/Output)是 STM32 最基本的 I/O 接口,每个引脚可独立配置为输入或输出模式。STM32F103C8T6 有 37 个 GPIO 引脚,分布在 GPIOA(PA0-PA15)、GPIOB(PB0-PB15)、GPIOC(PC13-PC15)端口中。

2.2 GPIO 工作模式

STM32 的 GPIO 有 8 种工作模式,分为输入和输出两大类:

模式类型说明
浮空输入输入引脚电平直接进入输入数据寄存器,无上下拉
上拉输入输入内部上拉电阻接入,默认高电平
下拉输入输入内部下拉电阻接入,默认低电平
模拟输入输入引脚接入 ADC 等模拟外设
开漏输出输出类似 MOS 管漏极开路,需外部上拉;可实现电平转换、线与逻辑
推挽输出输出PMOS + NMOS 互补输出,可输出高/低电平
复用开漏输出复用由片上外设驱动(如 I2C 的 SDA 线)
复用推挽输出复用由片上外设驱动(如 USART 的 TX、PWM 输出)

2.3 GPIO 寄存器

每个 GPIO 端口都由一系列寄存器控制。以 GPIOA 为例:

寄存器地址偏移描述
GPIOx_CRL0x00端口配置低寄存器(Pin 0-7)
GPIOx_CRH0x04端口配置高寄存器(Pin 8-15)
GPIOx_IDR0x08输入数据寄存器
GPIOx_ODR0x0C输出数据寄存器
GPIOx_BSRR0x10置位/复位寄存器(原子操作)
GPIOx_BRR0x14复位寄存器
GPIOx_LCKR0x18锁定寄存器

2.4 寄存器方式编程

C 代码(寄存器操作 LED)
// 寄存器方式点亮 LED(PB0 接 LED)
#define GPIOB_CRL  *(volatile unsigned long *)0x40010C00
#define GPIOB_ODR  *(volatile unsigned long *)0x40010C0C
#define RCC_APB2ENR *(volatile unsigned long *)0x40021018

// 开启 GPIOB 时钟
RCC_APB2ENR |= (1 << 3);    // APB2 总线上 GPIOB 时钟使能

// 配置 PB0 为推挽输出,50MHz
GPIOB_CRL &= ~(0x0F << 0);  // 先清除 CNF0 和 MODE0
GPIOB_CRL |= (0x01 << 0);   // MODE0 = 01(输出 50MHz)
GPIOB_CRL |= (0x00 << 2);   // CNF0 = 00(推挽输出)

// 点亮 LED
GPIOB_ODR |= (1 << 0);     // PB0 = 1(根据电路决定高/低电平点亮)

2.5 库函数方式编程

C 代码(库函数操作 LED)
#include "stm32f10x.h"

void GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能 GPIOB 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    // PB0 配置为推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

int main(void)
{
    GPIO_Config();
    while (1)
    {
        GPIO_SetBits(GPIOB, GPIO_Pin_0);   // PB0 = 1
        delay(500);
        GPIO_ResetBits(GPIOB, GPIO_Pin_0); // PB0 = 0
        delay(500);
    }
}
💡 这两段代码怎么用、有什么区别?
  1. 寄存器方式:直接读写内存地址,性能最高、代码量最少,但可读性差、容易算错偏移。适合理解底层原理
  2. 库函数方式:用 GPIO_Init() + 结构体配置,写起来像填表,是课程主流方式,本课程实验都用它
  3. 两者最终配置的都是同一组寄存器——「先使能时钟,再设模式,最后操作引脚」三步缺一不可
📎 配套资料课件:2.GPIO口.pptx | 实验:实验04:跑马灯实验05:按键输入