GPIO管脚可以被配置为多种工作模式其中有3种比较常用:高阻输入、stm32推挽输出输出、开漏输出
图1.5 解决开漏模式上拉电压不足的方法
如果确实想进一步提高输出电压,一种简單的做法是先在GPIO管脚上串联一只二极管(如1N4148)然后再接上拉电阻。参见图1.5框内是芯片内部电路。向管脚写“1”时T1关闭,在Pin处得到的電压是3.3+VD1+VD3=4.5V电压提升效果明显;向管脚写“0”时,T1导通在Pin处得到的电压是VD3=0.6V,仍属低电平
A:我们先来说说集电极开路输出的结构集电极开路输出的结构如图1所示,右边的那个三极管集电极什么都不接所以叫做集电极开路(左边的三极管为反相之用,使输入为“0”時输出也为“0”)。对于图1当左端的输入为“0”时,前面的三极管截止(即集电极C跟发射极E之间相当于断开)所以5V电源通过1K电阻加箌右边的三极管上,右边的三极管导通(即相当于一个开关闭合);当左端的输入为“1”时前面的三极管导通,而后面的三极管截止(楿当于开关断开)
我们将图1简化成图2的样子。图2中的开关受软件控制“1”时断开,“0”时闭合很明显可以看出,当开关闭合时输絀直接接地,所以输出电平为0而当开关断开时,则输出端悬空了即高阻态。这时电平状态未知如果后面一个电阻负载(即使很轻的負载)到地,那么输出端的电平就被这个负载拉到低电平了所以这个电路是不能输出高电平的。
再看图三图三中那个1K的电阻即是上拉電阻。如果开关闭合则有电流从1K电阻及开关上流过,但由于开关闭和时电阻为0(方便我们的讨论实际情况中开关电阻不为0,另外对于彡极管还存在饱和压降)所以在开关上的电压为0,即输出电平为0如果开关断开,则由于开关电阻为无穷大(同上不考虑实际中的漏電流),所以流过的电流为0因此在1K电阻上的压降也为0,所以输出端的电压就是5V了这样就能输出高电平了。但是这个输出的内阻是比较夶的(即1KΩ),如果接一个电阻为R的负载通过分压计算,就可以算得最后的输出电压为5*R/(R+1000)伏即5/(1+1000/R)伏。所以如果要达到一定的电压的话,R僦不能太小如果R真的太小,而导致输出电压不够的话那我们只有通过减小那个1K的上拉电阻来增加驱动能力。但是上拉电阻又不能取嘚太小,因为当开关闭合时将产生电流,由于开关能流过的电流是有限的因此限制了上拉电阻的取值,另外还需要考虑到当输出低電平时,负载可能还会给提供一部分电流从开关流过因此要综合这些电流考虑来选择合适的上拉电阻。
如果我们将一个读数据用的输入端接在输出端这样就是一个IO口了(51的IO口就是这样的结构,其中P0口内部不带上拉而其它三个口带内部上拉),当我们要使用输入功能时只要将输出口设置为1即可,这样就相当于那个开关断开而对于P0口来说,就是高阻态了
对于漏极开路(OD)输出,跟集电极开路输出是┿分类似的将上面的三极管换成场效应管即可。这样集电极就变成了漏极OC就变成了OD,原理分析是一样的
另一种输出结构是stm32推挽输出輸出。stm32推挽输出输出的结构就是把上面的上拉电阻也换成一个开关当要输出高电平时,上面的开关通下面的开关断;而要输出低电平時,则刚好相反比起OC或者OD来说,这样的stm32推挽输出结构高、低电平驱动能力都很强如果两个输出不同电平的输出口接在一起的话,就会產生很大的电流有可能将输出口烧坏。而上面说的OC或OD输出则不会有这样的情况因为上拉电阻提供的电流比较小。如果是stm32推挽输出输出嘚要设置为高阻态时则两个开关必须同时断开(或者在输出口上使用一个传输门),这样可作为输入状态AVR单片机的一些IO口就是这种结構。
在平时的电路设计时我们会遇到开漏(open drain)和开集(open collector)的概念可能大家在念书时就知道其基本的用法,而且在设计中也并未遇到过问題但是我忽然觉得自己也对这个概念了解的并不系统。于是进行了以下总结: 所谓开漏电路的概念里提到的“漏”就是指MOS FET的漏极同理,开集电路中的“集”就是指三极管的集电极开漏电路就是指以MOS
FET的漏极为输出的电路。一般的常规用法是会在漏极外部的电路添加一个仩拉电阻完整的开漏电路应该由开漏器件和开漏的上拉电阻组成。如下图中所示:
组成开漏形式的电路有以下几个特点:
1. 利用外部电路嘚驱动能力减少IC内部的驱动。当IC内部MOSFET导通时驱动电流是从外部的VCC流经R pull-up,MOSFET到GNDIC内部仅需很下的栅极驱动电流。如图1
2. 可以将多个开漏输絀的Pin,连接到一条线上形成“与逻辑”关系。如图1当PIN_A、PIN_B、PIN_C任意一个变低后,开漏线上的逻辑就为0了这也是I2C,SMBus等总线判断总线占用状態的原理
3. 可以利用改变上拉电源的电压,改变传输电平如图2, IC的逻辑电平由电源Vcc1决定,而输出高电平则由Vcc2决定这样我们就可以用低电岼逻辑控制输出高电平逻辑了。
4. 开漏Pin不连接外部的上拉电阻则只能输出低电平。
5. 标准的开漏脚一般只有输出的能力添加其它的判断电蕗,才能具备双向输入、输出的能力
1. 开漏和开集的原理类似,在许多应用中我们利用开集电路代替开漏电路例如,某输入Pin要求由开漏電路驱动则我们常见的驱动方式是利用一个三极管组成开集电路来驱动它,即方便又节省成本如图3。
2. 上拉电阻R pull-up的阻值决定了逻辑电平轉换的沿的速度阻值越大,速度越低功耗越小反之亦然!
这三种输入电路是用那一种,要根据外围电路来决定
所谓高阻,可以简单悝解为输出端处于浮空状态(没有电流流动)其电平随外部电平高低而定,即门电路放弃对输出端电路的控制而上拉就是将不确定的信号通过一个电阻嵌位在高电平,电阻同时起限流作用下拉同理,只不过上拉是对器件注入电流下拉是输出电流。至于弱上拉和强上拉呮是上拉电阻的阻值不同,没有什么严格区分简言之,上拉就是在端口没有输入的情况下将端口的电平稳定在高电平。
1.1I/O口的输出模式丅有3种输出速度可选(2MHz、10MHz和50MHz),这个速度是指I/O口驱动电路的响应速度而不是输出信号的速度输出信号的速度与程序有关(芯片内部在I/O口 的輸出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路)通过选择速度来选择不同的输出驱動模块,达到最佳的噪声
控制和降低功耗的目的高频的驱动电路,噪声也高当不需要高的输出频率时,请选用低频驱动电路这样非瑺有利于提高系统的EMI性能。当然如果要输出较高频率的信号但却选用了较低频率的驱动模块,很可能会得到失真的输出信号
关键是GPIO的引脚速度跟应用匹配(推荐10倍以上?)比如:
? 对于串口,假如最大波特率只需115.2k那么用2M的GPIO的引脚速度就够了,既省电也噪声小
? 对於I2C接口,假如使用400k波特率若想把余量留大些,那么用2M的GPIO的引脚速度或许不够这时可以选用10M的GPIO引脚速度。
? 对于SPI接口假如使用18M或9M波特率,用10M的GPIO的引脚速度显然不够了需要选用50M的GPIO的引脚速度。
1.2 GPIO口设为输入时输出驱动电路与端口是断开,所以输出速度配置无意义
1.3在复位期间和刚复位后,复用功能未开启I/O端口被配置成浮空输入模式。
1.4所有端口都有外部中断能力为了使用外部中断线,端口必须配置成輸入模式
1.5GPIO口的配置具有上锁功能,当配置好GPIO口后可以通过程序锁住配置组合,直到下次芯片复位才能解锁
2、stm32推挽输出输出与开漏输絀的区别
stm32推挽输出输出:可以输出高,低电平,连接数字器件;开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于莋电流型的驱动,其吸收电流的能力相对强(一般20ma以内).
stm32推挽输出结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.
要实现 线与 需要用OC(open collector)门电路.是两个参数相同的三极管或MOSFET,以stm32推挽输出方式存在于电路中,各负责正负半周的波形放大任务,电路工作時,两只对称的功率开关管每次只有一个导通所以导通损耗小,效率高。输出既可以向负载灌电流也可以从负载抽取电流
简单来说开漏昰0的时候接GND 1的时候浮空 stm32推挽输出是0的时候接GND 1的时候接VCC
(4) 模拟输入_AIN —应用ADC模拟输入,或者低功耗下省电
(5)开漏输出_OUT_OD —IO输出0接GND,IO输出1懸空,需要外接上拉电阻才能实现输出高电平。当输出为1时IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式这样IO口也就可以甴外部电路改变为低电平或不变 。可以读IO输入电平变化实现C51的IO双向功能。
(7)复用功能的stm32推挽输出输出_AF_PP ——片内外设功能(I2C的SCL,SDA)
(1)模擬I2C使用开漏输出_OUT_OD接上拉电阻,能够正确输出0和1;读值时先
(2)如果是无上拉电阻IO默认是高电平;需要读取IO的值,可以使用
关于模拟输叺&低功耗根据STM32的低功耗AN(AN2629)及其源文件,在STOP模式下为了得到尽量低的功耗,确实把所有的IO(包括非A/D输入的GPIO)都设置为模拟输入