一、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 电平的。

ST官方提供的GPIO基本结构图

GPIO基本结构图


二、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.表示保留位,必须保持复位值。

配置8种工作模式
GPIO 工作模式 模式寄存器
MODER[0:1]
输出类型寄存器
OTYPER
输出速度寄存器
OSPEEDR[0:1]
上拉/下拉寄存器
PUPDR[0:1]
输入浮空 00 - 输入模式 无效 无效

00 - 无上拉或下拉

输入上拉

01 - 上拉

输入下拉

10 - 下拉

模拟功能 11 - 模拟模式

00 - 无上拉或下拉

开漏输出 01 - 通用输出 1 - 开漏输出

00 - 低速
01 - 中速
10 - 高速
11 - 超高速

00 - 无上拉或下拉
01 - 上拉
10 - 下拉
11 - 保留

推挽输出 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->MODERGPIOx->OSPEEDRGPIOx->OTYPERGPIOx->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引脚不能再修改配置。

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 -> MODERGPIOx -> OTYPERGPIOx -> OSPEEDRGPIOx -> PUPDR
    ② 操作 HAL 库的方法:HAL_GPIO_Init();
  (5) 操作 IO 口。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