首页 理论教育STM32F4处理器的I/O端口应用

STM32F4处理器的I/O端口应用

【摘要】:1.端口特性每个通用I/O端口包括4个32位配置寄存器、2个32位数据寄存器、1个32位置位/复位寄存器、1个32位锁定寄存器和2个32位复用功能选择寄存器。可为每个I/O选择不同的速度。2.端口使用1)复位后的I/O引脚在复位期间及复位刚刚完成后,复用功能尚未激活,I/O端口被配置为输入浮空模式。这可以确保共用同一个I/O引脚的外设之间不会发生冲突。置位复位寄存器的大小是GPIOx_ODR的2倍。在对GPIOx_ODR进行位操作时,软件无须禁止中断。

1.端口特性

每个通用I/O端口包括4个32位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR和GPIOx_PUPDR)、2个32位数据寄存器(GPIOx_IDR和GPIOx_ODR)、1个32位置位/复位寄存器(GPIOx_BSRR)、1个32位锁定寄存器(GPIOx_LCKR)和2个32位复用功能选择寄存器(GPIOx_AFRH和GPIOx_AFRL)。每个I/O端口位均可自由编程,但I/O端口寄存器必须按32位字、半字或字节进行访问。

GPIO主要特性包括以下几点:

(1)受控I/O多达16个。

(2)输出状态:推挽或开漏+上拉/下拉。

(3)从输出数据寄存器(GPIOx_ODR)或外设(复用功能输出)输出数据。

(4)可为每个I/O选择不同的速度。

(5)输入状态:浮空、上拉/下拉、模拟。

(6)将数据输入输入数据寄存器(GPIOx_IDR)或外设(复用功能输入)。

(7)置位和复位寄存器(GPIOx_BSRR),对GPIOx_ODR具有按位写权限。

(8)锁定机制(GPIOx_LCKR),可冻结I/O配置。

(9)模拟功能。

(10)复用功能I/O选择寄存器(一个I/O最多可具有16个复用功能)。

(11)快速翻转,每次翻转最快只需要两个时钟周期。

(12)引脚复用非常灵活,允许将I/O引脚用作GPIO或多种外设功能中的一种。

根据以上列出的每个I/O端口的特性,可将通用I/O(GPIO)端口的各个端口位分别配置为多种模式:

(1)输入浮空。

(2)输入上拉。

(3)输入下拉。

(4)模拟功能。

(5)具有上拉或下拉功能的开漏输出。

(6)具有上拉或下拉功能的推挽输出。

(7)具有上拉或下拉功能的复用功能推挽。

(8)具有上拉或下拉功能的复用功能开漏。

2.端口使用

1)复位后的I/O引脚

在复位期间及复位刚刚完成后,复用功能尚未激活,I/O端口被配置为输入浮空模式。复位后,调试引脚处于复用功能上拉/下拉状态。

(1)PA15:JTDI处于上拉状态。

(2)PA14:JTCK/SWCLK处于下拉状态。

(3)PA13:JTMS/SWDAT处于下拉状态。

(4)PB4:NJTRST处于上拉状态。

(5)PB3:JTDO处于浮空状态。

当引脚配置为输出后,写入输出数据寄存器(GPIOx_ODR)的值将在I/O引脚上输出。可以在推挽模式或开漏模式下使用输出驱动器。输入数据寄存器(GPIOx_IDR)每隔一个AHB1时钟周期捕获一次I/O引脚的数据。所有GPIO引脚都具有内部弱上拉及下拉电阻,可根据GPIOx_PUPDR寄存器中的值来打开/关闭。

2)I/O引脚的复用和映射

微控制器I/O引脚通过一个复用器连接到板载外设/模块,该复用器一次仅允许一个外设的复用功能(AF)连接到I/O引脚。这可以确保共用同一个I/O引脚的外设之间不会发生冲突。每个I/O引脚都有一个复用器,该复用器采用16路复用功能输入(AF0~AF15),可通过GPIOx_AFRL(针对引脚0~7)和GPIOx_AFRH(针对引脚8~15)寄存器对这些输入进行配置。

(1)完成复位后,所有I/O都会连接到系统的复用功能0(AF0)。

(2)外设的复用功能映射到AF1~AF13。

(3)Cortex-M4FEVENTOUT映射到AF15。

3)I/O端口相关寄存器

