GPIO是什么?
GPIO=General Purpose Input Output,通用输入输出。有时候简称为“IO口”。通用,就是说它是万金油,干什么都行。输入输出,就是说既能当输入口使用,又能当输出口使用。端口,就是元器件上的一个引脚。怎么用?写软件控制。
总结:GPIO就是芯片上的一根干啥都行的引脚。
【STM32入门教程-2023】第3集 绚丽小灯 点灯宗师 | keysking的stm32教程_哔哩哔哩_bilibili
GPIO的简单用法
输出高低电平控制信号-点亮led小灯-推挽输出
如上图,查看单片机原理图,找到led外设,观察led电路图,看到芯片的PA7 GPIO引脚连向了它,因此只要控制这个引脚持续输出高电平即可。
GPIO口是怎么被控制的呢?通过软件代码。需要亮灯的时候调用GPIO口拉高的函数,需要熄灯的时候调用GPIO拉低的函数,即可实现控制。函数的操作,最终变成了向这个GPIO的硬件寄存器配置数据(当然你也可以直接去操作寄存器,C51),硬件的状态会跟随寄存器的数据改变而改变。
进一步,可以使用延时函数在死循环中实现led的闪烁
再进一步,写代码实现三色灯的炫彩效果
按键输入实现对led的状态控制-利用浮空输入模式-上/下拉电路
先看按键电路图,包括K1和K2上下两个电路,K1按键是外置了上拉电路;K2按键内置有上拉电路
K1按键实现按住led亮,松开灭
芯片检测PB12输入,因此检测按键状态。(因此,可以想象,按键的按下和松开会对应PB12引脚的电平状态变化)。我们可以设置PB12引脚的为浮空输入模式。
浮空输入:类似于芯片内部接了个巨大电阻,高阻抗。
观察上图,按键松开时,高阻态分压,PB12仍为 3.3V【这种利用外接电源拉高GPIO口电压的操作,成为上拉。由于上拉操作通常需要一个电阻来配合,因此我们称这个电阻为上拉电阻】,接通时,接地。
上/下拉电路
同理,下拉电路
上拉与下拉电路最基本的作用是:将某个电路的电平状态确定为高电平或低电平。
简单来说,电源到器件引脚上的电阻叫上拉电阻,作用是平时使用该引脚为高电平;地到器件引脚的电阻叫下拉电阻,作用是平时使该引脚为低电平。
小知识:电容防止按键抖动?
因为按键都是机械式的,两个金属片在接触的瞬间,从微秒级的时间段来看,会存在接触-断开-再接触这样的轻微的抖动。直到两个金属片牢牢的接触到一起之后,抖动才会消失。硬件消除抖动可以加并联电容。
所谓软件按键去抖动,就是通过延时来消除掉接触再断开这种异常状态的。
死循环中读取按键状态,根据返回值点或者灭led
K2按键实现按住led亮,松开灭
利用芯片内部上下拉电路
观察上面K2电路图,我们知道其芯片内部有个上下拉电路。因此,我们设置一下芯片内部是上拉还是下拉,然后死循环检测按键状态点亮led即可。
一开始死循环里这么写:
出现问题,在按键按下,达到翻转条件,机械还没松开的这段时间里,死循环可能已经翻转了很多次,这样最终按键松开时,小灯的量灭是随机的。
解决办法:第一次进入死循环,检测到K2按键按下时,我们翻转小灯,最后用一个空循环,判断机械按键确实已经松开了,再继续进行外面的大循环。
GPIO的输入输出模式
GPIO不止有持续输出高电平那么简单的模式,也不止只有输出,一共有8种输入/出模式,支持花里胡哨的外设功能。
STM32入门-GPIO端口的八种工作模式_c语言_rivencode-华为云开发者联盟
GPIO8种工作模式_gpio的8种工作模式_牛虻-的博客-CSDN博客
GPIO输入输出模式原理(八种工作方式附电路图详解)_gpio输出模式_行稳方能走远的博客-CSDN博客
GPIO结构
最右侧为引脚
电流从右侧引脚先进入-保护二极管
1)当波动电压大于VDD(3.3V),上方二极管导通;反之小于0V,下方二极管导通
2)仅能抵御瞬间电压,长时间亦会损坏。
3)5V容忍(可以承受瞬间电压5v作为高电平输入) GPIO引脚 FT类型
输出结构(推挽/开漏)
复用推挽输出、复用开漏输出
关于输出控制模块获得的指令来源
例如串口模块、IIC模块等GPIO复用引脚。
也因此,STM32也将GPIO的输出模式细分为了 推挽输出、开漏输出、复用推挽输出、复用开漏输出。
单片机为什么会有引脚复用?
正常的系统,当芯片设计时如果有足够的空间,引脚资源不会重合的,都是分离的,各自有各自的唯一作用,比如某某引脚,是对应的USB的那些pin。
为了在不复杂硬件引脚的前提下,丰富单片机功能,允许通过软件配置,在一组引脚上充分利用多种不同的功能,从而降低硬件成本和引脚数量,提升硬件可靠性。
推挽输出
代码设置GPIO为推挽输出,此模式下P-MOS与N-MOS协同工作,
函数最终修改相关寄存器,导致P-MOS激活,小灯亮起;反之,写函数控制小灯关闭,N-MOS寄存器被修改,小灯熄灭。
开漏输出与推挽输出区别
开漏输出:芯片内部只能输出 0V低电平和高阻态
推挽输出:芯片内部可以输出高电平,但是电压固定,比如3.3V。
开漏输出
如果想驱动一个5V的小灯,只能使用开漏输出,外部电压利用上拉电阻供电。
利用N-MOS的关断和输出低电平控制小灯亮灭
输入结构 (浮空/上拉/下拉/模拟)
上拉输入、下拉 输入
浮空输入
上下拉电阻均不启用。
肖特基触发器(外部不标准电压-整合为高低电平)
读取引脚输入电平的原理
模拟输入
其他那种输入统称为数字输入;模拟输入不经过肖特基触发器处理,将电压引入了需要模拟输入的片上外设。
输出控制器只能有一个控制源,输入部分可以同时读取肖特基触发器的输出
从GPIO到寄存器--软硬件之间的桥梁
GPIO相关的寄存器
首先需要知道的是,STM32中对于GPIO口的操作,无非就是操作下面的寄存器而已,所谓的标准库也好,HAL库也好,它们都只是对操作寄存器的过程进行了封装,目的是为了减轻你编程时的工作负担。因此对于寄存器的描述,你只要稍微了解一下,大概知道每个寄存器是干啥的,有哪些位,是如何配置的就行,除了一些你觉得需要留意的地方,其它的完全没有必要完全记住,用的时候知道再哪里查就行了。
两个32位的配置寄存器:GPIOx_CRL、GPIOx_CRH
两个32位数据寄存器:GPIOx_IDR、GPIOx_ODR
一个32位的置位/复位寄存器:GPIOx_BSRR
一个16位复位寄存器:GPIOx_BRR
一个32位锁定寄存器:GPIOx_LCKR
注:具体的寄存器描述可以参考《STM32F10x-中文参考手册》的GPIO章节的P113页。强烈建议先花几分钟先看一下这一部分的内容。
GPIO输出的操作流程示例
Step1:使能GPIO的时钟
STM32中的每一个外设都对应了一个时钟,当我们想要使用某一个外设的时候,必须先要开启它的时钟才行。时钟是STM32单片机的脉搏,是单片机的驱动源,使用任何一个外设都必须打开相应的时钟。这样的好处是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果。每个时钟,系统都会处理一步数据,这样才能让工作不出现紊乱。
注:STM32中有一个专门管理时钟和复位的外设RCC。有关RCC时钟控制寄存器部分的具体描述可以参考《STM32F10x-中文参考手册》的P55页,可以花个十分钟左右的时间,大概了解一下STM32有哪些时钟,又有哪些寄存器可以配置。
所有的 GPIO 都挂载到 APB2 总线上,具体的时钟由 APB2 外设时钟使能寄存器(RCC_APB2ENR)来控制(《STM32F10x-中文参考手册》P70页)。
在编程时,可以使用标准库里提供的函数RCC_APB2PeriphClockCmd()
,快速的使能相应的GPIO时钟。
/*以GPIOC为例,使能它的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
Step2:初始化GPIO引脚至相应的模式
当我们使用GPIO口之前,我们还需要对它进行一些初始化的操作,比如要设置它的速度、模式和引脚号。
注:关于速度和模式的配置可以查看《STM32F10x-中文参考手册》P113页和P114页部分的内容。
然后关于GPIO的几种输出模式的区别有所不了解的,可以自行百度或者谷歌:推挽输出和开漏输出。
简单来说,推挽输出既可以输出高电平,也可以输出低电平;开漏输出只能输出低电平,若要输出高电平,需要外接上拉电阻才行。
像我们平时利用单片机点个灯什么的,直接将GPIO配置为推挽输出模式就可以了。