目录
什么是GPIO
General Purpose Input/Output,通用输入输出端口,简称GPIO
作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出
GPIO特点
1. 不同型号,IO口数量可能不一样,可通过选型手册快速查询
2. 快速翻转,每次翻转最快只需要两个时钟周期
3. 每个IO口都可以用作中断
4. 支持8种工作模式
GPIO电气特性
GPIO引脚分布
以V开头的是电源引脚
PX -OSC是晶振引脚
NRST是复位引脚
串口、JWD、JTAG都有不同的下载引脚
PX开头的都是GPIO引脚
IO端口基本结构介绍
上图比较关键的几个器件有 保护二极管、内部上下拉电阻、施密特触发器、P-MOS&N-MOS管
一个信号输入进来,经过保护二极管,之后有两条路可以走,一个是模拟输入,也就是ADC和DAC,另一个是经过TLL肖特基触发器,之后可作为复用功能输入,两条路最后都是到达片上外设。经过TTL肖特基触发器后还可将信号保存到数据寄存器(IDR寄存器),之后可通过CPU去读ODR寄存器,这样就可以知道引脚输入的信号是高还是低(作为通用输入)
一个信号输出出去的时候,如果将P-MOS管导通,这样引脚输出高电平,如果将N-MOS管导通,这样引脚输出低电平
可以这样理解,输出控制器作左边是控制机构,右边是执行机构
位设置清除寄存器(BSRR)
输出数据寄存器(ODR)
可以通过BSRR寄存器间接控制ODR寄存器来控制输出,也可以通过直接读写ODR寄存器来控制输出(通用输出)
二选一选择器下方的复用功能输出的控制源是来自片上外设的,像串口外设等等
IO口芯片手册上标有FT标志的就是TTL端口,没标FT的就是CMOS端口
CMOS端口接的是3.3V
如果输入电压比3.3V高,上面的保护二极管就会导通,输入电压产生的电流就会直接流入VDD而不会流入内部电路,这样就可以避免过高的电压对内部电路产生伤害。如果输入电压比0V还要低,这个电压是相对于VSS的电压,所以是可以有负电压的,那这时下面这个保护二极管就会导通,电流会从VSS直接流出去,而不会从内部电路汲取电流,也是可以保护内部电路的。如果输入电压在0~3.3V之间,两个保护二极管均不会导通,这时二极管对电路没有影响,这就是保护二极管的用途。
如果外面接5V,下面的保护二极管不导通,上面的导通会导致保护二极管烧掉,也会导致芯片内部的器件烧掉。因此如果要接5V,一般加一个保护电阻。由于二极管存在压降,需要达到压降电压二极管才会导通,因此只需让电阻提供0.3V的电压,这样二极管导通后交点处的电压就是3.3+0.3=3.6v,而STM32的工作电压是2V-3.6V。二极管的钳位作用是指利用二极管正向导通压降相对稳定,且数值较小的特点,来限制电路中某点的电位
比如外部输入一个-5V的电压,同样不能直接输入,需要接一个电阻,同样满足二极管的压降条件,下方的二极管导通,下方二极管的电压根据电流流向和压降就是-0.3V
根据GPIO电气特性,CMOS类型的GPIO识别低电平电压范围为-0.3V~1.164V之间
芯片内部上下拉电阻的阻值大概是20kΩ~50kΩ之间,当上拉电阻的输入电压为3.3V,IO口输出的电流大概只有0.0825mA,因为流过的电流非常小驱动力非常弱,因此被称为弱上下拉电阻
施密特触发器是一种整形电路,可以将非标准方波整形成方波。正向阀值电压转高电平,负向阀值电压转低电平。
P-MOS&N-MOS管简介
P-MOS要Vgs<0导通,s接了3.3V,那么g要<3.3v。在图上所示情形我们是将MOS管作为开关来使用,因此只需要考虑0v和3.3v的情况
P-MOS管导通的条件是Vgs<=Vth N-MOS管导通的条件是Vgs>=阈值电压Vth
栅极和源极之间的电压Vgs 阈值电压Vth,阈值电压同样是gs处的电压
P-MOS电流流向是从漏极到源极 N-MOS电流流向是从源极到漏极
P-MOS阈值电压一般-0.2V~-0.7V N-MOS阈值电压一般0.2v~0.7v 这里要注意电流流向不一定是从高压到低压,还要取决于电源、电阻等因素
简单的看要P-MOS导通或者N-MOS导通只需要S和G电压不相等(注意电压方向)
GPIO的八种模式分析
GPIO的八种模式可以分为4种输入模式和4种输出模式
输入浮空 输入用,完全浮空,状态不定
输入上拉 输入用,用内部上拉,默认是高电平
输入下拉 输入用,用内部下拉,默认是低电平
模拟功能 ADC、DAC这俩外设
开漏输出 软件IIC的SDL、时钟引脚SCL等
推挽输出 驱动能力强,25mA(max),通用输出
开漏复用 片上外设功能(硬件IIC的SDL,SCL引脚等)
推挽复用 片上外设功能(SPI的SCK、MISO、MOSI引脚等)
数据引脚SDL 时钟引脚SCK/SCL MISO主入从出 MOSI主出从入
输入浮空模式
输入信号经过保护二极管后直接往输入数据寄存器IDR的方向去,存到IDR后再通过CPU读取,就可以得到外部的信号
输入浮空模式的特点:空闲时IO状态不确定,由外部环境决定。也就是IO空闲时外部接3.3V这个引脚输入就是1,外部接0V这个引脚输入就是0
输入上拉模式
输入上拉和输入浮空的区别在于使用了上拉电阻(图中输入驱动寄存器的上拉电阻)
一个信号从IO引脚输入进来仍然是走到IDR,输入为1走进去还是1,输入为0走进去还是0
如果外面输入高阻态,这时IDR的数据就是由上拉电阻的电源VDD来决定了
特点:空闲时,也就是外部为高阻态时,IO呈现高电平
高阻态,指不是高电平也不是低电平
输入下拉模式
和输入下拉相反,输入驱动器的输入下拉电阻打开,特点就是IO输入为高阻态的时候IO呈现低电平
模拟功能模式
输入驱动器上下拉电阻关闭,肖特基触发器关闭,输出驱动器的N-MOS和P-MOS也都关闭
就只剩模拟输入那一条路了
特点:专门用于模拟信号输入或输出,如ADC和DAC
开漏输出
上下拉电阻关闭,施密特触发器打开,信号走向可以走到IDR寄存器,意味着配置成输出模式也是可以读取到引脚的高低电平的。
P-MOS管固定不导通。往ODR对应位,也就是控制IO输出的ODR位写0,N-MOS管导通,输出0,往ODR对应位写1,N-MOS管不导通,此时N-MOS和P-MOS都不导通,交点处就会变成高阻态,高阻态输出到外部没有任何意义,而写1的目的是希望往外部输出1,这时只需要在外部接一个上拉电阻,外部的1由上拉电阻的VDD供应,就可以输出高电平
为了使P-MOS不导通,会由输出控制来控制在P-MOS的栅极处接一个3.3V的VDD,保证源极和栅极电压相等MOS管不导通
输出控制器内部是有反相器的,输入的0会被反向成1,1被反向成0,MOS管GS处电压不等,导通
特点:不能输出高电平,必须有有外部上拉才能输出高电平F4/F7/H7可使用内部上下拉
开漏式复用功能
上下拉电阻关闭,施密特触发器打开,P-MOS始终关闭,N-MOS选择性打开
和开漏输出的区别在于,输出来源于片上外设复用功能输出
特点:
不能输出高电平,必须有有外部上拉才能输出高电平F4/F7/H7可使用内部上下拉
由其他外设控制输出
推挽输出
上下拉电阻关闭,施密特触发器打开
往ODR对应位写0,N-MOS管导通;写1,P-MOS管导通
特点:可以输出高电平也可以输出低电平
需要注意的是,输出控制器内部是有反向器的,写0反成1,写1反成0,Vgs存在电压差,导通
图中有勾有叉代表可以打开也可以关闭
推挽式复用功能
和推挽输出类似,上下拉电阻关闭,施密特触发器打开,P-MOS和N-MOS都可以导通
特点:可以输出高低电平。信号来源于片上外设。
F4/F7/H7系列和F1系列的GPIO差异点
1、F1在输出模式,禁止使用内部上下拉;F4/F7/H7在输出模式,可以使用内部上下拉
2、不同系列IO翻转速度不同
STM32芯片内部不能输出5V的电平,STM32芯片IO引脚通常3.3V,只能通过外部接一个上拉电阻才有可能输出5V
GPIO寄存器介绍
使用GPIO寄存器来配置GPIO时要根据GPIO的8种状态来配置
每类GPIOx都有10个寄存器与之对应,分别是:
端口 模式寄存器(GPIOx_MODER) 输入、输出、复用、模拟
端口 输出类型寄存器(GPIOx_OTYPER) 推挽、开漏
端口 输出速度寄存器(GPIOx_OSPEEDR) 低速(2MHz)、中速(25)、快速(50)、高速(100MHz)
端口 上拉/下拉寄存器(GPIOx_PUPDR) 浮空、上拉、下拉
端口 输入数据寄存器(GPIOx_IDR)
端口 输出数据寄存器(GPIOx_ODR)
端口 置位/复位寄存器(GPIOx_BSRR)
端口 配置锁定寄存器(GPIOx_LCKR)
端口 复用功能低位寄存器(GPIO_AFRL)
端口 复用功能高位寄存器(GPIO_AFRH)
一共8个通用功能寄存器+2个复用功能寄存器
GPIO端口 模式寄存器(GPIOx_MODER)
MODER寄存器有32位,两个位控制一个IO
注意F1和F4系列的不同,此处只介绍F4的,理解了F4看芯片手册很快能理解F1
GPIO端口 输出类型寄存器(GPIOx_OTYPER)
输出类型寄存器OTYPER有32位,低16位有效,高16位保留。0推挽,1开漏
GPIO端口 输出速度寄存器(OSPEEDR)
输出速度寄存器OSPEEDR一共32位。每2位决定一个端口的输出速度。
00,01,10,11分别决定低速、中速、快速、高速,对应2、25、50、100MHz
GPIO端口 上下拉寄存器(PUPDR)
上下拉寄存器有32位,2位控制一个IO口,配置方式有00浮空、01上拉、02下拉
GPIO端口 输入数据寄存器(GPIOx_IDR)
IDR有32位,高16位保留,低16位为只读,包含响应I/O端口的输入值
GPIO端口 输出数据寄存器(GPIOx_ODR)
IDR有32位,高16位保留,低16位有效,可读写,包含响应I/O端口的输出值
GPIO端口 置位/复位寄存器(BSRR)
端口置位/复位寄存器有32位,高16位位BS复位寄存器,低16位为BR置位寄存器
16位中每一位分别对应响应端口的ODR位的置位/复位操作,如果同时对一个端口进行置位、复位操作,则BS复位的优先级更高,即只执行复位不执行置位
ODR和BSRR寄存器控制输出有什么区别?
使用ODR,在读和修改访问之间产生中断时,可能会发生风险。BSRR则无风险。
因为ODR是可读写,而BSRR是只写。使用ODR操控输出需要先读出ODR的值再进行按位或,如果此时有中断发生可能导致脏数据(ODR修改需经历:读-改-写的过程,BSRR直接写)
总的来说,建议使用BSRR控制输出。HAL库中也是使用的BSRR控制输出。
在F4等系列中,BSRR分为BSRRL(控制复位)和BSRRH(控制置位)
通用外设驱动模型(四步法)
通用外设驱动流程包括:
外设初始化 如时钟设置、寄存器参数设置、IO设置、中断设置(开中断、NVIC设置)
读函数(可选) 从外设读数据
写函数(可选) 往外设写数据
中断服务函数(可选) 根据中断标志,处理各种中断事务
时钟配置一般步骤
-
使能PWR时钟:调用函数 _HAL_RCC_PWR_CLK_ENABLE()。 PWR power controller
-
设置调压器输出电压级别:调用函数 _HAL_PWR_VOLTAGESCALING_CONFIG()。
-
选择是否开启Over-Driver功能:调用函数HAL_PWREx_EnableOverDrive()。
-
配置时钟源相关参数:调用函数HAL_RCC_OscConfig()。
-
配置系统时钟源以及AHB,APB1和APB2的分频系数:调用函数HAL_RCC_ClockConfig()。
GPIO配置步骤
1. 使能GPIO时钟 __HAL_RCC_GPIOx_CLK_ENABLE() 宏
2. 设置工作模式 HAL_GPIO_Init()
3. 设置输出状态(可选) 写函数 HAL_GPIO_WritePin() 、翻转函数 HAL_GPIO_TogglePin()
4. 读取输入状态(可选) HAL_GPIO_ReadPin()
STM32F4的GPIO物理引脚通过AHB1总线连接到内核和其他外设,而GPIO的控制寄存器是挂载在APB2总线上的
RCC即复位和时钟控制 模块,“Reset and Clock Control”,
RCC模块负责管理系统时钟和各种外设的时钟。通过RCC模块,可以配置和控制微控制器的时钟源、时钟分频器以及各个外设的时钟频率,RCC模块在初始化阶段起着至关重要的作用,以确保系统时钟和外设时钟的正确配置和稳定运行。
GPIO配置相关函数简介
根据GPIO时钟使能函数也可联想到F1的GPIO是挂在在APB2总线,F4的GPIO挂载在AHB1总线
GPIO时钟使能函数是一个宏,do-while函数结构代码块,代码块中对RCC_AHB1ENR(AHB1外设时钟使能寄存器)进行操作
HAL_GPIO_Init()函数简介
在stm32fxxx.h中通过类型强转将外设的基地址强转成了对应外设的xx_TypeDef*
统一称这些宏定义为xxx外设的基地址(xxx_TypeDef是外设的基地址),xxx_InitTypeDef是外设的初始化属性结构体
作为输出的时候设置上下拉是无效的
GPIO_Mode是GPIO模式选择 ,从上到下依次是
输入、推挽输出、开漏输出、复用推挽、复用开漏、模拟模式、
复用输入(其实和输入一样,不用管)、
外部中断上升沿触发检测、外部中断下降沿触发检测、外部中断双边触发检测、
外部事件上升沿触发检测、外部事件下降沿触发检测、外部事件双边触发检测
HAL_GPIO_WritePin()函数简介
HAL_GPIO_ROGGLE函数简介
GPIO点灯实战
首先分析原理图,三个发光二极管都是共阳,因此IO端口需要输出低电平才能亮灯,IO的输出模式有开漏、推挽、复用开漏、复用推挽这4种,复用主要针对外设器件,因此不考虑复用,开漏需要外接上拉电阻才能输出高电平,而推挽可以输出高/低电平,因此推挽输出模式合适。
GPIO通过按键控制灯的亮灭
按键的GPIO是输入模式,输入模式包括上拉、下拉、浮空、模拟
按键供阳要接低电平,下拉满足要求,共阴要接高电平,上拉满足要求