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

stm32的引脚有两种用途:gpio(generalpurposeio)和afio(alternatefunctionio)
对于一些引脚(视芯片而定),这两种用途都没有,如在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的时钟*/
/*configureusart1tx(pa.09)asalternatefunctionpush-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);
/*configureusart1rx(pa.10)asinputfloating*/
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的电阻,就能解决这个问题。
顺便一提,上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小。反之亦然。

学生们开创了使用 Wi-Fi 隔墙识别人的软件
小米6Plus什么时候上市?最新消息:小米6Plus曝光!网友:不着急,先来个小米6压压惊
GPRS远程多表集抄系统技术
人工智能时代来临,我们的工作岗位有什么变化呢?
贸泽开售TE Connectivity DT-XT密封式连接器系统 适用于要求严苛的商用汽车应用
一文看懂stm32的引脚的两种用途:GPIO和AFIO
lm741原理图_lm741应用电路
Pharnext等医药初创公司正借助机器学习来研究“专利过期”药物的新医疗用途
3D打印牙线问世,可清洁所有牙齿
Melexis推出新品MLX75027RTI ToF传感器
二极管IN4148和IN4007的应用区别
工业互联网的建设将成为传统制造业智能化发展的核心
美光科技发布NVMe级别的两款SSD新品,强化安全特性和数据保护功能
消费者们如何看待智能家居
小米公益平台正式上线
解析74HC14的原理及极限参数
PSA和FCA合并曝光:并不是合并,而是收购
AI涉足减肥领域 可AI+减肥并不是万能的
Silicon推出新型晶体振荡器XO/VCXO系列产品
基于米唐科技的语音解决方案