关于STM32 GPIO配置模式
扫描二维码
随时随地手机看文章
其实关于GPIO模式,手册有非常详细的说明,可见好好查看Datasheet有多么重要!!
首先关于stm32的GPIO口有输入输出之分,这点与51单片机使用的双向IO口有区别,这就需要根据我们具体是输入还是输出配置为相应的输入输出模式。输入就是输入模式,输出就是输出模式,两者不能混用。
下面这段话是手册这么描述GPIO口的:
通用I/O(GPIO)
复位期间和刚复位后,复用功能未开启,I/O端口被配置成浮空输入模式(CNFx[1:0]=01b,
MODEx[1:0]=00b)。
复位后,JTAG引脚被置于输入上拉或下拉模式:
─PA15:JTDI置于上拉模式
─PA14:JTCK置于下拉模式
─PA13:JTMS置于上拉模式
─PB4:JNTRST置于上拉模式
当作为输出配置时,写到输出数据寄存器上的值(GPIOx_ODR)输出到相应的I/O引脚。可以以推
挽模式或开漏模式(当输出0时,只有N-MOS被打开)使用输出驱动器。
输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。
所有GPIO引脚有一个内部弱上拉和弱下拉,当配置为输入时,它们可以被激活也可以被断开
从上面的描述我们知道,单片机复位后默认是浮空输入模式,但是JTAG的引脚会被设置为输入上拉或者下拉模式。输出模式下是输出寄存器ODR的输出到对应IO口实现高低电平。
输入配置
当I/O端口配置为输入时:
● 输出缓冲器被禁止
● 施密特触发输入被激活
● 根据输入配置(上拉,下拉或浮动)的不同,弱上拉和下拉电阻被连接
● 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器
● 对输入数据寄存器的读访问可得到I/O状态
参见手册关于输入配置这几点很重要。
1)当作为输入时,输出数据寄存器与IO口之间是断开的,这也就意味着我们在输入状态下即使操作输出数据寄存器对IO口也没有影响。比如我们用库函数各种直接或间接改变输出数据寄存器的操作都是无效的。比如我们设置在初始化某IO为上拉输入后,又将该IO口输出为0,将这输出为0的操作是完全无效不起作用的!比如你设置为输入去用万用表测IO口就很可笑的操作!!
2)IO口的数据在每个APB2时钟被采样到输入数据寄存器,这就意味着我们比如当前模式为输入模式,那么在72M系统时钟下,约每13ns会更新一次输入数据。比如我们在写某些通信接口时序,在设置为输入模式下就要留个心看看是否数据能否在读命令下是否13ns该通信方式是否有效数据已经到达保证读取 的是准确值,是否需加延时(针对通信数据更新慢的情况)。
3)注意我们设置为浮空、上拉还是下拉输入,在没有接外设的情况下,这些状态才是确定的。比如我们说浮空模式下,输入值不确定可能为0可能为1,上拉输入时输入数据寄存器为1,下拉输入时输入数据寄存器值为0均是针对前提是在未接任何外设情况下来说的!我们测开发板一定要先确定引脚是否有外设影响!
4)STM32为弱上拉和弱下拉,也就是上拉电阻阻值很大,未接外设时输入数据寄存器为1,这样有利于检测低电平输入;同理,下拉输入未接外设输入数据寄存器为0,有利于我们检测高电平输入。而对于外设电平可高可低的输入,我们设置为浮空输入即可。
5)输入数据寄存器为只读,在硬件仿真时值是屏蔽表示不可修改,但是值是准确的!需要注意的是,硬件仿真输入模式下去查看输入寄存器IDR没意义,输出模式下去查看输出数据寄存器ODR也没意义。
输出配置
当I/O端口被配置为输出时:
● 输出缓冲器被激活
─开漏模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将端口置于高阻状态(PMOS从不被激活)。
─推挽模式:输出寄存器上的’0’激活N-MOS,而输出寄存器上的’1’将激活P-MOS。
● 施密特触发输入被激活
● 弱上拉和下拉电阻被禁止
● 出现在I/O脚上的数据在每个APB2时钟被采样到输入数据寄存器
● 在开漏模式时,对输入数据寄存器的读访问可得到I/O状态
● 在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的值。
参见手册关于输出配置这段话我们需要注意这几点:
1)在输出模式下,输入寄存器与IO口之间并未屏蔽,并且在开漏输出模式下,我们读输入数据寄存器的操作可以真实的读取我们输入口的状态(尽管不建议输出模式和输入混用,但是具有这样的性质是要注意的)
2)开漏输出的特点如果要控制外设,则必须外接上拉电阻,因为其自身不具备输出高电平的能力,只能输出低电平,当然这种需外接上拉电阻的模式也实现我们可输出我们想要的任意“高电平”,比如5V外接5V上拉即可;而推挽输出则可输出可高可低电平。(欲了解见下文)
单片机I/O口推挽与开漏输出详解:
推挽输出:可以输出高,低电平,连接数字器件;推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.
开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内).
我们先来说说集电极开路输出的结构。集电极开路输出的结构如图1所示,右边的那个三极管集电极什么都不接,所以叫做集电极开路(左边的三极管为反相之用,使输入为“0”时,输出也为“0”)。对于图1,当左端的输入为“0”时,前面的三极管截止(即集电极C跟发射极E之间相当于断开),所以5V电源通过1K电阻加到右边的三极管上,右边的三极管导通(即相当于一个开关闭合);当左端的输入为“1”时,前面的三极管导通,而后面的三极管截止(相当于开关断开)。
我们将图1简化成图2的样子。图2中的开关受软件控制,“1”时断开,“0”时闭合。很明显可以看出,当开关闭合时,输出直接接地,所以输出电平为0。而当开关断开时,则输出端悬空了,即高阻态。这时电平状态未知,如果后面一个电阻负载(即使很轻的负载)到地,那么输出端的电平就被这个负载拉到低电平了,所以这个电路是不能输出高电平的。
再看图三。图三中那个1K的电阻即是上拉电阻。如果开关闭合,则有电流从1K电阻及开关上流过,但由于开关闭其它三个口带内部上拉),当我们要使用输入功能时,只要将输出口设置为1即可,这样就相当于那个开关断开,而对于P0口来说,就是高阻态了。
对于漏极开路(OD)输出,跟集电极开路输出是十分类似的。将上面的三极管换成场效应管即可。这样集电极就变成了漏极,OC就变成了OD,原理分析是一样的。
另一种输出结构是推挽输出。推挽输出的结构就是把上面的上拉电阻也换成一个开关,当要输出高电平时,上面的开关通,下面的开关断;而要输出低电平时,则刚好相反。比起OC或者OD来说,这样的推挽结构高、低电平驱动能力都很强。如果两个输出不同电平的输出口接在一起的话,就会产生很大的电流,有可能将输出口烧坏。而上面说的OC或OD输出则不会有这样的情况,因为上拉电阻提供的电流比较小。如果是推挽输出的要设置为高阻态时,则两个开关必须同时断开(或者在输出口上使用一个传输门),这样可作为输入状态,AVR单片机的一些IO口就是这种结构。
开漏电路特点及应用
在电路设计时我们常常遇到开漏(open drain)和开集(open collector)的概念。
所谓开漏电路概念中提到的“漏”就是指MOSFET的漏极。同理,开集电路中的“集”就是指三极管的集电极。开漏电路就是指以MOSFET的漏极为输出的电路。一般的用法是会在漏极外部的电路添加上拉电阻。完整的开漏电路应该由开漏器件和开漏上拉电阻组成。如图1所示:
组成开漏形式的电路有以下几个特点:
1. 利用外部电路的驱动能力,减少IC内部的驱动(或驱动比芯片电源电压高的负载)。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。如图1。
2. 可以将多个开漏输出的Pin,连接到一条线上。形成 “与逻辑” 关系。如图1,当PIN_A、PIN_B、PIN_C任意一个变低后,开漏线上的逻辑就为0了。这也是I2C,SMBus等总线判断总线占用状态的原理。如果作为输出必须接上拉电阻。接容性负载时,下降延是芯片内的晶体管,是有源驱动,速度较快;上升延是无源的外接电阻,速度慢。如果要求速度高电阻选择要小,功耗会大。所以负载电阻的选择要兼顾功耗和速度。
3. 可以利用改变上拉电源的电压,改变传输电平。如图2, IC的逻辑电平由电源Vcc1决定,而输出高电平则由Vcc2(上拉电阻的电源电压)决定。这样我们就可以用低电平逻辑控制输出高电平逻辑了(这样你就可以进行任意电平的转换)。(例如加上上拉电阻就可以提供TTL/CMOS电平输出等。)
4. 开漏Pin不连接外部的上拉电阻,则只能输出低电平(因此对于经典的51单片机的P0口而言,要想做输入输出功能必须加外部上拉