原文链接:STM32的GPIO的简单原理 | Colin Gretzky的博客
## 原理图
本文使用的芯片是STM32F103C8T6芯片,可供各位参考
本文仅做知识笔记整理,如有错误或不严谨请指出
这里借用一下keysking老师的原理图
### 程序控制电路的方式
实际上我们平时用代码控制的引脚,走的是这样一个流程:
程序——>寄存器——>电路
寄存器相当于一个小秘书,专门在程序与电路之间传话
程序修改寄存器中的数据和状态,而电路通过读取寄存器的数据来知道目前的芯片、其他电路的情况,这就是**程序控制电路的方式**
### GPIO口的保护二极管
GPIO口引脚旁有两个保护二极管,主要是用来承受瞬间的高电压,如果长时间处在不合理的电压还是会对电路和芯片造成影响
当然也有一些引脚是可以承受5V的高电压的,具体可以查看官方芯片指导手册对于引脚的定义
当电压大于3.3V时上端的二极管导通,电流流向VDD电源内部由电源消化
当电压小于0V时下端的二极管导通,电流流向VSS消化
## 输入输出模式
在STM32的开发中GPIO口总共有八种常用的输入输出模式,都可以通过程序端控制:
1. 推挽输出
2. 开漏输出
3. 复用推挽输出
4. 复用开漏输出
5. 浮空输入
6. 上拉输入
7. 下拉输入
8. 模拟输入
### 输出端
先看输出端的两个MOS管,分别是上端P-MOS管连接着高电平3.3V,然后是下端的N-MOS管连接的地,它们就相当于两个开关,分别对外输出高电平与低电平
**推挽输出**
当P管导通N管断开,3.3V与电路相连,输出的就是高电平,当N管导通P管断开,0V与电路相连,输出的就是低电平
这就是推挽输出的工作原理,可以通过芯片输出一些稳定的电压和电流用来驱动一些合适的对于功率要求没那么高的小元器件,而缺点也很明显就是只能输出3.3V电压
**开漏输出**
此时就只有N管工作,P管相当于就处在断路的情况
如果通过程序控制输出高电平,则N管断开,整个电路处于一个断开的高阻态情况,无法输出电流
如果通过程序控制输出低电平,则N管接通,地接入线路,元器件的两端没有产生电压差,电流仍然为0,若负载的另一端接外部5V高电压,此时就形成了电压差,能够驱动需要功率较大的元器件
开漏输出的优点相比之下,很明显就是可以更灵活的输出电压,但缺点就是需要一个外部的电源。也就是实际上开漏输出只提供了一个地电位
但这里最好选用能容忍5V电压的I/O口,不然长时间的高电压使上端保护二极管长时间接通还是会对电路及芯片产生一定的影响
在原理图的左边可以看到实际上除了片上寄存器以外,片上的外设也能控制I/O口的高低电平,当双方同时控制时,输出驱动器就不知道该听谁的
面对这个问题自然就产生了**复用推挽输出**与**复用开漏输出**
### 输入端
在输入驱动器这一块控制上下拉的就只有一个上拉电阻和下拉电阻
当上拉输入的时候上拉电阻启用,下拉输入的时候下拉电阻启用
而浮空输入的时候上拉下拉电阻都不启用,只由外部的电路决定,类似输出端的开漏输出模式,可以有更好的灵活性实现更多可能
再往前就是TTL肖特基触发器或叫施密特触发器,其作用就是稳定输入的电平,因为输入的电平很多时候会没有理想的那么稳定,产生的抖动会影响判断
**可以简单的理解:** 先设定3.3V为高电平,0V为低电平,但输入的电平很可能在这之间徘徊,所以我们设定两个参考线,一个是高参考电压一个是低参考电压,只有当输入电平高过高参考电压时才认为是高电平,当输入电平低过低参考电压时才认为是低电平,如果介于两者之间则维持此前的电平不变
这样就输出了稳定的电平到寄存器供芯片读取
不过不同于输出只能有一个控制源,输入的多个分支可以同时读取肖特基触发器上的电平,所以就没有复用输入
但还有一种情况是需要知道具体的电平变化模拟信号而非肖特基触发器处理过后的数字信号,所以产生了不同于其他的模拟输入,在肖特基触发器之前就已经产生分支读取了电平信息