欢迎光临
我们一直在努力

STM32学习——GPIO+AFIO(附LED闪灯与按钮实验)

这份 GPIO/AFIO 的核心逻辑适用于所有 STM32 系列,但不同型号(F1/F4/F7/H7/L4 等)有细节差异,工作中只需关注 “通用逻辑 + 型号专属差异” 即可,本文结合数据手册用通俗易懂的语言整理,详略得当,注重内容实用性。

STM32F1 GPIO+AFIO 实用手册(大白话版)

一、先搞懂基础:STM32 芯片分类(不用记细节,知道就行)

可以把 STM32F1 系列按 “闪存大小” 分成几类,不同类别功能略有差异,但 GPIO 用法基本一样:

  • 小容量:闪存 16K~32K(入门款)
  • 中容量:闪存 64K~128K(最常用)
  • 大容量:闪存 256K~512K(功能更多)
  • 互联型:F105/F107(带以太网、双 CAN,GPIO 重映射更丰富)

二、GPIO 核心:8 种工作模式(工作必记,其余可忘)

GPIO 就是芯片的 “对外接口”,每个引脚能设成 8 种模式,用通俗的话解释:

表格

模式类型大白话解释典型用途
输入浮空 引脚悬空,啥都不接,只检测外部电平 串口 RX、外部中断触发
输入上拉 引脚默认高电平,外部拉低才变低 按键检测(不用外接上拉电阻)
输入下拉 引脚默认低电平,外部拉高才变高 外部传感器信号检测
模拟输入 禁用数字电路,专门接模拟信号 ADC 采样、DAC 输出
通用推挽输出 能主动拉高 / 拉低,驱动能力强 点灯、继电器、电机控制
通用开漏输出 只能拉低,拉高靠外部上拉电阻 多设备共用总线(无外设复用)
复用推挽输出 由芯片内部外设(如串口)控制,不是手动改 串口 TX、SPI 时钟、定时器 PWM
复用开漏输出 外设控制 + 开漏特性,需外部上拉 I2C 的 SCL/SDA、CAN 通信

关键提醒:

  • 推挽 =“能推能拉”:输出 1 时引脚变高,输出 0 时变低,直接驱动设备;
  • 开漏 =“只拉不推”:输出 0 时引脚变低,输出 1 时引脚悬空,必须外接上拉电阻才能变高(I2C 必用)。

三、GPIO 配置:核心是 “4 位开关”(CRL/CRH 寄存器)

每个 GPIO 引脚的模式由 “4 个二进制位” 决定(存在 CRL/CRH 寄存器里),可以理解成 “4 个小开关”:

                   CNF=Configuration即引脚模式配置位

  • 前 2 位(CNF):管 “模式类型”(是推挽还是开漏,是通用还是复用);
  • 后 2 位(MODE):管 “速度 / 方向”(输入还是输出,输出的话反应多快)。

