1、综述
<1> STM32F4最多有9组I/O,大多数组每组有0~15,一共有16个IO口。每组通用I/O端口由10个32位寄存器控制:
4个32位配置寄存器(MODER,OTYPER,OSPEED,PUPDR);
2个32位数据寄存器(IDR和ODR);
1个32位置位/复位寄存器(BSRR);
1个32位锁定寄存器(LCKR);
2个32位复用功能选择寄存器(AFRH和AFRL)。
<2>STM32F4的IO口的8中工作模式:
浮空输入;
输入上拉;
输入下拉;
模拟输入;
开漏输出;
推挽输出;
推挽式复用功能;
开漏式复用功能。
2、主要寄存器介绍
参数配置寄存器
(1)MODER
用于控制GPIO的端口模式。32位寄存器,控制一组中的16个IO,那么,每两位控制一个IO。
(2)OTYPER
用于控制GPIO的输出类型。该寄存器仅用于输出模式,到底是推挽输出,还是开漏输出。在输入模式下不起作用。该寄存器低16位有效,每一个位控制一个IO口。复位后,该寄存器值均为0(复位后默认输出推挽)。
(3)OSPEEDER
用于控制GPIO的输出速度。也是在输入模式下不起作用。共32位,每两个位控制一个IO口。
(4)PUPDR
用于控制GPIO的上拉下拉。可以设置为:
00:无上拉或下拉;
01:上拉;
10:下拉;
11:保留。
32位寄存器,控制一组中的16个IO,那么,每两位控制一个IO。
输入输出电平控制相关寄存器
(5)ODR
用于控制GPIOx的输出,该寄存器用来设置某个IO输出低电平还是高电平,该寄存器也是仅在输出模式下有效,在输入模式下不起作用。32位寄存器,低16位有效,一位控制同一组内的一个IO口。
(6)IDR
用于读取GPIOx的输入,该寄存器用来读取某个IO的电平是低电平还是高电平,32位寄存器,低16位有效,一位对应同一组内的一个IO口。
(7)BSRR
该寄存器用来置位或者复位IO口。该寄存器有32位,高16位是BR15~BR0,用来复位;低16位是BS15~BS0,用来置位。对于BSRR寄存器,你写0的话,对IO口电平是没有任何影响的,要设置那个IO口(置位或者复位),向相应的位写1。当对于同一个IO复位置位矛盾时,置位的优先级较高。
(8)AFRH和AFRL
这两个寄存器用来设置IO口的复用功能。
3、库文件和头文件
GPIO相关的函数和定义分布在固件库文件stm32f4xx_gpio.c和库文件stm32f4xx_gpio.h中。
4、初始化函数
void GPIO_Init(GPIO_TypeDef* GPIOx,GPIO_InitTypeDef* GPIO_InitStruct)
函数在stm32f4xx_gpio.c文件中R202处定义。函数有两个参数:第一个参数是哪一组GPIO,第二个参数是一个结构体指针,配置上面的四个寄存器。
5、其他寄存器对应的常用函数
(1)读取某个IO口的电平
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
第1个函数是用来读取一组IO口中的一个或者几个IO口输入电平;第2个函数用来一次性读取一组IO口所有IO口的输入电平。<查看IDR寄存器>
(2)设置某个IO口的电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
void GPIO_ResetBits(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
函数在stm32f4xx_gpio.c文件中R412处定义。第1个函数是用来读取一组IO口中的一个或者几个IO口为高电平;第2个函数用来设置一组IO口所有IO口为低电平。<设置BSRR寄存器>
6、IO口的操作步骤
(1)使能IO口时钟。调用函数
RCC_AHB1PeriphClockCmd();
(2)初始化IO口参数。调用函数
GPIO_Init();
(3)操作IO口。
7、配置实例
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义参数配置结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//使能IO口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//同时设置两个IO口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//输出速度
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化GPIO
GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10 初始化时 设置为高电平 灯灭
}