前言

本文以设置STM32f103c8t6的GPIOC的13号引脚为例,分别以寄存器直接操作底层和库函数的方式来学习GPIO 寄存器与配置的原理,详细介绍了寄存器方式,用以学习参考手册的使用和GPIO寄存器配置的底层原理。

一、GPIO 寄存器概述

STM32 的 GPIO 端口通过寄存器控制引脚模式、输入/输出状态,核心寄存器包括:

寄存器类型功能描述位宽与对应引脚
端口配置寄存器(CRL/CRH)配置引脚工作模式(输入/输出、速度、上拉/下拉等),每 4 位控制 1 个引脚。CRL 控制低 8 位(Pin0~Pin7),CRH 控制高 8 位(Pin8~Pin15)。32 位(CRL+CRH 共 64 位,控制 16 个引脚)
输入数据寄存器(IDR)读取引脚电平状态,每一位对应 1 个引脚,低 16 位有效(对应 Pin0~Pin15),高 16 位未使用。32 位(低 16 位有效)
输出数据寄存器(ODR)控制引脚输出电平,写 1 输出高电平,写 0 输出低电平,低 16 位有效(对应 Pin0~Pin15),高 16 位未使用。32 位(低 16 位有效)
置位/复位寄存器(BSRR/BRR)快速设置/清除引脚输出(BSRR 低 16 位置位,高 16 位复位;BRR 仅低 16 位复位),避免 ODR 读-改-写操作。32 位

二、GPIO 总线与引脚编号

  • 所有 GPIO 外设挂载在 APB2 外设总线 上。
  • 每个 GPIO 外设包含 16 个引脚(编号 0~15),寄存器仅低 16 位对应有效引脚。

三、GPIO 使能(时钟控制)

GPIO 需先使能时钟才能工作,通过 RCC_APB2ENR 寄存器 控制。例如,GPIOC 的时钟使能位为 IOPCEN(RCC_APB2ENR 的第 4 位)。

四、GPIO 配置步骤(标准流程)

  1. 使能时钟:通过 RCC_APB2ENR 开启目标 GPIO 的时钟。
  2. 初始化配置:通过 GPIO_Init() 函数(或寄存器)配置引脚模式、速度、上拉/下拉等。
  3. 引脚控制:通过 GPIO_SetBits()/GPIO_ResetBits()(或寄存器)控制输出,或通过 GPIO_ReadInputDataBit() 读取输入。

五、GPIOC 引脚 13(PC13)的详细配置示例

STM32F103 为例,配置 PC13 为推挽输出,50MHz 速度,并实现“翻转电平”功能(LED 控制常见场景)。

方法 1:寄存器直接操作(底层控制)

5.1、开启GPIOC时钟—APB2 外设时钟使能寄存器(RCC_APB2ENR)

APB2ENR配置
上图APB2ENR寄存器二进制形式
0000 0000 0000 0000 0000 0000 0001 0000
用于开启GPIOC时钟,转换成十六进制(四个一组)就是0x0000 0010,即RCC->APB2ENR |= (1 << 4); // 置位 IOPCEN
在这里插入图片描述

5.2、配置PC13口模式—端口配置高寄存器(GPIOx_CRH) (x=A…E)

配置上PC13口的寄存器,端口配置低寄存器用来配置引脚0~引脚7,因此需要在端口配置高寄存器中配置(引脚8-引脚15)

  • 端口配置低寄存器(GPIOx_CRL) (x=A…E)
    在这里插入图片描述
  • 端口配置高寄存器(GPIOx_CRH) (x=A…E)
    PC13口,因此配置高寄存器中的CNF13(输出模式)和MODE13(输出速度)

在这里插入图片描述
GPIOC->CRH |= (0x3 << 20);
等价于GPIOC->CRH = 0x0030 0000
在这里插入图片描述

