STM32设置GPIO模式
1. 宏定义功能
I2C软件模拟驱动(Bit-Banging),寄存器方式设置GPIO:
#define SDA_IN() {GPIOB->CRH&=0X0FFFFFFF;GPIOB->CRH|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRH&=0X0FFFFFFF;GPIOB->CRH|=(u32)3<<28;}
此代码常见于I2C通过快速切换引脚方向实现双向数据传输:
函数 | 引脚功能配置 | 寄存器值 | 应用场景 |
SDA_IN | 浮空输入 | CNF15=10, MODE15=00 | 读取从设备数据 |
SDA_OUT | 推挽输出,速度50MHz | CNF15=00, MODE15=11 | 主机发送数据 |
优点:直接操作寄存器,切换速度快,适合实时性要求高的场景(如I2C位翻转)。
缺点:可读性较差,需熟悉寄存器位域定义。
2. 代码解析
(1) 基本概念
操作寄存器:
GPIOB->CRH
(控制GPIOB的Pin8~Pin15)。移位操作: x << n, 将x向左移动n位
引脚确定:操作的是 Pin15(因为每引脚占4位,
28 = 7×4
,对应Pin15的配置位)。
(2) 寄存器操作逻辑
GPIOB->CRH &= 0X0FFFFFFF
:0x0FFFFFFF
=0000 1111 1111 1111 1111 1111 1111 1111
将CRH寄存器的[31:28]
位(Pin15的CNF15和MODE15)清零,保留其他引脚配置
GPIOB->CRH |= (u32)8<<28
: 8<<28 = 1000 0000 0000 0000 0000 0000 0000 0000
CNF15[1:0] = 10
:浮空输入模式; MODE15[1:0] = 00
:输入无需速度配置。
GPIOB->CRH |= (u32)3<<28
:3<<28 = 0011 0000 0000 0000 0000 0000 0000 0000
CNF15[1:0] = 00
:推挽输出模式; MODE15[1:0] = 11
:输出速度50MHz
(3) HAL库等效代码
若使用STM32 HAL库,等效代码如下:
// SDA_IN(): 浮空输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 浮空输入
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);// SDA_OUT(): 推挽输出,50MHz
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_50MHz;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
注意事项
时钟使能:操作前需确保GPIOB时钟已启用(
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN
)。引脚冲突:避免与其他外设(如SPI、TIM)复用引脚时配置冲突。
位域安全:在多任务环境中,操作寄存器需加锁或关中断防止竞态条件。