通常来说,GPIO 的工作模式会在初始化时就确定好,但是在芯片工作中偶尔还是会出现需要改变 GPIO 工作模式的情况,比如在没有外接电阻的情况下用软件模拟 I2C,这时候就需要通过寄存器进行操作。

涉及到的寄存器

一组 GPIO 有 16 个 IO 口,每个 IO 口都需要配置输入或输出、具体的输入输出模式,也就需要 4 位二进制,总共需要 64 位二进制,而 STM32 的寄存器为 32 位,所以 GPIO 工作模式的配置寄存器就分成了两个:CRL(GPIOx,x=0~7),CRH(GPIOx,x=8~15)。

其中,每个 GPIO 口对应的 4 位寄存器分为两部分:CNF(高 2 位),MODE(低 2 位)。CNF 对应具体的输入输出模式,MODE 对应输入或输出,如下表所示:

寄存器名 配置位含义
CNF 输入模式下:
00 模拟输入
01 浮空输入(复位后的状态)
10 上拉/下拉输入
11 保留

输出模式下
00 通用推挽输出
01 通用开漏输出
10 复用推挽输出
11 复用开漏输出
MODE 00 输入模式(复位后的状态)
01 输出模式,最大速度 10MHz
10 输出模式,最大速度 2MHz
11 输出模式,最大速度 50MHz

怎么操作

假设我想把 PB11 改成浮空输入(改成其他模式以此类推),PB11 是高 8 位的 GPIO,因此这里需要操作 CRH 寄存器。

第一步,清零寄存器位

为了后面方便写入寄存器,要先清空寄存器位。前面说了,每个 GPIO 口对应 4 位寄存器,PB11 是高 8 位 GPIO 中的第4 位,因此需要将 CRH 的 12~15 位清零。代码如下:

GPIOB->CRH &= 0xFFFF0FFF

第二步,写入寄存器

因为是浮空输入,所以 MODE 应该为 00,CNF 应该为 01,拼起来就是[CNF, MODE]=[01,00]=4(十进制)。代码如下:

GPIOB->CRH |= 4<<12

两步合起来,用宏定义表示如下:

#define PB11_IN() {GPIOB->CRH &= 0xFFFF0FFF;GPIOB->CRH |= 4<<12;}
最后修改:2023 年 05 月 14 日
如果觉得我的文章对你有用,请随意赞赏