一文看懂stm32的引脚的两种用途:GPIO和AFIO

发布时间:2024-01-05  

stm32的引脚有两种用途:GPIO(general purpose io)和AFIO(alternate function io)

对于一些引脚(视芯片而定),这两种用途都没有,如在64脚产品中,OSC_IN/OSC_OUT与作为GPIO端口的PD0/PD1共用一样的引脚,而在100、144引脚产品中,这四个功能各有引脚与之对应,不互相冲突,所以OSC_IN/OSC_OUT既不作GPIO也不作AFIO,当然,这样的引脚不是讨论重点。


1、引脚的配置

不论是作GPIO还是做AFIO,都要对引脚进行配置。在固件库函数中,用GPIO_Init()函数对引脚进行配置,并不是说这个函数带了“GPIO”字样就是要当做GPIO来用,而是把它纳入GPIO的范畴来讨论。

所谓配置,就是引脚上的片上资源连接方式,如上拉电阻、密特触发等等。理解了配置,也就能明白配置与模式的区别。

特别得,在下文中将会专门讨论一下输出配置中的推挽与开漏。

2、复用功能

复用功能有两种:没有重映像、重映像(包括部分重映像、完全重映像),使用引脚用作AFIO功能,同样需要对其进行配置。

这三句话来自参考手册,但我对第一句和注意有疑问,第三节讲。如果把端口配置成复用输出功能,则引脚和输出寄存器断开,并和片上外设的输出信号连接。输入配置则与GPIO没有区别。

为什么输出模式有专门的复用模式而输入则没有呢。因为输出是由芯片内部电路驱动的,必须选择这个驱动来自哪一个外设,是GPIO还是复用此管脚的其他外设,也就是选择该管脚在内部是与哪个外设相连的,不说明这个就会发生信号的错乱。而输入则不同了,输入信号是由芯片外的信号驱动的,虽然该信号进入芯片内部后可能有不同的去向,但不需要对此进行配置,因为不会发生信号的冲突,最坏的情况就是多驱动了个寄存器而已。事实上,当将引脚作为GPIO输入时,相应的AFIO外设是处在关闭的状态,并不会耗电;当引脚作为AFIO的输入时,可能GPIO是读不进来的,这是我猜的,没有验证,能不能读进来无所谓的,不必纠结于此。

若选择了复用,则默认是没有重映像的,可以直接使用外设,不需要再软件做设置。

但若要重映射,则需要简单设置一下,

先要配置重映射后对应的管脚,可参看参考手册或数据手册引脚定义章节,开AFIO时钟,使能重映射。例如重映射USART1,全部代码如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 

/*对寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX进行读写操作前,即重映射和选择外部中断线前,应当首先打开AFIO的时钟*/

/* Configure USART1 Tx (PA.09) as alternate function push-pull */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Configure USART1 Rx (PA.10) as input floating */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);

这就完成了IO口的配置和重映射,下边再配置相关的外设(USART1)就可以使用了。

外部中断线也是可以映射的,并且需要开AFIO时钟,不用GPIO_PinRemap函数,用GPIO_EXTILineConfig重映射引脚到中断线。其实与其说是映射,不如说是选择,选择引脚连接到外部中断线。

重映射不是任意的,只能重映射到指定的管脚。

3、关于第二节讲到那个疑问,为甚么不能配置成模拟输入?模拟输入与浮空什么区别?

答案是可以配置成模拟输入,官方3.5版固件库例子和alientek例程都是将ADC输入引脚配置成GPIO_Mode_AIN

那么配置成浮空行么,还能ADC么?

//例程

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

//修改

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

实验证明,这两种配置都能实现ADC。那么USART的Tx应配置成GPIO_Mode_IN_FLOATING,如果配置成GPIO_Mode_AIN,还能接受数据么?金牛板实验结果是不能,ST不我欺也。总之:

可以将引脚配置成模拟输入,使用相应的复用功能;

浮空与模拟这两种配置是不同的。

关于第二节里那个“注意“,我也不知道是什么意思。我猜测是这样的:打开某外设,这个外设将某引脚当做输入,我们偏偏把这个引脚配置为GPIO输出,这样可以操作GPIO来”欺骗“这个外设,这种用法应该是很微妙的。

4、推挽与开漏

不仅仅stm32有这种配置,实际上,这两种已经广泛应用在很多场合。

推挽,又叫做推拉,是个很形象的名字,一般是指两个三极管(MOS管)分别受两互补信号(或者一个信号,但是用互补对管)的控制,总是在一个三极管导通的时候另一个截止,这样的电路被称为推挽式(互补式):

这种电路在放大中通常被用作输出级,在STM32中,推挽配置就是这种,如图:

在相应位置1时,P-MOS导,通N-MOS截止,输出电压为VDD;在相应位置0时,N-MOS导通,P-MOS截止,输出电压为VSS,这就是所谓的推挽。是比较简单的。

而所谓的开漏(对三极管而言是开集,一样的原理),则要巧妙一些。所谓开漏电路概念中提到的“漏”就是指MOS FET的漏极。同理,开集电路中的“集”就是指三极管的集电极。开漏电路就是指以MOS FET的漏极为输出的电路。一般的用法是会在漏极外部的电路添加上拉电阻。完整的开漏电路应该由开漏器件和开漏上拉电阻组成。

对于stm32,开漏就是失能了P-MOS,这样,当相应位置1时,引脚实际上是处在了浮空的状态,而通过外接的上拉电阻,将其拉高。

这么做有如下的好处:

1、可以将多个开漏输出的引脚,连接到一条线上。形成“与逻辑”关系。当多个引脚任意一个变低后,开漏线上的逻辑就为0了。这也是I2C,SMBus等总线判断总线占用状态的原理。在我的文章“stm32模拟iic——引脚配置、代码”中,还会提到这个问题。
2、 可以利用改变上拉电源的电压,改变传输电平。这样我们就可以用低电平逻辑控制输出高电平逻辑了。想想当初认为stm32输出3.3v电压带不动IRF540,就直接断定要重新选型,是错误的想法,只要将推挽输出变为开漏,再加上上拉到5v的电阻,就能解决这个问题。

顺便一提,上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小。反之亦然。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>