极简配置逻辑(记这个就够):

  • 想设为 “输入”:MODE 位写 00(00 = 输入)
    • 模拟输入:CNF=00;浮空输入:CNF=01;上拉 / 下拉输入:CNF=10;
  • 想设为 “输出 / 复用”:MODE 位写非 00(01=10MHz、10=2MHz、11=50MHz,选 11 就行,速度够快)
    • 通用推挽:CNF=00;通用开漏:CNF=01;复用推挽:CNF=10;复用开漏:CNF=11。
  • 举例子(工作中直接套):

    • 想让 PA0 点灯(通用推挽输出):MODE=11(50MHz),CNF=00;
    • 想让 PB6 做 I2C_SCL(复用开漏输出):MODE=11,CNF=11;
    • 想让 PC13 接按键(输入上拉):MODE=00,CNF=10。

    四、7 个 GPIO 寄存器:只记 “怎么用”,别记地址

    寄存器就是芯片里的 “开关盒”,不用记具体地址,知道功能和用法就行:

    表格

    寄存器名大白话功能实用用法
    GPIOx_CRL 管引脚 0~7 的配置 配置 PA0~PA7、PB0~PB7 等
    GPIOx_CRH 管引脚 8~15 的配置 配置 PA8~PA15、PB8~PB15 等
    GPIOx_IDR 只读!看引脚实际电平 检测按键是否按下、读传感器值
    GPIOx_ODR 读写!设输出电平(但不安全) 临时改电平,中断里别用
    GPIOx_BSRR 只写!安全改电平(重点) 中断里点灯 / 控设备,只改 1 个引脚,不影响其他
    GPIOx_BRR 只写!专门清零电平 想让引脚变低时用,比 BSRR 简单
    GPIOx_LCKR 锁死配置(复位前改不了) 工业场景用,普通项目不用
    1. CRL
    Configuration Register Low
    • 配置寄存器(低 8 位)
    • 管:Pin0 ~ Pin7
    2. CRH
    Configuration Register High
    • 配置寄存器(高 8 位)
    • 管:Pin8 ~ Pin15
    3. IDR
    Input Data Register
    • 输入数据寄存器
    • 作用:读引脚电平
    4. ODR
    Output Data Register
    • 输出数据寄存器
    • 作用:写输出电平
    5. BSRR
    Bit Set / Reset Register
    • 位置位 / 复位寄存器
    • 作用:只写 1 有效,安全改引脚
    6. BRR
    Bit Reset Register
    • 位复位寄存器
    • 作用:只用来把引脚拉低
    7. LCKR
    Lock Register
    • 锁定寄存器
    • 作用:锁死引脚配置,不让改

    超级精简记忆(背这 7 行就够)
    • CRL:配置低 8 位
    • CRH:配置高 8 位
    • IDR:读电平
    • ODR:写电平
    • BSRR:安全置位 / 复位
    • BRR:只复位
    • LCKR:锁配置

    核心用法(工程必会):

  • 改电平优先用 BSRR:比如想让 PA0 变高→往 BSRR 的第 0 位写 1;想让 PA0 变低→往 BSRR 的第 16 位写 1(只改这一位,其他引脚不受影响);
  • 读电平必看 IDR:哪怕是输出引脚,想知道实际电平(比如有没有被外部拉低),必须读 IDR,读 ODR 只是 “你之前写的值”,不是真实状态;
  • 配置引脚先改 CRL/CRH:比如 PA0 要做推挽输出,先改 CRL 里 PA0 对应的 4 位,再用 BSRR 改电平。
  • 五、复用功能:让 GPIO 听 “外设” 的话(重点)

    1. 啥是复用功能?

    普通 GPIO 是 “你手动控制”,复用功能是 “把 GPIO 交给串口、I2C、定时器等内部外设控制”,比如串口 TX 引脚,电平由串口自动发,不是你手动改。

    2. 复用功能配置步骤(一步都不能少):

  • 开时钟:先开 AFIO 时钟(必开!)+ 对应外设时钟(比如串口时钟);
  • 配 GPIO:把引脚设为 “复用推挽 / 开漏”(比如串口 TX 设为复用推挽,I2C 设为复用开漏);
  • 初始化外设:比如配置串口的波特率、I2C 的地址。
  • 3. 关键提醒:

    • 复用输出时,GPIO 的 ODR 寄存器失效!引脚电平由外设控制,不是你写 ODR 能改的;
    • 如果外设没激活(比如串口没初始化),复用引脚的电平会乱跳,一定要先初始化外设。

    六、AFIO:GPIO 的 “搬家公司”(重映射 + 外部中断)

    AFIO 是辅助 GPIO 工作的模块,核心就两件事,先开 AFIO 时钟才能用:

    1. 引脚重映射(实用)

    把外设的默认引脚 “挪到别的引脚”,比如串口 1 默认用 PA9/TX、PA10/RX,如果这两个引脚被占了,就通过 AFIO 把串口 1 挪到 PB6/TX、PB7/RX。

    • 配置寄存器:AFIO_MAPR(改里面的 USART1_REMAP 位就行);
    • 常用场景:JTAG 引脚(PA13/14/15、PB3/4)想当普通 GPIO 用→改 AFIO_MAPR 的 SWJ_CFG 位,关闭 JTAG 即可。

    2. 外部中断配置(必用)

    STM32 的外部中断是 “按引脚号分的”(EXTI0~EXTI15),比如 EXTI0 对应所有端口的 0 号引脚(PA0、PB0、PC0…),AFIO 就是用来 “选哪个端口的引脚触发中断”。

    • 配置寄存器:AFIO_EXTICR1~4(比如想让 PB0 触发 EXTI0 中断,就往 EXTICR1 的 EXTI0 位写 0001);
    • 步骤:先把 GPIO 设为输入模式→用 AFIO 选引脚→配置中断控制器。

    七、复位默认状态(排错必知)

    • 所有 GPIO 复位后默认是 “浮空输入”;
    • JTAG/SWD 引脚(PA13/14/15、PB3/4)复位后带上下拉,想当普通 GPIO 用,必须先通过 AFIO 重映射关闭 JTAG。

    八、工程排错小技巧(实用!)

  • 引脚没反应:先查 CRL/CRH 配置是否正确→查时钟是否打开→查是不是复用功能没配 AFIO;
  • 复用引脚电平乱跳:查外设是否初始化→查 GPIO 模式是不是设成 “复用”(不是通用输出);
  • 中断不触发:查 AFIO 是否选对引脚→查 GPIO 是不是输入模式→查中断控制器是否使能。
  • 总结(核心 3 句话,记死!)

  • 配置 GPIO 先改 CRL/CRH 定模式,改电平优先用 BSRR(安全),读电平必看 IDR(真实);
  • 用串口 / I2C 等复用功能,先开 AFIO 时钟,再配 GPIO 为复用模式,需要的话重映射;
  • 不用记寄存器地址和二进制值,写代码时查手册 / 库函数,核心是 “配置→控制→读取” 的逻辑。
  • 这份 GPIO/AFIO 的核心逻辑适用于所有 STM32 系列,但不同型号(F1/F4/F7/H7/L4 等)有细节差异,工作中只需关注 “通用逻辑 + 型号专属差异” 即可。

    一、通用逻辑(所有 STM32 都适用,记死!)

    不管是 F1/F4/F7,还是 L4/G4/H7,GPIO 的核心设计思路完全一致,你之前记的这些内容通用:

  • 模式分类逻辑:所有 STM32 的 GPIO 都有 “输入(浮空 / 上拉 / 下拉)、输出(推挽 / 开漏)、模拟输入、复用功能” 四大类,只是 F1 叫 “8 种模式”,其他型号可能合并命名,但本质一样;
  • 核心寄存器作用:
    • 配置模式的寄存器(F1 是 CRL/CRH,其他型号可能叫 MODER/OTYPER/OSPEEDR/PUPDR)→ 本质都是 “定模式、定速度、定上下拉”;
    • 读电平的寄存器(IDR)、写电平的寄存器(ODR)、安全改电平的寄存器(BSRR/BRR)→ 功能和用法完全一样,只是位宽可能从 16 位变 32 位;
    • 复用功能核心规则:“GPIO 交给外设控制、需开对应时钟、重映射靠 AFIO/ SYSCFG”→ 逻辑不变;
  • 复用 / 重映射核心:所有型号用串口 / I2C/SPI 等外设时,GPIO 都要设为 “复用模式”,引脚不够用时都能通过 “重映射” 挪位置(只是 F1 叫 AFIO,F4 及以上叫 SYSCFG)。
  • 二、不同型号的关键差异(工作中只记这些,其余可查手册)

    1. F1(你学的这款)vs F4/F7/H7(中高端)

    表格

    差异点STM32F10xx(你的款)STM32F4/F7/H7实用影响
    配置寄存器 CRL/CRH(4 位配 1 个引脚) MODER/OTYPER/OSPEEDR/PUPDR(分寄存器配置) 配置步骤多 1 步,但逻辑一样(比如 F4 先设 MODER 为输出,再设 OTYPER 为推挽)
    重映射模块 AFIO(单独模块) SYSCFG(整合到系统配置) 开时钟时 F4 要开 SYSCFG,F1 开 AFIO,代码改个宏就行
    速度等级 10/2/50MHz 25/50/100/180MHz 配置时选更高速度,不影响用法
    复用模式命名 复用推挽 / 开漏 复用功能模式(自动区分推挽 / 开漏) 不用纠结命名,手册查对应外设的 GPIO 配置即可

    2. F1 vs L0/L4/G4(低功耗 / 性价比款)

    • 核心差异:低功耗型号多了 “开漏上拉”“模拟输出” 等小众模式,还支持 “GPIO 唤醒低功耗”,但日常用的推挽 / 上拉输入 / 复用功能完全和 F1 一样;
    • 实用影响:做低功耗项目时查手册加配置,普通项目(点灯、串口、I2C)直接照搬 F1 的逻辑。

    3. F1 vs STM32H7(高端款)

    • 核心差异:H7 的 GPIO 支持更多引脚、更高电压、更精细的速度控制,还能配置 “施密特触发阈值”,但基础用法(配模式、改电平、读电平)和 F1 完全一致;
    • 实用影响:高端项目关注手册的 “特殊配置”,基础功能不用重新学。

    三、工作中怎么快速适配不同型号(实用技巧)

  • 先抓通用逻辑:不管换哪个型号,先想 “我要让这个引脚做什么(输入 / 输出 / 复用)”,再按 “配置模式→开时钟→改电平 / 接外设” 的步骤来,和 F1 完全一样;
  • 查 “型号专属配置表”:
    • 打开对应型号的参考手册,搜 “GPIO 配置”“外设 GPIO 映射”,比如 F4 的 USART1_TX 默认是 PA9,和 F1 一样,直接配复用模式就行;
    • 重映射时,F1 查 AFIO_MAPR,F4 查 SYSCFG_MEMRMP/SYSCFG_EXTICR,只是寄存器名变了,功能位的逻辑(比如 USART1_REMAP)完全一致;
  • 代码层面的适配:
    • 用 HAL 库:几乎不用改代码,只改引脚定义(比如 F1 是 GPIOA_PIN_0,F4 也是),HAL 库会自动适配寄存器差异;
    • 用寄存器:只需要把 F1 的 CRL/CRH 配置,换成对应型号的 MODER/OTYPER 配置,比如 F1 配 PA0 为推挽输出是改 CRL 的 4 位,F4 是改 MODER 为 01(输出)、OTYPER 为 0(推挽)。
  • 总结(核心 2 句话)

  • 通用逻辑通吃所有 STM32:GPIO 的 “输入 / 输出 / 复用 / 模拟” 四大类、IDR/ODR/BSRR 的用法、复用功能的配置思路,不管哪个型号都一样,你学的 F1 基础完全够用;
  • 差异只在 “细节配置”:不同型号只是寄存器名、速度等级、小众模式有差异,工作中不用记,只要打开对应手册,按 “通用逻辑 + 手册专属配置” 来,5 分钟就能适配新型号。
  • 简单说:你现在吃透的 F1 GPIO 知识,是所有 STM32 的 “通用语法”,换型号只需要查 “单词表(手册)”,不用重新学 “语法规则”。

    一、实验基础信息(硬件 + 功能不变)

    1. 硬件接线

    表格

    器件连接引脚说明
    LED PA0(正极)+ GND(负极) 串 220Ω 限流电阻
    按键 PB0(一端)+ GND(另一端) 上拉输入,按下拉低
    2. 实验功能
    • 默认:LED 以 500ms 频率闪烁;
    • 按键按下:LED 停止闪烁,保持常亮;
    • 按键松开:LED 恢复闪烁。

    #include "stm32f10x.h"

    // 简易ms级延时(72MHz)
    void Delay_ms(uint32_t ms)
    {
    uint32_t i,j;
    for(i=0;i<ms;i++) for(j=0;j<1141;j++);
    }

    // GPIO初始化:PA0(LED输出)、PB0(按键上拉输入)
    void GPIO_Init_LED_Key(void)
    {
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);

    // PA0 通用推挽输出 50MHz
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // PB0 上拉输入
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
    }

    // 读按键:1=按下,0=未按
    uint8_t Key_Read(void)
    {
    return (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) ? 1 : 0;
    }

    int main(void)
    {
    uint8_t key_flag = 0;
    GPIO_Init_LED_Key();

    while(1)
    {
    key_flag = Key_Read();
    if(key_flag) // 按键按下,LED常亮
    GPIO_SetBits(GPIOA, GPIO_Pin_0);
    else // 松开,LED闪烁
    {
    GPIO_SetBits(GPIOA, GPIO_Pin_0);
    Delay_ms(500);
    GPIO_ResetBits(GPIOA, GPIO_Pin_0);
    Delay_ms(500);
    }
    }
    }

    核心要点总结

  • 核心流程:开时钟 → 配 GPIO 模式 → 读按键 / 控 LED;
  • 关键函数:GPIO_SetBits/ResetBits(安全改电平)、GPIO_ReadInputDataBit(读真实电平);
  • 硬件适配:LED 接 PA0、按键接 PB0(上拉输入,按下拉低)。
  • 赞(0)
    未经允许不得转载:171主机测评 » STM32学习——GPIO+AFIO(附LED闪灯与按钮实验)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址