文章目录
前言
一个学习STM32的小白有问题评论区或私信指出~
1.GPIO基础知识
GPIO(General-Purpose input/output,通用输入/输出接口)
用于感知外部信号(输入模式)和控制外部设备(输出模式)
- 简单模块:LED,按键,蜂鸣器,温度传感器,使用一个GPIO就可以完成数据的传输/控制
- 复杂一点的模块OLED,FLASH,六轴传感器需要多个引脚组成“协议”传输数据,USART,IIC,SPI等协议
- MCU单片机大都采用引脚复用模式也就是一个GPIO,可以直接控制它输出高低电平,也可以设置为某个协议的引脚之一。此外,一些MCU的引脚,还能设置为ADC模式读取模拟信号,或者设置为DAC模式输出模拟信号
系统架构
2. IO八种工作模式
GPIO结构图
1、STM32 IO工作模式
输出模式有四种:推挽输出,开漏输出,复用开漏,复用推挽
输入模式有四种:上拉输入,下拉输入,浮空输入,模拟输入
输出模式:
1.推挽输出(Push-Pull,pp)
让输出控制变成了VDD/VSS输出,使得输出电流增大
提高了输出引脚的驱动能力,提高了电路的负载能力和开关的动作速度
输出高电平时P-MOS导通电流从上方过去
输出高电平时-MOS导通电流从下方过去
2.开漏输出(Open-Drain,OD)
推挽输出模式可以直接输出高电平,开漏输出需要外接上拉电阻才能输出高电平
开漏输出的特性
- 利用外部电路驱动能力
- 实现电平转换
- 方便实现“逻辑与” 功能
3.复用推挽/开漏输出(Alternate Funtion,AF)
GPIO除了作为通用输入输出引脚使用以外,还可以作为片上外设(USART,IIC,SPI)专用引脚,即一个引脚可以有多种用途,但是同一时刻一个引脚只能使用复用功能中的一个
当引脚设置为复用功能的时候,可选择推挽复用模式或者复用开漏模式,在设置为复用开漏模式时,需要外接上拉电阻。
输入模式:
1.上拉输入(Input Pull-up)
VDD经过开关、上拉电阻,连接外部I/O引脚。当开关闭合时,外部I/O输入信号时,默认输入高电平。
2.下拉输入(Input Pull-down)
VSS经过开关,下拉电阻,连接外部I/O引脚,当开关闭合时,外部I/O无输入信号时,默认输入低电平
3.浮空输入(Floating Input)
两个上下拉电阻开关均断开,没有上拉也没有下拉,I/O引脚直接连接TTL肖特基触发器
此时,I/O引脚浮空,读取的电平是不确定的,外部信号是什么电平,MCU引脚就输入什么电平
MCU复位上电后,默认为浮空输入模式
4.模拟输入(Analoge mode)
两个上下拉电阻开关均断开,同事TTL肖特基触发器也断开,引脚信号直接连接模拟输入,实现对外部信号的采集。
2、GPIO的输出速度
STM32的I/O引脚工作再输出模式下时,需要配置I/O引脚的输出速度
该输出速度不是输出信号的速度,而是I/O口驱动电路的响应速度。
STM32提供了三个速度,2MHZ,10MHZ,50MHZ
实际开发过程中需要结合实际情况选择合适的响应速度,以兼顾信号的稳定性和低功耗
- 当设备为高速时,功耗大,噪声大,电磁干扰强
- 当设备为低速时,功耗低,噪声小,电磁干扰弱
简单外设,比如LED灯,蜂鸣器建议使用2MHZ的输出速度
而复用为IIC,SPI等通信信号时,建议使用10MHZ或50MHZ以提高响应速度。
3 固件库实现LED点灯
1.LED灯
LED灯,是一种能够将电能转化为可见光的半导体期间
原理:当给P极施加正向电压时,空穴和自由电子在P-N结复合,辐射出光子而发光。
2.控制LED灯
LED灯的正极接到了3.3V,LED灯的负极接到了PA1,也就是GPIOA1引脚
只需要控制PA1为相对应的低电平,即可点亮对饮的LED灯,输出高电平则熄灭对应的LED灯。
GPIO结构体:
typedef struct
{
uint16_t GPIO_Pin; //GPIO引脚
GPIOSpeed_TypeDef GPIO_Speed; //GPIO输出速度
GPIOMode_TypeDef GPIO_Mode; //GPIO输入/输出模式
}GPIO_InitTypeDef;
GPIO相关库函数:
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_AFIODeInit(void);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_EventOutputCmd(FunctionalState NewState);
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
软件设计流程
- 初始化系统
- 初始化GPIO外设时钟
- 初始化LED引脚
- 输出电平