一、GPIO 是什么?
GPIO,全称为General Purpose Input Output Ports(通用输入输出端口),也就是通用IO口。
GPIO是控制或者采集外部器件的信息的外设,可以由软件程序控制,用于输出或者输入高低电平。
GPIO的使用非常广泛。可以与硬件进行数据交互(如UART),控制硬件工作(如LED、蜂鸣器等),读取硬件的工作状态信号(如中断信号)等。
GPIO按组分配,每组16个I/O口,组数视芯片而定。
以STM32F429IGT6为例:
① 一共有9组IO,PA~PI。
② 一共有140个IO口,其中PA~PH每组有16个IO,PI只有12个IO口。
注意:芯片的数据手册中,引脚标注为 FT 的,是可以兼容 5V 电平的。
二、GPIO 的 8 种工作模式
8种工作模式,分为4种输入模式和4种输出模式。
1. 浮空输入模式(GPIO_Mode_IN_FLOATING)
浮空输入模式下,上拉/下拉电阻为断开状态,施密特触发器为开启状态,I/O引脚的输出功能被禁止。
该模式下,外部的电平信号通过①(I/O引脚)进入MCU,先经过②(施密特触发器)的整形后,再进入③(输入数据寄存器),最后MCU可以在④(输入数据寄存器的另一端)随时读取I/O引脚的电平。
即,整形后的I/O引脚的电平信号直接进入输入数据寄存器,MCU直接读取I/O引脚的电平。
如果I/O引脚无输入时,MCU读取到的电平状态是不确定的。所以引脚不建议悬空,易受干扰。
如果I/O引脚输入高电平时,MCU读取到高电平1。
如果I/O引脚输入低电平时,MCU读到低电平0。
总结,浮空输入模式:
I/O引脚输入什么电平信号,MCU就读取到什么电平信号;
无信号输入(默认)时,MCU读取到的电平信号是不确定的。
浮空输入模式,可以用于KEY识别,RX1等。
2. 上拉输入模式(GPIO_Mode_IPU)
上拉输入模式下,上拉电阻导通,施密特触发器处于开启状态,I/O引脚的输出功能被禁止。
GPIO的内部上拉电阻的阻值较大,所以通过内部上拉输出的电流是很弱的,即“弱电流”。
如果需要大电流用作电流型驱动输出,还是要用外部上拉电阻。
上拉输入模式与浮空输入模式不同之处,是在①(I/O引脚)和②(施密特触发器)之间接入了一个上拉电阻,将电位拉高,比如拉到VCC。
如果I/O引脚无输入时,I/O引脚处相当于断开,上拉电阻的电流直接流向④,MCU读取到高电平1。
如果I/O引脚输入高电平时,I/O引脚的电压等于VDD的电压,电流还是流向④,MCU读取到高电平1。
如果I/O引脚输入低电平时,I/O引脚处相当于接地,上拉电阻的电流直接流向I/O引脚,MCU读到低电平0。
总结,上拉输入模式:
无信号输入(默认)或输入高电平时,MCU都是读取到高电平1;
输入低电平时,MCU读取到低电平0。
上拉输入模式,可以用于按键检测。
3. 下拉输入模式(GPIO_Mode_IPD)
下拉输入模式下,下拉电阻导通,施密特触发器处于开启状态,I/O引脚的输出功能被禁止。
下拉输入模式与浮空输入模式不同之处,是在①(I/O引脚)和②(施密特触发器)之间接入了一个下拉电阻,将电位拉低,比如拉到GND。
如果I/O引脚无输入时,I/O引脚处相当于断开,I/O引脚的电压等于VSS的电压,MCU读取到低电平0。
如果I/O引脚输入高电平时,由于下拉电阻阻值比通道④的阻值大,所以电流流向④,MCU读取到高电平1。
如果I/O引脚输入低电平时,I/O引脚处相当于接地,I/O引脚的电压等于VSS的电压,MCU读到低电平0。
总结,下拉输入模式:
无信号输入(默认)或输入低电平时,MCU都是读取到低电平0;
输入高电平时,MCU读取到高电平1。
下拉输入模式,和上拉输入模式相似,可以用于按键检测。
4. 模拟输入模式(GPIO_Mode_AIN)
模拟模式下,上拉/下拉电阻为断开状态,施密特触发器为关闭状态,输出部分的双MOS管也断开。
模拟输入模式下,外部的电平信号通过①(I/O引脚的模拟输入通道)进入MCU,MCU可以直接在③(模拟输出口)随时读取I/O引脚的电平。
由于施密特触发器断开,所以电信号也无法进入输入数据寄存器,所以MCU无法在“输入数据寄存器”中读取到有效的数据。
总结,模拟输入模式:
输入的电信号为模拟电压信号,而不是数字电平信号。
模拟输入的模拟电压信号,直接送到片上外设,一般是ADC。
除了 ADC 和 DAC 要将 I/O 配置为模拟通道之外,其他外设功能一律要配置为复用功能模式。
模拟输入模式,可以用于ADC采集或DAC输出,或者低功耗下省电。
5. 开漏输出模式(GPIO_Mode_Out_OD)
开漏输出模式下,P-MOS管一直处于断开状态。
开漏输出模式下,MCU通过左边的①(位设置/清除寄存器)或(输出数据寄存器)写入数据后,该数据位将通过②(输出控制电路)传送到④(I/O引脚)。
同时,输入功能可用,⑤(施密特触发器)处于开启状态,可以通过⑥(输入数据寄存器)可读取④(I/O引脚)的实际电平状态。
当MCU输出低电平0时,经过“非门”后,转换为高电平1,N-MOS管导通,使I/O引脚输出低电平。
当MCU输出高电平1时,经过“非门”后,转换为低电平0,N-MOS管断开,I/O引脚处于悬空状态,此时I/O引脚输出的电平高低是由I/O引脚外部的上拉或者下拉决定。
开漏输出,输出端相当于三极管的集电极。要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对较强,一般20mA以内。
6. 开漏复用输出模式(GPIO_Mode_AF_OD)
GPIO可以是通用的IO口功能,还可以是其他外设的特殊功能引脚,这就是GPIO的复用功能。
GPIO复用为其他外设,输出数据寄存器无效,④(I/O引脚)输出的高低电平由①(其他外设的输出)决定。
同时,输入功能可用,⑤(施密特触发器)处于开启状态,可以通过⑥(输入数据寄存器)可读取④(I/O引脚)的实际电平状态,同时外设可以读取IO引脚的信息。
开漏复用输出模式与开漏输出模式的配置基本相同,除了输出信号的来源不同,其他与开漏输出模式的功能相同。
即,②(输出控制电路)的输入,开漏输出模式是由输出数据寄存器输出,开漏复用输出模式是由其他外设输出。
7. 推挽输出模式(GPIO_Mode_Out_PP)
推挽输出模式,从结果上看它会输出低电平VSS或者高电平VDD。推挽输出跟开漏输出不同的是,推挽输出模式P-MOS管和N-MOS管都用上,可以把“输出控制”简单地等效为一个非门。
当MCU输出低电平0时,经过“非门”后,转换为高电平1,P-MOS管截止,N-MOS管导通,使I/O引脚下拉到VSS,即I/O引脚输出低电平。
当MCU输出高电平1时,经过“非门”后,转换为低电平0,P-MOS管导通,N-MOS管截止,使I/O引脚上拉到VDD,即I/O引脚输出高电平。
同时,输入功能可用,⑤(施密特触发器)处于开启状态,可以通过⑥(输入数据寄存器)可读取④(I/O引脚)的实际电平状态。
总结,推挽输出模式下,P-MOS管和N-MOS管同一时间只能有一个MOS管是导通的。当引脚高低电平切换时,两个管子轮流导通,一个负责灌电流,一个负责拉电流,使其负载能力和开关速度都有很大的提高。
由于推挽输出模式输出高电平时,是直接连接VDD,所以驱动能力较强,可以做电流型驱动,驱动电流最大可达25mA。该模式也是最常用的输出模式。
8. 推挽复用输出模式(GPIO_Mode_AF_PP)
GPIO可以是通用的IO口功能,还可以是其他外设的特殊功能引脚,这就是GPIO的复用功能。
GPIO复用为其他外设,输出数据寄存器无效,④(I/O引脚)输出的高低电平由①(其他外设的输出)决定。
同时,输入功能可用,⑤(施密特触发器)处于开启状态,可以通过⑥(输入数据寄存器)可读取④(I/O引脚)的实际电平状态,同时外设可以读取IO引脚的信息。
推挽复用输出模式与推挽输出模式的配置基本相同,除了输出信号的来源不同,其他与推挽输出模式的功能相同。
即,②(输出控制电路)的输入,推挽输出模式是由输出数据寄存器输出,推挽复用输出模式是由其他外设输出。
三、GPIO 寄存器
每组GPIO的寄存器包括:
配置寄存器:
一个端口模式寄存器(GPIOx_MODER)
一个端口输出类型寄存器(GPIOx_OTYPER)
一个端口输出速度寄存器(GPIOx_OSPEEDR)
一个端口上拉下拉寄存器(GPIOx_PUPDR)
数据寄存器:
一个端口输入数据寄存器(GPIOx_IDR)
一个端口输出数据寄存器(GPIOx_ODR)
置位/复位寄存器:
一个端口置位/复位寄存器(GPIOx_BSRR)
锁存寄存器:
一个端口配置锁存寄存器(GPIOx_LCKR)
复用功能共寄存器:
两个复用功能寄存器(低位GPIOx_AFRL & 高位GPIOx_AFRH)
注意:
① 每组GPIO由10个寄存器组成,如果芯片有 GPIOA ~ GPIOI 9个组,那么一共有对应90个寄存器。
② 如果配置一个I/O口需要2个位,那么刚好32位寄存器配置一组16个I/O口。
③ 如果配置一个I/O口只需要1个位,一般高16位保留。
④ BSRR寄存器32位分为低16位BSRRL和高16位BSRRH,
BSRRL配置一组16个I/O口的置位状态(1),
BSRRH配置一组16个I/O口的复位状态(0)。
⑤ rw表示可读可写;r表示只可读;w表示只可写;Res.表示保留位,必须保持复位值。
GPIO 工作模式 | 模式寄存器 MODER[0:1] |
输出类型寄存器 OTYPER |
输出速度寄存器 OSPEEDR[0:1] |
上拉/下拉寄存器 PUPDR[0:1] |
输入浮空 | 00 - 输入模式 | 无效 | 无效 | 00 - 无上拉或下拉 |
输入上拉 | 01 - 上拉 |
|||
输入下拉 | 10 - 下拉 |
|||
模拟功能 | 11 - 模拟模式 | 00 - 无上拉或下拉 |
||
开漏输出 | 01 - 通用输出 | 1 - 开漏输出 | 00 - 低速 |
00 - 无上拉或下拉 |
推挽输出 | 0 - 推挽输出 | |||
开漏式复用功能 | 10 - 复用功能 | 1 - 开漏输出 | ||
推挽式复用功能 | 0 - 推挽输出 |
1. GPIO端口模式寄存器(GPIOx_MODER)
该寄存器是GPIO的模式控制寄存器,用于控制GPIO的工作模式。
该寄存器共32位,每2个位控制1个I/O口。
以 GPIOA = 0xABFFFFFF 为例:
① 低16位的值是FFFF,都是1,即 PA0 ~ PA7 默认都是模拟模式。
② 高16位的值是0xABFF,即 PA8 ~ PA12 是模拟模式,PA13 ~ PA15 是复用功能模式。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
MODER15[1:0] | MODER14[1:0] | MODER13[1:0] | MODER12[1:0] | MODER11[1:0] | MODER10[1:0] | MODER9[1:0] | MODER8[1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
MODER7[1:0] | MODER6[1:0] | MODER5[1:0] | MODER4[1:0] | MODER3[1:0] | MODER2[1:0] | MODER1[1:0] | MODER0[1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 2y+1:2y MODERy[1:0]:端口x配置位(Port x configuration bits)(y=0…15)
这些位通过软件写入,用于配置 I/O 模式。
00:输入模式(复位状态)
01:通用输出模式
10:复用功能模式
11:模拟模式
2. GPIO端口输出类型寄存器(GPIOx_OTYPER)
该寄存器用于控制GPIO的输出类型,仅用于输出模式,在输入模式(MODER[1:0] = 00 / 11 时)下不起作用。
该寄存器的低16位有效,每1个位控制1个I/O口。
复位后,该寄存器的值均为0,即I/O口在输出模式下默认为推挽输出。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
OT15 | OT14 | OT13 | OT12 | OT11 | OT10 | OT9 | OT8 | OT7 | OT6 | OT5 | OT4 | OT3 | OT2 | OT1 | OT0 |
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 31:16 :保留,必须保持复位值。
位 15:0 OTy:端口x配置位(Port x configuration bits)(y=0…15)
这些位通过软件写入,用于配置 I/O 输出类型。
0:推挽输出(复位状态)
1:开漏输出
3. GPIO端口输出速度寄存器(GPIOx_OSPEEDR)
该寄存器用于控制GPIO的输出速度,仅用于输出模式,在输入模式(MODER[1:0] = 00 / 11 时)下不起作用。
该寄存器共32位,每2个位控制1个I/O口。
复位后,该寄存器的值均为0,即I/O口在输出模式下默认为推挽输出。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
OSPEEDR15 [1:0] | OSPEEDR14 [1:0] | OSPEEDR13 [1:0] | OSPEEDR12 [1:0] | OSPEEDR11 [1:0] | OSPEEDR10 [1:0] | OSPEEDR9 [1:0] | OSPEEDR8 [1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
OSPEEDR7 [1:0] | OSPEEDR6 [1:0] | OSPEEDR5 [1:0] | OSPEEDR4 [1:0] | OSPEEDR3 [1:0] | OSPEEDR2 [1:0] | OSPEEDR1 [1:0] | OSPEEDR0 [1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 2y+1:2y OSPEEDRy[1:0]:端口x配置位(Port x configuration bits)(y=0…15)
这些位通过软件写入,用于配置 I/O 输出速度。
00:低速 ( 2MHz)
01:中速 ( 25MHz)
10:高速 ( 50MHz)
11:超高速(100MHz)
注: 有关 OSPEEDRy 位以及 V D D V_{DD} VDD 范围和外部负载的值,请参见产品数据手册。
4. GPIO端口上拉/下拉寄存器(GPIOx_PUPDR)
该寄存器用于控制GPIO的上拉/下拉。
该寄存器共32位,每2个位控制1个I/O口。
复位后,该寄存器的值一般为0,即无上拉或下拉。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
PUPDR15 [1:0] | PUPDR14 [1:0] | PUPDR13 [1:0] | PUPDR12 [1:0] | PUPDR11 [1:0] | PUPDR10 [1:0] | PUPDR9 [1:0] | PUPDR8 [1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
PUPDR7 [1:0] | PUPDR6 [1:0] | PUPDR5 [1:0] | PUPDR4 [1:0] | PUPDR3 [1:0] | PUPDR2 [1:0] | PUPDR1 [1:0] | PUPDR0 [1:0] | ||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 2y+1:2y PUPDRy[1:0]:端口x配置位(Port x configuration bits)(y=0…15)
这些位通过软件写入,用于配置 I/O 上拉或下拉。
00:无上拉或下拉
01:上拉
10:下拉
11:保留
5. 端口输入数据寄存器(GPIOx_IDR)
该寄存器用于控制GPIO的输入高电平或者低电平。
该寄存器的低16位有效,每1个位控制1个I/O口。
该寄存器是只读权限,当CPU读访问该寄存器时:
如果对应的某位为0,则表示设置该I/O口输入的是低电平;
如果对应的某位为1,则表示设置该I/O口输入的是高电平。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
IDR 15 |
IDR 14 |
IDR 13 |
IDR 12 |
IDR 11 |
IDR 10 |
IDR 9 |
IDR 8 |
IDR 7 |
IDR 6 |
IDR 5 |
IDR 4 |
IDR 3 |
IDR 2 |
IDR 1 |
IDR 0 |
r | r | r | r | r | r | r | r | r | r | r | r | r | r | r | r |
位 31:16 :保留,必须保持复位值。
位 15:0 :IDRy:端口输入数据(Port input data)(y=0…15)
这些位为只读。它们包含相应 I/O 端口的输入值。
6. 端口输出数据寄存器(GPIOx_ODR)
该寄存器用于控制GPIO的输出高电平或者低电平。
该寄存器的低16位有效,每1个位控制1个I/O口。
当CPU写访问该寄存器时:
如果对应的某位写0,则表示设置该I/O口输出的是低电平;
如果对应的某位写1,则表示设置该I/O口输出的是高电平。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ODR 15 |
ODR 14 |
ODR 13 |
ODR 12 |
ODR 11 |
ODR 10 |
ODR 9 |
ODR 8 |
ODR 7 |
ODR 6 |
ODR 5 |
ODR 4 |
ODR 3 |
ODR 2 |
ODR 1 |
ODR 0 |
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 31:16 :保留,必须保持复位值。
位 15:0 :ODRy:端口输出数据(Port output data)(y=0…15)
这些位可通过软件读取和写入。
注: 对于原子置位/复位,通过写入 GPIOx_BSRR 或 GPIOx_BRR 寄存器,可分别置位和/或复位 ODR 位(x=A…F)。
7. 端口置位/复位寄存器(GPIOx_BSRR)
该寄存器也用于控制GPIO的输出高电平或者低电平。
BSRR寄存器32位有效。
对于低16位(0 ~ 15):
我们往相应的位写1,那么对应的IO口会输出高电平;
我们往相应的位写0,对IO口没有任何影响。
对于高16位(16 ~ 31)作用刚好相反:
我们往相应的位写1,那么对应的IO口会输出低电平;
我们往相应的位写0,对IO口没有任何影响。
总结:
对于BSRR寄存器,写0时,对I/O口电平无影响。
如需输出高电平,则将对应的BS位写1;
如需输出低电平,则将对应的BR位写1。
ODR寄存器和BSRR寄存器的不同之处:
ODR是可读可写权限,而BSRR是只写权限。
ODR寄存器,我们要设置某个IO口电平,我们首先需要读出来ODR寄存器的值,然后对整个ODR寄存器重新赋值来达到设置某个或者某些IO口的目的。
BSRR寄存器,我们就不需要先读,而是直接设置即可,这在多任务实时操作系统中作用很大。
BSRR寄存器比ODR寄存器更好的地方,就是BSRR寄存器改变引脚状态的时候,不会被中断打断。而ODR寄存器有被中断打断的风险。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
BR15 | BR14 | BR13 | BR12 | BR11 | BR10 | BR9 | BR8 | BR7 | BR6 | BR5 | BR4 | BR3 | BR2 | BR1 | BR0 |
w | w | w | w | w | w | w | w | w | w | w | w | w | w | w | w |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
BS15 | BS14 | BS13 | BS12 | BS11 | BS10 | BS9 | BS8 | BS7 | BS6 | BS5 | BS4 | BS3 | BS2 | BS1 | BS0 |
w | w | w | w | w | w | w | w | w | w | w | w | w | w | w | w |
位 31:16 BRy:端口x复位位y(Port x reset bit y)(y=0…15)
这些位为只写。读取这些位可返回值 0x0000。
0:不会对相应的 ODRx 位执行任何操作
1:复位相应的 ODRx 位
注: 如果同时对 BSx 和 BRx 置位,则 BSx 的优先级更高。
位 15:0 BSy:端口x置位位y(Port x set bit y)(y=0…15)
这些位为只写。读取这些位可返回值 0x0000。
0:不会对相应的 ODRx 位执行任何操作
1:置位相应的 ODRx 位
8. 端口配置锁定寄存器(GPIOx_LCKR)
该寄存器的每个锁定位冻结一个特定的配置寄存器(控制寄存器和复用功能寄存器)。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | LCKK |
Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | Res. | rw |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ODR 15 |
ODR 14 |
ODR 13 |
ODR 12 |
ODR 11 |
ODR 10 |
ODR 9 |
ODR 8 |
ODR 7 |
ODR 6 |
ODR 5 |
ODR 4 |
ODR 3 |
ODR 2 |
ODR 1 |
ODR 0 |
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 31:17 :保留,必须保持复位值。
位 16 LCKK:锁定键(Lock key)
可随时读取此位。可使用锁定键写序列对其进行修改。
0:端口配置锁定键未激活
1:端口配置锁定键已激活。在下一次 MCU 复位或外设复位之前,GPIOx_LCKR 寄存器始终处于锁定状态。
位 15:0 LCKy:端口x锁定位y(Port x lock bit y)(y=0…15)
这些位都是读/写位,但只能在 LCKK 位等于 “0” 时执行写操作。
0:端口配置未锁定
1:端口配置已锁定
9. 复用功能寄存器(GPIOx_AFRL、GPIOx_AFRH)
该寄存器分为高位AFRH和低位AFRL,分别控制16位,即分别控制8个I/O口。
复用功能寄存器有2个,都是32位有效的寄存器,分高位(AFRH)和低位(AFRL)。复用器采用16路复用功能输入AF0~AF15,通过GPIOx_AFRL(引脚 0~7)、GPIOx_AFRH(引脚 8~15)寄存器对复用功能输入进行配置,每四位控制1路复用。
I/O口并不能随意复用功能,而是有规定的,可以通过查阅数据手册来获取每个I/O引脚的复用功能。
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
AFR7[3:0] | AFR6[3:0] | AFR5[3:0] | AFR4[3:0] | ||||||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
AFR3[3:0] | AFR2[3:0] | AFR1[3:0] | AFR0[3:0] | ||||||||||||
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位 31:0 AFRy[3:0]:端口x引脚y的复用功能选择(Alternate function selection for port x pin y)(y=0…7)
这些位通过软件写入,用于配置复用功能 I/O 。
AFSELy 选择:
0000:AF0 1000:AF8
0001:AF1 1001:AF9
0010:AF2 1010:AF10
0011:AF3 1011:AF11
0100:AF4 1100:AF12
0101:AF5 1101:AF13
0110:AF6 1110:AF14
0111:AF7 1111:AF15
四、GPIO 库函数
1. 1个初始化函数
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
作用:初始化一个或多个 IO 口的工作模式、输出类型、速度、上下拉方式,分别由4个配置寄存器来配置:GPIOx->MODER
、GPIOx->OSPEEDR
、GPIOx->OTYPER
、GPIOx->PUPDR
。
注意:一次初始化多个 IO 口时,必须是同一个 GPIOx 组下的相同配置方式的多个 IO 口。
2. 1个反初始化函数
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
作用:将一个或多个同一个 GPIOx 组下的 IO 口的配置寄存器,反初始化为其默认重置值。
3. 1个读取输入电平函数
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
作用:通过操作 GPIOx->IDR
寄存器,IO 口作输入时,读取其电平状态是低电平0,还是高电平1。
4. 1个设置输出电平函数
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
作用:IO 口作输出时,设置输出的电平。
5. 1个电平翻转函数
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
作用:令原本输出的低电平,变为高电平;
令原本输出的高电平,变为低电平。
6. 1个引脚电平锁定函数
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
作用:锁定 IO 引脚的配置寄存器,锁定的GPIO引脚不能再修改配置。
文章来源:https://www.toymoban.com/news/detail-797216.html
7. 2个外部中断相关函数
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
五、操作 GPIO 的步骤
(1) 初始化 HAL库:HAL_Init();
。
(2) 初始化系统时钟:Stm32_Clock_Init();
。
(3) 使能 IO 口时钟:
① 操作寄存器的方法:配置 IO 口时钟使能寄存器:RCC -> AHB1ENR
。
② 操作 HAL 库的方法:HAL_RCC_GPIOx_CLK_ENABLE();
。
(4) 初始化 IO 口模式:
① 操作寄存器的方法:GPIOx -> MODER
、GPIOx -> OTYPER
、GPIOx -> OSPEEDR
、GPIOx -> PUPDR
。
② 操作 HAL 库的方法:HAL_GPIO_Init();
。
(5) 操作 IO 口。
文章来源地址https://www.toymoban.com/news/detail-797216.html
到了这里,关于【STM32】GPIO的工作原理和配置的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!