再学GPIO(三)
GPIOx_BRR
寄存器作用
GPIOx_BRR(Bit Reset Register)是 STM32 中专门用于 原子操作清除 GPIO 引脚输出电平(即置低)的寄存器。其核心功能包括:
-
单引脚或多引脚快速置低:通过写入对应位为
1
,直接拉低指定引脚电平。 -
原子性操作:无需读-改-写流程,避免多线程或中断环境下的数据竞争。
-
硬件效率优化:相比直接操作
ODR
或BSRR
,代码更简洁且执行速度更快。
地址偏移:0x14 复位值:0x0000 0000
寄存器结构
位域:
-
-
低 16 位有效(对应 Pin 0 ~ Pin 15),每位控制一个引脚的清除操作:
-
BRy = 1(Bit Reset for Pin
y
):对应引脚输出低电平(ODRy = 0
)。 -
BRy = 0:无影响。
-
-
高 16 位保留(通常写入无效)。
-
配置模式详解
例1
将 PA6 置低。
GPIOA->BRR = (1 << 6); // 写入 BR6=1,PA6 输出低电平
例2
将 PB3、PB5、PB7 同时置低。
GPIOB->BRR = (1 << 3) | (1 << 5) | (1 << 7);
// 等效于 PB3=0, PB5=0, PB7=0
例3
快速切换 PC4 电平(高 → 低 → 高)。
GPIOC->BSRR = (1 << 4); // PC4 置高(BSRR 低16位)
delay_ms(100);
GPIOC->BRR = (1 << 4); // PC4 置低
delay_ms(100);
GPIOx_LCKR
寄存器作用
GPIOx_LCKR(Lock Register)用于 锁定 GPIO 端口的配置,防止后续软件意外修改引脚的工作模式(如输入/输出模式、速度、复用功能等)。锁定后,相关配置寄存器(如 GPIOx_CRL
、GPIOx_CRH
)将无法被修改,直到下次系统复位。
-
保护关键引脚的配置(如安全控制引脚)。
-
防止多任务环境下配置被意外篡改。
-
确保实时性要求高的引脚配置稳定。
地址偏移:0x18 复位值:0x0000 0000
寄存器结构
位域:
位域 | 名称 | 描述 |
---|---|---|
LCKK | Bit 16 | 锁定键:写 1 使能锁定操作,写 0 无效。需按特定顺序写入。 |
LCKy | Bit 0~15 | 引脚锁定位:对应 Pin 0~15。写 1 锁定引脚配置,写 0 无影响。 |
配置模式详解
锁定步骤
-
设置目标引脚锁定位(LCKy=1):选择需要锁定的引脚(可同时锁定多个)。
-
置位锁定键(LCKK=1):向
LCKK
位写1
。 -
清零锁定键(LCKK=0):向
LCKK
位写0
。 -
再次置位锁定键(LCKK=1):向
LCKK
位写1
。 -
读取锁定键(LCKK)确认:若
LCKK
位为1
,表示锁定成功。
例
锁定 PA0 和 PA2 的配置
// 步骤1:设置 LCK0 和 LCK2 为 1(锁定 PA0 和 PA2)
GPIOA->LCKR = GPIO_LCKR_LCK0 | GPIO_LCKR_LCK2;// 步骤2:置位锁定键(LCKK=1)
GPIOA->LCKR = GPIO_LCKR_LCK0 | GPIO_LCKR_LCK2 | GPIO_LCKR_LCKK;// 步骤3:清零锁定键(LCKK=0)
GPIOA->LCKR = GPIO_LCKR_LCK0 | GPIO_LCKR_LCK2;// 步骤4:再次置位锁定键(LCKK=1)
GPIOA->LCKR = GPIO_LCKR_LCK0 | GPIO_LCKR_LCK2 | GPIO_LCKR_LCKK;// 步骤5:读取 LCKK 确认锁定成功
if (GPIOA->LCKR & GPIO_LCKR_LCKK) {// 锁定成功
}
实践
实现LED闪烁实验
使用标准库实现
#include "stm32f10x.h"
#include "delay.h"int main(void)
{Delay_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 开启GPIOC的时钟GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStruct);// GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET);// GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET);while(1){GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // 亮Delay(100); GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // 灭Delay(100); }
}
操作GPIO寄存器实现
#include "stm32f10x.h"
#include "delay.h"int main(void) {// 使能GPIOC时钟RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;// 配置PC13为通用推挽输出模式,最大速度2MHzGPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);GPIOC->CRH |= GPIO_CRH_MODE13_0;while (1){// 点亮LEDGPIOC->BRR = GPIO_Pin_13;Delay(100);// 熄灭LEDGPIOC->BSRR = GPIO_Pin_13;Delay(100);}
}