文章目录
文章基于适用于STM32F4系列,作者使用STM32F401CCU6开发板。
本文章基于此系列和开发板展开讨论。
GPIO初始化
GPIO模式
GPIO(General-purpose input/output)是通用型输入输出。
也就是说是一种有多种功能的输入输出接口。
GPIO输入模式
类型 | 特点 |
---|---|
上下拉输入 | 内部自带上/下拉电阻,外部为高阻时为高/低电平 |
浮空输入 | 浮空状态,高阻时状态不定 |
模拟输入 | 使用ADC转换,将模拟信号转为数字信号输入 |
GPIO输出模式
类型 | 特点 | 原理 |
---|---|---|
推挽输出 | 可以输出较大电流(20mA左右) | 利用Pmos和Nmos接GND和VCC实现 |
开漏输出 | 可以设置为高阻态 | 只有接GND(接VCC)和高阻两种状态,可以直接输出低(高)电平,另一电平靠上(下)拉电阻实现 |
复用模式 | 外设使用端口 | 不通过置位复位控制寄存器,直接通过数据寄存器 |
复用模式其实就是推挽/开漏输出,只不过是数据来源不同而已。
这是F4系列的GPIO框图。来源于下连接
具体详解可以看这个博客
初始化思路
流程
- 打开时钟
- 配置GPIO初始化结构体
- 调用初始化函数
解析
打开时钟
因为stm32片上资源很多,而且开发时并不是所有的资源都会使用。为了节省功耗,默认状态下时钟为关闭状态,因此我们需要在使用时打开这个资源的时钟。
配置GPIO初始化结构体
这是个描述初始化GPIO需要设置的参数的结构体。
调用初始化函数
标准库帮我们把之前配置的数据写入到规定的寄存器中来完成初始化。
初始化配置代码详解
打开时钟
F4系列的GPIO时钟挂载在AHB1下,使用这个函数打开时钟。
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
传入的值有2个,
第一个是哪个时钟
关于GPIO 的取值可以是
RCC_AHB1Periph_GPIOA 到 RCC_AHB1Periph_GPIOK
这是不同的GPIO分组的时钟,本质上是不同的地址。
第二个是打开或者关闭,这应该不需要解释
DISABLE
ENABLE
GPIO初始化结构体
使用这句定义结构体
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;
GPIO_Pin
GPIO_Pin这个是需要初始化的管脚,可以使用或命令同时处理多个管脚
取值可为
GPIO_Pin_0 到 GPIO_Pin_15
GPIO_Pin_All
GPIO_Mode
这个是配置输入/输出模式的
取值可以为
GPIO_Mode_IN //输入
GPIO_Mode_OUT //输出
GPIO_Mode_AF //复用模式
GPIO_Mode_AN //模拟输入
GPIO_Speed
用于设置GPIO的反转速度的
取值可以为
GPIO_Low_Speed
GPIO_Medium_Speed
GPIO_Fast_Speed
GPIO_High_Speed
从上到下依次加快
GPIO_OType
设置为开漏或者推挽输出
取值可以为
GPIO_OType_PP //推挽输出
GPIO_OType_OD //开漏输出
GPIO_PuPd
设置上下拉模式,F4系列的上下拉电阻在输入输出控制的外端,
所有输入输出均可设置上下拉。
取值可以为
GPIO_PuPd_NOPULL //无上下拉
GPIO_PuPd_UP //上拉
GPIO_PuPd_DOWN //下拉
初始化函数
使用这个函数来初始化GPIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
第一个参数是GPIO的分组
取值可以是
GPIOA 到 GPIOK
第二个是GPIO初始化结构体的地址,可以使用取址符(&)
例子
GPIO_InitTypeDef GPIO_InitStruct; //声明GPIO初始化结构体
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //打开GPIOA的时钟
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //设置为输出模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD; //设置为开漏输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //设置引脚为0,1
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //设置为上拉
GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed; //设置为快速模式
GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化
GPIO常用函数
读取相关
GPIO_ReadInputDataBit
原型
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
名称 | 描述 |
---|---|
输入1 | 要读取的GPIO组 |
输入2 | 要读取的GPIO引脚号 |
输出 | 这个引脚的高(低)电平分别输出为1(0) |
功能描述:读取指定一个管脚的电平高低
GPIO_ReadInputData
原型
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
名称 | 描述 |
---|---|
输入 | 要读取的GPIO组 |
输出 | 输出这个GPIO组的16个管脚的值,GPIO_Pin_15到GPIO_Pin_0分别为返回值的高位到低位 |
功能描述:读取指定一个GPIO组的电平高低,编写成uint16_t数
GPIO_ReadOutputDataBit
原型
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
名称 | 描述 |
---|---|
输入1 | 要读取的GPIO组 |
输入2 | 要读取的GPIO引脚号 |
输出 | 这个引脚的高(低)电平分别输出为1(0) |
功能描述:读取指定一个输出管脚的被CPU设成的电平高低
GPIO_ReadOutputData
原型
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
名称 | 描述 |
---|---|
输入 | 要读取的GPIO组 |
输出 | 输出这个GPIO组的16个管脚的值,GPIO_Pin_15到GPIO_Pin_0分别为返回值的高位到低位 |
功能描述:读取指定一个输出GPIO组被设置成的电平高低,编写成uint16_t数
写入相关
GPIO_SetBits
原型
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
名称 | 描述 |
---|---|
输入 1 | 要写入的GPIO组 |
输入 2 | 要写入的管脚号可用或运算符输入多个管脚 |
输出 | 无 |
功能描述:将一个输出GPIO组的一个或多个管脚设置为高电平(1)
注意:必须是设置为输出状态的管脚
GPIO_ResetBits
原型
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
名称 | 描述 |
---|---|
输入 1 | 要写入的GPIO组 |
输入 2 | 要写入的管脚号可用或运算符输入多个管脚 |
输出 | 无 |
功能描述:将一个输出GPIO组的一个或多个管脚设置为低电平(0)
注意:必须是设置为输出状态的管脚
GPIO_WriteBit
原型
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
名称 | 描述 |
---|---|
输入 1 | 要写入的GPIO组 |
输入 2 | 要写入的管脚号(只能输入一个管脚) |
输入 3 | 设置是置位或复位 |
输出 | 无 |
BitAction(输入3)的可能值为
Bit_RESET //复位
Bit_SET //置位
功能描述:将一个输出GPIO组的一个管脚设置为高(低)电平(1/0)
注意:必须是设置为输出状态的管脚
GPIO_Write
原型
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
名称 | 描述 |
---|---|
输入 1 | 要写入的GPIO组 |
输入 2 | 设置是置位或复位 |
输出 | 无 |
功能描述:将一个输出GPIO组设置为高(低)电平(1/0)
注意:必须是设置为输出状态的GPIO组