【STM32F407学习笔记】GPIO(一)
1. GPIO基础知识
1.1 GPIO工作方式
- 4种输入模式:
- 输入浮空
- 输入上拉
- 输入下拉
- 模拟输入
- 4种输出模式:
- 开漏输出(带上拉或下拉)
- 开漏复用功能(带上拉或下拉)
- 推挽输出(带上拉或下拉)
- 推挽复用功能(带上拉或下拉)
- 4种最大输出速度:
- 2MHz
- 25MHz
- 50MHz
- 100MHz
上电复位后GPIO默认为浮空状态,部分特殊功能引脚为特定状态。
推挽输出:可以输出强高低电平,连接数字器件
开漏输出:只可以输出强低电平,高电平需要靠外部电阻拉高。输出端相当于三极管的集电极。适合于做电流型驱动
1.2 GPIO相关配置寄存器
每组GPIO端口的寄存器包括10个寄存器:
- 4个32位配置寄存器
- GPIOx_MODER:端口模式寄存器
- GPIOx_OTYPER:输出类型寄存器
- GPIOx_OSPEEDR:输出速度寄存器
- GPIOx_PUPDR:输出上下拉寄存器
- 2个32位数据寄存器
- GPIOx_IDR:输入数据寄存器
- GPIOx_ODR:输出数据寄存器
- 1个端口置位/复位寄存器
- GPIOx_BSRR
- 1个端口配置锁存寄存器
- GPIOx_LCKR
- 2个端口复用功能寄存器
- GPIOx_AFRL
- GPIOx_AFRH
通过这10个寄存器,可以控制一组GPIO的16个IO口
1.2.1 端口模式寄存器:GPIOx_MODER
位2y:2y+1 MODERy[1:0]:端口x配置位(y=0,1,…,15)
- 00:输入(复位状态)
- 01:通用输出
- 10:复用功能模式
- 11:模拟模式
1.2.2 输出类型寄存器:GPIOx_OTYPER
位32:16保留,必须为复位值
位15:0 OTy[1:0]:端口x配置位(y=0,1,…,15)
- 0:输出推挽(复位状态)
- 1:输出开漏
1.2.3 输出速度寄存器:GPIOx_OSPEEDR
位2y:2y+1 OSPEEDRy[1:0]:端口x配置位(y=0,1,…,15)
- 00:2MHz(低速)
- 01:25MHz(中速)
- 10:50MHz(快速)
- 11:100MHz(高速)
1.2.4 上拉/下拉寄存器:GPIOx_PUPDR
位2y:2y+1 PUPDRy[1:0]:端口x配置位(y=0,1,…,15)
- 00:无上下拉
- 01:上拉
- 10:下拉
- 11:保留
1.2.5 输入数据寄存器:GPIOx_IDR
位32:16保留,必须保持复位值
位15:0 IDRy[15:0]:端口输入数据(y=0,1,…,15)
这些位为只读形式,只能在字模式下访问,它们包含相应IO口的输入值
1.2.6 端口置位/复位寄存器:GPIOx_BSRR(包含BSSRH和BSSRL)
注意:同时对BSy和BRy进行操作,则置位操作BSy优先级更高。
位32:16 BRy:端口x复位位y(y=0,1,…,15)(BSSRH)
- 0:不会对ODRx位进行任何操作
- 1:对相应的ODRx位进行复位操作
位15:0 BSy:端口x置位位y(y=0,1,…,15)(BSSRL)
- 0:不会对ODRx位进行任何操作
- 1:对相应的ODRx位进行置位操作
2. GPIO输出的相关库函数
重要函数
- GPIO初始化
作用:初始化一个或多个IO口(同一组的GPIO)的工作模式,输出类型,速度以及上下拉方式。void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
typedef struct { uint32_t GPIO_Pin//指定要初始化的端口 GPIOMode_TypeDef GPIO_Mode;//端口模式 GPIOSpeed_TypeDef GPIO_Speed;//速度 GPIOOType_TypeDef GPIO_OType; //输出类型 GPIOPuPd_TypeDef GPIO_PuPd;//上拉或者下拉 }GPIO_InitTypeDef; /*端口模式*/ typedef enum { GPIO_Mode_IN = 0x00, // 输入 GPIO_Mode_OUT = 0x01, // 普通输出模式 GPIO_Mode_AF = 0x02, // 复用功能 GPIO_Mode_AN = 0x03 // 模拟功能 }GPIOMode_TypeDef; /*速度*/ typedef enum { GPIO_Low_Speed = 0x00, /*!< Low speed */ GPIO_Medium_Speed = 0x01, /*!< Medium speed */ GPIO_Fast_Speed = 0x02, /*!< Fast speed */ GPIO_High_Speed = 0x03 /*!< High speed */ }GPIOSpeed_TypeDef; /*输出类型*/ typedef enum { GPIO_OType_PP = 0x00,// 推挽输出 GPIO_OType_OD = 0x01 // 开漏输出 }GPIOOType_TypeDef; /*上下拉*/ typedef enum { GPIO_PuPd_NOPULL = 0x00, // 浮空 GPIO_PuPd_UP = 0x01, // 上拉 GPIO_PuPd_DOWN = 0x02 // 下拉 }GPIOPuPd_TypeDef;
- 设置输出电平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //置位 实际操作BSRRL寄存器 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//复位 实际操作BSRRH寄存器 void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);//设置值 void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);// 写入端口的值
3 实验操作
3.1 使用库函数进行操作
// 挂载时钟
// GPIOD
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
// 配置端口PD13,14,15;
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;// 普通输出模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100Mhz
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_DOWN;// 上拉
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;// 引脚
GPIO_Init(GPIOD,&GPIO_InitStructure);
delay_init(128);
while(1)
{
GPIO_SetBits(GPIOD,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
delay_ms(200);
GPIO_ResetBits(GPIOD,GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
delay_ms(200);
}
3.2 使用寄存器操作
// 挂载时钟
RCC->AHB1ENR|=(1<<3); //GPIOD
// 配置端口13
// 01:普通输出模式
GPIOD->MODER&=~(3<<(13*2));
GPIOD->MODER|=(1<<(13*2));
// 0:推挽输出
GPIOD->OTYPER|=(0<<13);
// 11:高速
GPIOD->OSPEEDR|=(3<<(13*2));
// 01:上拉
GPIOD->PUPDR|=(1<<(13*2));
delay_init(128);
while(1)
{
GPIOD->BSRRL|=(1<<13);// 置位PD13
delay_ms(200);
GPIOD->BSRRH|=(1<<13);// 复位PD13
delay_ms(200);
}