5.3、给PC13口输出数据—端口输出数据寄存器(GPIOx_ODR) (x=A…E)

  • 用到端口输出数据寄存器(GPIOx_ODR) (x=A…E),需要设置ODR寄存器的值为1,即设置PC13口为高电平,即GPIOC->ODR &= 1 << 13;
    在这里插入图片描述

5.4、寄存器直接操作完整代码步骤

#include "stm32f10x.h"

void GPIOC_PC13_Init(void) {
    // 1. 使能 GPIOC 时钟(RCC_APB2ENR 第 4 位:IOPCEN)
    RCC->APB2ENR |= (1 << 4);  // 置位 IOPCEN,开启 GPIOC 时钟
    
    // 2. 配置 CRL/CRH:PC13 属于高 8 位(Pin8~Pin15),需配置 CRH
    // CRH 的格式:[3:0]对应 Pin11, [7:4]对应 Pin10, ..., [31:28]对应 Pin8?不,CRH 是 Pin8~Pin15,每 4 位控制 1 个引脚:
    // Pin15: CRH[31:28], Pin14: CRH[27:24], ..., Pin8: CRH[3:0]
    // PC13 是第 13 号引脚,对应 CRH 的 [23:20](因为 13-8=5,5*4=20,所以位 23~20)
    // 配置为:推挽输出(CNF=00),50MHz(MODE=11)
    GPIOC->CRH &= ~(0xF << 20);  // 清除原有配置(CRH[23:20])
    GPIOC->CRH |= (0x3 << 20);   // MODE=11(50MHz),CNF=00(推挽输出)→ 0x3<<20 = 0b0011<<20 = 0x300000
    
    // 3. 初始输出电平(可选,例如默认低电平)
    GPIOC->BSRR &= ~(1 << 13);   // 清除置位,准备复位(或直接写 ODR)
    // 或 GPIOC->ODR &= ~(1 << 13); // 输出低电平
}

// 翻转 PC13 电平(示例函数)
void GPIOC_PC13_Toggle(void) {
    if (GPIOC->ODR & (1 << 13)) { // 读取当前电平
        GPIOC->BRR |= (1 << 13);  // 复位(输出低)
    } else {
        GPIOC->BSRR |= (1 << 13); // 置位(输出高)
    }
}

int main(void) {
    GPIOC_PC13_Init();
    while(1) {
        GPIOC_PC13_Toggle();      // 翻转电平(模拟 LED 闪烁)
        for(int i=0; i<1000000; i++); // 简单延时
    }
}

方法 2:库函数操作(STM32 标准外设库)

需包含 stm32f10x_gpio.hstm32f10x_rcc.h 等头文件。

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void GPIOC_PC13_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 1. 使能 GPIOC 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
    // 2. 配置 PC13:推挽输出,50MHz
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 50MHz 速度
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    // 初始电平(可选,例如默认低)
    GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}

// 翻转 PC13 电平
void GPIOC_PC13_Toggle(void) {
    if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13)) {
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    } else {
        GPIO_SetBits(GPIOC, GPIO_Pin_13);
    }
}

int main(void) {
    GPIOC_PC13_Init();
    while(1) {
        GPIOC_PC13_Toggle();
        for(int i=0; i<1000000; i++); // 延时
    }
}

六、关键知识点总结

  • 寄存器映射:GPIO 寄存器地址需参考芯片手册(如 STM32F103 的 GPIO 基地址为 0x4001 1000 + 端口偏移)。
  • 模式配置:输入模式(浮空、上拉、下拉)、输出模式(推挽、开漏)、复用模式、模拟模式等,由 CRL/CRH 的 4 位(CNF[1:0] + MODE[1:0])决定。
  • 时钟使能:GPIO 属于 APB2 外设,时钟由 RCC_APB2ENR 控制,必须先使能时钟才能操作寄存器。

通过以上整理和示例,可清晰理解 GPIO 寄存器的功能、配置流程,以及针对特定引脚(如 PC13)的详细配置方法。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