第一章 GPIO(General Purpose Input Output 通用功能输入输出)
1.1、GPIO内部结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuaTcPWW-1672056960969)(assets/1672053591299.png)]
1.2、GPIO可配置功能
1.2.1输入功能
cpu可以获取该gpio的外部电路输入的一个电平状态
输入模式:
-
浮空输入(Input Floating):
不接上拉电阻也不接下拉电阻。
上拉电阻: 经过一个小阻值的电阻,接入到VDD
下拉电阻: 经过一个小阻值的电阻,接入到VSS(GND) 在这种情况下,IO引脚的状态完全由外部输入所决定。
-
上拉输入(Input pull-up):
通过上拉电阻,接入VDD
输入引脚内部接一个上拉电阻,
此时,IO引脚没有外部输入信号时,CPU也能获得一个 高电平(1),
唯有在外部电路输入低电平信号时,CPU读取到的才是低电平(0)。 -
下拉输入(Input pull-down):
通过下拉电阻,接入 VSS
输入引脚内部接一个下拉电阻,
此时,IO引脚没有外部输入信号时,CPU也能获得一个 低电平(0)。
唯有在外部电路输入高电平信号是,CPU读取到的才是高电平(1)。 -
模拟输入(Input analog):
该引脚被设置为模拟输入时,能够获取到模拟信号
1.2.2 输出功能
CPU可以往该GPIO口输出一个电平状态(相当于可以控制外部电路工作状态)
输出模式:
-
推挽输出(PP:push-pull):
CPU可以向外部电路输出高电平也可以输出低电平
-
开漏输出(OD:open-drain):
不输出电压.
CPU写0时,引脚接VSS(GND)
CPU写1时,悬空 (如果用户接了上拉电阻,则在CPU写1时,IO口会接到用户的上拉电阻上)
1.2.3 复用功能
复用功能是指GPIO口用作其它的外设功能口线
比如:
I2C USART SPI等等
1.3 GPIO使用步骤
- 使能GPIO分组时钟(GPIO分组都是处于AHB1总线上)
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)
用来配置AHB1总线上的外设时钟
@RCC_AHB1Periph 指定要使能AHB1总线上的哪个外设
@arg RCC_AHB1Periph_GPIOA: GPIOA clock
@arg RCC_AHB1Periph_GPIOB: GPIOB clock
@arg RCC_AHB1Periph_GPIOC: GPIOC clock
@arg RCC_AHB1Periph_GPIOD: GPIOD clock
@arg RCC_AHB1Periph_GPIOE: GPIOE clock
@arg RCC_AHB1Periph_GPIOF: GPIOF clock
@arg RCC_AHB1Periph_GPIOG: GPIOG clock
@arg RCC_AHB1Periph_GPIOG: GPIOG clock
@arg RCC_AHB1Periph_GPIOI: GPIOI clock
.....
@NewState 指定该设备的时钟的状态
ENABLE 使能,为该外设提供时钟
DISABLE 禁止
例子:使能GPIOE/GPIOF组的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE,ENABLE);
-
初始化GPIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) @GPIOx 指定要初始化的GPIO属于哪个组 GPIOA/GPIOB....GPIOI @GPIO_InitTypeDef 指向GPIO初始化信息结构体 typedef struct { uint32_t GPIO_Pin; //指定要初始化的GPIO引脚(可以位或上多个) #define GPIO_Pin_0 ((uint16_t)0x0001) /* Pin 0 selected */ #define GPIO_Pin_1 ((uint16_t)0x0002) /* Pin 1 selected */ #define GPIO_Pin_2 ((uint16_t)0x0004) /* Pin 2 selected */ #define GPIO_Pin_3 ((uint16_t)0x0008) /* Pin 3 selected */ #define GPIO_Pin_4 ((uint16_t)0x0010) /* Pin 4 selected */ #define GPIO_Pin_5 ((uint16_t)0x0020) /* Pin 5 selected */ #define GPIO_Pin_6 ((uint16_t)0x0040) /* Pin 6 selected */ #define GPIO_Pin_7 ((uint16_t)0x0080) /* Pin 7 selected */ #define GPIO_Pin_8 ((uint16_t)0x0100) /* Pin 8 selected */ #define GPIO_Pin_9 ((uint16_t)0x0200) /* Pin 9 selected */ #define GPIO_Pin_10 ((uint16_t)0x0400) /* Pin 10 selected */ #define GPIO_Pin_11 ((uint16_t)0x0800) /* Pin 11 selected */ #define GPIO_Pin_12 ((uint16_t)0x1000) /* Pin 12 selected */ #define GPIO_Pin_13 ((uint16_t)0x2000) /* Pin 13 selected */ #define GPIO_Pin_14 ((uint16_t)0x4000) /* Pin 14 selected */ #define GPIO_Pin_15 ((uint16_t)0x8000) /* Pin 15 selected */ #define GPIO_Pin_All ((uint16_t)0xFFFF) /* All pins selected */ GPIOMode_TypeDef GPIO_Mode; //指定要配置的GPIO口的模式 GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ 输入模式 GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ 输出模式 GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */ 复用模式 GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */ 模拟输入模式 GPIOSpeed_TypeDef GPIO_Speed; //指定要配置的GPIO口的速率 #define GPIO_Speed_2MHz GPIO_Low_Speed #define GPIO_Speed_25MHz GPIO_Medium_Speed #define GPIO_Speed_50MHz GPIO_Fast_Speed #define GPIO_Speed_100MHz GPIO_High_Speed GPIOOType_TypeDef GPIO_OType; //指定要配置的GPIO口的输出类型 GPIO_OType_PP = 0x00, 输出推挽 GPIO_OType_OD = 0x01 输出开漏 GPIOPuPd_TypeDef GPIO_PuPd; //指定要配置的GPIO口的上下拉选择 GPIO_PuPd_NOPULL = 0x00, 悬空 GPIO_PuPd_UP = 0x01, 上拉 GPIO_PuPd_DOWN = 0x02 下拉 }GPIO_InitTypeDef; 例子:将PF9/PF10配置成输出推挽 GPIO_InitTypeDef g; g.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; g.GPIO_Mode = GPIO_Mode_OUT; g.GPIO_Speed = GPIO_Speed_50MHz; g.GPIO_OType = GPIO_OType_PP; g.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOF,&g);
-
输入/输出
-
输入:从配置好的GPIO引脚中获取外部电路状态
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) 获取指定的GPIO分组输入数据寄存器中的值并通过返回值返回 @GPIOx 指定GPIO分组 GPIOA/GPIOB...GPIOI @return 返回获取达到的GPIO分组的输入数据寄存器中的数据 返回值类型:uint16_t --> unsigned short 这个16bit的值分别对应该GPIO分组的16个GPIO引脚的输入电平状态 bit0 ---> 0号的引脚的电平状态 bit1 ---> 1号的引脚的电平状态 .. bit15 ---> 15号的引脚的电平状态 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 获取指定的GPIO引脚的电平状态 @GPIOx 指定GPIO分组 GPIOA/GPIOB...GPIOI @GPIO_Pin 指定要获取电平状态的引脚的编号 GPIO_Pin_0...GPIO_Pin_15 @return 返回指定的GPIO引脚的电平状态 0 表示该GPIO口输入低电平 1 表示该GPIO口输入高电平 uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
-
输出:CPU通过GPIO向外部输出一个电平
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) 用来向指定的GPIO分组输出电平 void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) 用来向指定的某一个GPIO输出电平 @GPIOx 指定GPIO分组 GPIOA/GPIOB...GPIOI @GPIO_Pin 指定要输出电平的引脚的编号 GPIO_Pin_0...GPIO_Pin_15 @BitVal 指定要输出的电平值 Bit_RESET 输出低电平 Bit_SET 输出高电平 GPIO_WriteBit(GPIOF,GPIO_Pin_9,(BitAction)0);//PF9-->0 void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 将指定的GPIO引脚的输出状态翻转(1-->0or0-->1) @GPIOx 指定GPIO分组 GPIOA/GPIOB...GPIOI @GPIO_Pin 指定要输出电平的引脚的编号 GPIO_Pin_0...GPIO_Pin_15 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 用来将指定的GPIO口引脚输出高电平 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 用来将指定的GPIO口引脚输出低电平
-