每个GPIO有4个32位存储器映射的控制寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR),可配置多达16个I/O。GPIOx_MODER寄存器用于选择I/O方向(输入、输出、AF、模拟)。GPIOx_OTYPER和GPIOx_OSPEEDR寄存器分别用于选择输出类型(推挽或开漏)和速度(无论采用哪种I/O方向,都会直接将I/O速度引脚连接到相应的GPIOx_OSPEEDR寄存器位)。无论采用哪种I/O方向,GPIOx_PUPDR寄存器都用于选择上拉/下拉。

每个GPIO都具有2个16位数据寄存器,即输入数据寄存器和输出数据寄存器(GPIOx_IDR和GPIOx_ODR)。GPIOx_ODR用于存储待输出数据,可对其进行读/写访问。通过I/O输入的数据存储到输入数据寄存器(GPIOx_IDR)中,该寄存器是一个只读寄存器。

4)I/O端口数据位操作(www.chuimin.cn)

置位复位寄存器(GPIOx_BSRR)是一个32位寄存器,它允许应用程序在输出数据寄存器(GPIOx_ODR)中对各个单独的数据位执行置位和复位操作。置位复位寄存器的大小是GPIOx_ODR的2倍。

GPIOx_ODR中的每个数据位对应GPIOx_BSRR中的两个控制位:BSRR(i)和BSRR(i+SIZE)。当写入1时,BSRR(i)位会置位对应的ODR(i)位。当写入1时,BSRR(i+SIZE)位会清零ODR(i)对应的位。

在GPIOx_BSRR中向任何位写入0都不会对GPIOx_ODR中的对应位产生影响。如果在GPIOx_BSRR中同时尝试对某个位执行置位和清零操作,则置位操作优先。

使用GPIOx_BSRR寄存器更改GPIOx_ODR中各个位的值是一个“单次”操作,不会锁定GPIOx_ODR位,随时可以直接访问GPIOx_ODR位。GPIOx_BSRR寄存器提供了一种执行按位处理的方法。

在对GPIOx_ODR进行位操作时,软件无须禁止中断。

5)GPIO锁定机制

通过将特定的写序列应用到GPIOx_LCKR寄存器,可以冻结GPIO控制寄存器。冻结的寄存器包括GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR、GPIOx_AFRL和GPIOx_AFRH。

要对GPIOx_LCKR寄存器执行写操作,必须应用特定的写/读序列。当正确的LOCK序列应用到此寄存器的第16位后,会使用LCKR[15:0]的值来锁定I/O的配置(在写序列期间,LCKR[15:0]的值必须相同)。将LOCK序列应用到某个端口位后,在执行下一次复位之前,将无法对该端口位的值进行修改。每个GPIOx_LCKR位都会冻结控制寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR、GPIOx_PUPDR、GPIOx_AFRL和GPIOx_AFRH)中的对应位。

LOCK序列只能通过对GPIOx_LCKR寄存器进行字(32位长)访问的方式来执行,因为GPIOx_LCKR的第16位必须与[15:0]位同时置位。

6)I/O端口复用功能

有2个寄存器(GPIOx_AFRL和GPIOx_AFRH)可用来从每个I/O可用的16个复用功能I/O中进行选择。借助这些寄存器,可根据应用程序的要求将某个复用功能连接到其他某个引脚。

这意味着可使用GPIOx_AFRL和GPIOx_AFRH复用功能寄存器在每个GPIO上复用多个可用的外设功能。因此,应用程序可为每个I/O选择任何一个可用功能。由于AF选择信号由复用功能输入和复用功能输出共用,因此只需为每个I/O的复用功能I/O选择一个通道即可。所有端口都具有外部中断功能。要使用外部中断线,必须将端口配置为输入模式。

7)输入/输出配置方法

当I/O端口进行编程作为输入时,输出缓冲器被关闭;施密特触发器输入被打开;根据GPIOx_PUPDR寄存器中的值决定是否打开上拉和下拉电阻;输入数据寄存器每隔1个AHB1时钟周期对I/O引脚上的数据进行一次采样;对输入数据寄存器的读访问可获取I/O状态。

当I/O端口进行编程作为输出时,首先输出缓冲器被打开。在开漏模式下,输出寄存器中的“0”可激活N-MOS,而输出寄存器中的“1”会使端口保持高组态(P-MOS始终不激活)。在推挽模式下,输出寄存器中的“0”可激活N-MOS,而输出寄存器中的“1”可激活P-MOS。

其次施密特触发器输入被激活,根据GPIOx_PUPDR寄存器中的值决定是否打开弱上拉电阻和下拉电阻,输入数据寄存器每隔1个AHB1时钟周期对I/O引脚上的数据进行一次采样。在开漏模式下,对输入数据寄存器的读访问可获取I/O状态;在推挽模式下,对输出数据寄存器的读访问可获取最后的写入值。

8)模拟配置方法

当I/O端口进行编程作为模拟配置时,输出缓冲器被禁止;施密特触发器输入停用,I/O引脚的每个模拟输入的功耗变为零。施密特触发器的输出被强制处理为恒定值(0),弱上拉和下拉电阻被关闭,对输入数据寄存器的读访问值为“0”。

3.I/O端口初始化函数

GPIO相关函数和定义分布在固件库文件stm32f4××_GPIO.c和头文件stm32f4××_GPIO.h文件中。在固件库开发中,操作4个配置寄存器初始化GPIO通过GPIO初始化函数完成:

这个函数有2个参数,第1个参数用来指定需要初始化的GPIO对应的GPIO组,取值范围为GPIOA~GPIOK。第2个参数为初始化参数结构体指针,结构体类型为GPIO_InitTypeDef。

下面来看这个结构体的定义。

下面通过一个GPIO初始化实例来讲解这个结构体的成员变量的含义。通过初始化结构体初始化GPIO的常用格式如下:

上面代码的意思是,设置GPIOF的第9个端口为推挽输出模式,速度为100MHz,上拉形式。从上面初始化代码可以看出,结构体GPIO_InitStructure的第一个成员变量GPIO_Pin用来设置是要初始化哪个或哪些I/O口。

第2个成员变量GPIO_Mode用来设置对应I/O端口的I/O端口模式,这个值实际就是配置GPIOx的MODER寄存器的值。在MDK中端口模式是通过一个枚举类型定义的,其参数值GPIO_Mode_IN表示设置为复位状态的输入,GPIO_Mode_OUT表示通用输出模式,GPIO_Mode_AF表示复用功能模式,GPIO_Mode_AN表示模拟输入模式。

第3个成员变量GPIO_Speed是I/O口输出速度设置,有4个可选值,即配置GPIO对应的OSPEEDR寄存器的值。在MDK中输出速度同样是通过枚举类型定义的,其参数值GPIO_Speed_2MHz等同于GPIO_Low_Speed,GPIO_Speed_25MHz等同于GPIO_Medium_Speed,GPIO_Speed_50MHz等同于GPIO_Fast_Speed,GPIO_Speed_100MHz等同于GPIO_High_Speed。

第4个成员变量GPIO_OType是GPIO的输出类型设置,即配置GPIO对应的OTYPER寄存器的值。在MDK中输出类型设置也是通过枚举类型定义的,其参数值GPIO_OType_PP表示输出推挽模式,GPIO_OType_OD表示输出开漏模式。

第5个成员变量GPIO_PuPd用来设置I/O口的上下拉,即配置GPIO对应的PUPDR寄存器的值。同样,通过枚举类型列出,其参数值GPIO_PuPd_NOPULL为不使用上下拉,GPIO_PuPd_UP为上拉,GPIO_PuPd_DOWN为下拉,只需根据需要设置相应的值即可。

4.I/O端口主要固件函数

1)I/O端口输出控制函数

在固件库中设置ODR寄存器的值来控制I/O口的输出状态是通过函数GPIO_Write来实现的。函数格式如下:

该函数可用来一次性向GPIO的多个端口设值。大部分情况下,设置I/O口不用这个函数。使用实例如下:

2)I/O端口输出状态读函数

固件库函数可以通过读ODR寄存器检测I/O口的输出状态。函数格式如下:

这两个函数功能类似,只不过前者一次性读取某组端口所有I/O口输出状态,后者一次性读取某组端口的一个或多个I/O口的输出状态。使用实例如下:

3)I/O端口输入状态读函数

固件库函数可以通过读ODR寄存器检测I/O口的输入状态。函数格式如下:

使用实例如下:

4)I/O端口电平写函数

库函数操作BSRR寄存器来设置I/O电平的函数如下:

第1行用来设置某组端口中的一个或多个I/O口为高电平。第2行用来设置某组端口中一个或多个I/O口为低电平。使用实例如下: