你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32f1的IO,推挽与开漏

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:20
stm32的引脚有两种用途:GPIO(general purpose io)和AFIO(alternate function io)
' v! U) I2 ?7 @1 b5 ]
/ ^, C2 }" T+ c  C8 k对于一些引脚(视芯片而定),这两种用途都没有,如在64脚产品中,OSC_IN/OSC_OUT与作为GPIO端口的PD0/PD1共用一样的引脚,而在100、144引脚产品中,这四个功能各有引脚与之对应,不互相冲突,所以OSC_IN/OSC_OUT既不作GPIO也不作AFIO,当然,这样的引脚不是讨论重点。/ P( W4 b8 J6 A7 w

' L7 M6 E0 O4 T1、引脚的配置
* h, f1 N9 K* q8 j  t
4 ~9 w" q  Z; D3 m# O/ I2 A不论是作GPIO还是做AFIO,都要对引脚进行配置。在固件库函数中,用GPIO_Init()函数对引脚进行配置,并不是说这个函数带了“GPIO”字样就是要当做GPIO来用,而是把它纳入GPIO的范畴来讨论。4 F& ?" p) c6 H
1 Y! V2 h0 X; o" P2 C- c  `
所谓配置,就是引脚上的片上资源连接方式,如上拉电阻、密特触发等等。理解了配置,也就能明白配置与模式的区别。
; Z' S7 z6 S* W
# x% z' ?, X9 Z特别得,在下文中将会专门讨论一下输出配置中的推挽与开漏。
; x# G( t1 d4 b) C3 x* @: k. t  }. v0 d" y8 Y
2、复用功能
5 k/ Q' O/ H9 P4 D1 c9 \, u
2 [8 R3 r) n* Q$ I& k. @( j  a$ l复用功能有两种:没有重映像、重映像(包括部分重映像、完全重映像),使用引脚用作AFIO功能,同样需要对其进行配置。4 e, ?0 H, a. ^( n9 Z* B0 g" X% I
( Y5 R% [( r6 N, {# i, w) D! S
1341810945_5803.jpg
1 k0 L+ q: R' U8 P
这三句话来自参考手册,但我对第一句和注意有疑问,第三节讲。如果把端口配置成复用输出功能,则引脚和输出寄存器断开,并和片上外设的输出信号连接。输入配置则与GPIO没有区别。0 e" M( g! E- }  R6 \
$ [" B( H4 [- ]
为什么输出模式有专门的复用模式而输入则没有呢。因为输出是由芯片内部电路驱动的,必须选择这个驱动来自哪一个外设,是GPIO还是复用此管脚的其他外设,也就是选择该管脚在内部是与哪个外设相连的,不说明这个就会发生信号的错乱。而输入则不同了,输入信号是由芯片外的信号驱动的,虽然该信号进入芯片内部后可能有不同的去向,但不需要对此进行配置,因为不会发生信号的冲突,最坏的情况就是多驱动了个寄存器而已。事实上,当将引脚作为GPIO输入时,相应的AFIO外设是处在关闭的状态,并不会耗电;当引脚作为AFIO的输入时,可能GPIO是读不进来的,这是我猜的,没有验证,能不能读进来无所谓的,不必纠结于此。, S$ p9 M7 _3 k6 x9 c2 K

& h" i$ v' C, V2 t
1341809146_6021.jpg

3 `. W- ^) o$ [! o) ~# \/ ^  V若选择了复用,则默认是没有重映像的,可以直接使用外设,不需要再软件做设置。$ a0 s0 T3 A! }0 y$ f

; i+ I( F% o9 ~9 C: j但若要重映射,则需要简单设置一下,# c. K" h5 X, r6 A
4 V3 w" a9 m# c8 ?1 u
先要配置重映射后对应的管脚,可参看参考手册或数据手册引脚定义章节,开AFIO时钟,使能重映射。例如重映射USART1,全部代码如下:5 f1 \1 \& c# I8 s( E, j

* Y3 d2 B/ h7 S: x3 |! O8 f8 o  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
+ v# L! ]3 Y1 M+ H" q, U! ]6 ~$ ~' [% U
  /*对寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX进行读写操作前,即重映射和选择外部中断线前,应当首先打开AFIO的时钟*/
: t2 Z% W* \5 R" \
& x6 t. V( [% P
  1. <p>  /* Configure USART1 Tx (PA.09) as alternate function push-pull */</p><p>
    " e: s' s' d' n* R
  2. </p><p>  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;</p><p>
    0 P3 }3 }# B9 m+ f; `9 g" Q
  3. </p><p>  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;</p><p>% P) J9 r3 p+ U4 a4 M! p
  4. </p><p>  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;</p><p>, j8 t: U: I9 d* U! {4 }
  5. </p><p>  GPIO_Init(GPIOB, &GPIO_InitStructure);</p><p>
    " F' n. C; s! }( {" i9 ^+ ?
  6. </p><p>    </p><p>
    5 P4 V  G1 S" Y! a  ~" y1 O$ _' N7 Y; u
  7. </p><p>  /* Configure USART1 Rx (PA.10) as input floating */</p><p>- v, A5 r. T3 l3 U+ h: h
  8. </p><p>  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;</p><p>
    / ^5 q2 X1 P( o- R4 D
  9. </p><p>  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;</p><p>
    ' c4 x2 Z  u' }9 S7 t
  10. </p><p>  GPIO_Init(GPIOB, &GPIO_InitStructure);</p><p>) k- G8 h+ R$ W8 W
  11. </p><p>  GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);</p>
复制代码

$ X5 n: ^1 w2 l" R7 Q& c7 D这就完成了IO口的配置和重映射,下边再配置相关的外设(USART1)就可以使用了。1 u& ?* ?9 s9 K2 C; O
3 I/ ~! ?$ J8 Y1 j/ |
外部中断线也是可以映射的,并且需要开AFIO时钟,不用GPIO_PinRemap函数,用GPIO_EXTILineConfig重映射引脚到中断线。其实与其说是映射,不如说是选择,选择引脚连接到外部中断线。
+ e, t  Z" X. ?" n6 `1 r
, x; d4 d; w6 i5 Z/ I5 F重映射不是任意的,只能重映射到指定的管脚。1 d9 M2 B. w& ~& ?5 v, m9 T! Y
! c6 _/ J" H) F) ^2 W& T& X' v# V
3、关于第二节讲到那个疑问,为甚么不能配置成模拟输入?模拟输入与浮空什么区别?; e/ {/ f# h, ~! z9 h6 U

5 m- ]. x: d1 I) I3 O答案是可以配置成模拟输入,官方3.5版固件库例子和alientek例程都是将ADC输入引脚配置成GPIO_Mode_AIN" P& X; o  ~; _: w& ^% f
4 N- k$ S1 m7 x# {$ Q
那么配置成浮空行么,还能ADC么?$ A  O6 T  c# P' k( Q4 S4 n
  1. <p><span style="background-color: rgb(255, 255, 255);"> </span>   //例程</p><p>1 d$ [* B* d: U& B& C
  2. </p><p>    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;</p><p>    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;</p><p>    GPIO_Init(GPIOC, &GPIO_InitStructure);</p><p>) q; w& d2 c# ~# F
  3. </p><p>     //修改</p><p>* _1 L3 P+ m2 u% r. ?
  4. </p><p>    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;</p><p>    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;</p><p>    GPIO_Init(GPIOC, &GPIO_InitStructure);</p><p></p>
复制代码

% d& S% k! i7 i' [( @实验证明,这两种配置都能实现ADC。那么USART的Tx应配置成GPIO_Mode_IN_FLOATING,如果配置成GPIO_Mode_AIN,还能接受数据么?金牛板实验结果是不能,ST不我欺也。总之:5 ]; Y9 B7 o5 O

! d& B3 c) s1 P: k9 J可以将引脚配置成模拟输入,使用相应的复用功能;
' X# C) l9 J' S! i1 j$ T% |! `! L8 W$ F
浮空与模拟这两种配置是不同的。' b4 U" m6 \# b+ q% o: a0 o+ P
! A5 p" e0 |5 d' o
关于第二节里那个“注意“,我也不知道是什么意思。我猜测是这样的:打开某外设,这个外设将某引脚当做输入,我们偏偏把这个引脚配置为GPIO输出,这样可以操作GPIO来”欺骗“这个外设,这种用法应该是很微妙的。
/ \5 y8 N7 o+ N6 y' c, T3 Y+ U8 j" t& J' g5 |' R5 Z/ E# J
4、推挽与开漏( V! B* c- c9 C( A2 @+ T- l
( {# h- U$ h( ~( ?. A
不仅仅stm32有这种配置,实际上,这两种已经广泛应用在很多场合。) L7 C7 e8 W& n) E1 G5 L. G3 d
2 F. d! g" s& t% d/ h% g7 H- h6 M
推挽,又叫做推拉,是个很形象的名字,一般是指两个三极管(MOS管)分别受两互补信号(或者一个信号,但是用互补对管)的控制,总是在一个三极管导通的时候另一个截止,这样的电路被称为推挽式(互补式):
/ S6 Q! c; R3 W* s0 d6 Q% q, `( i/ Y8 a" h- g" z
1346657973_9578.png
5 X6 @. J; a3 M8 D5 S
这种电路在放大中通常被用作输出级,在STM32中,推挽配置就是这种,如图:
* H/ G" b& q7 h( j  T3 u" d* {
/ }9 }' D& n! R6 k' F; o; q  |# H
1346657791_8272.jpg
6 n6 v0 E9 Y5 J) P% I
在相应位置1时,P-MOS导,通N-MOS截止,输出电压为VDD;在相应位置0时,N-MOS导通,P-MOS截止,输出电压为VSS,这就是所谓的推挽。是比较简单的。
5 B% ?% k" n( a
: p- g' O4 z  O4 s  X而所谓的开漏(对三极管而言是开集,一样的原理),则要巧妙一些。所谓开漏电路概念中提到的“漏”就是指MOS FET的漏极。同理,开集电路中的“集”就是指三极管的集电极。开漏电路就是指以MOS FET的漏极为输出的电路。一般的用法是会在漏极外部的电路添加上拉电阻。完整的开漏电路应该由开漏器件和开漏上拉电阻组成。
7 D. Y* m8 Z! j
  }' N4 O; |1 j: q7 `对于stm32,开漏就是失能了P-MOS,这样,当相应位置1时,引脚实际上是处在了浮空的状态,而通过外接的上拉电阻,将其拉高。
$ f+ y- `" n$ t+ G; P# q! J3 H
# O; Y; W, E) Y1 a* F7 \/ W这么做有如下的好处:
0 j7 }% ]: X' f* C& q! a0 n+ H) e' p* U' O- z3 v3 i0 b" s$ _# N$ q
1、可以将多个开漏输出的引脚,连接到一条线上。形成“与逻辑”关系。当多个引脚任意一个变低后,开漏线上的逻辑就为0了。这也是I2C,SMBus等总线判断总线占用状态的原理。
' H2 M8 r! j5 T9 b% E2、 可以利用改变上拉电源的电压,改变传输电平。这样我们就可以用低电平逻辑控制输出高电平逻辑了。想想当初认为stm32输出3.3v电压带不动IRF540,就直接断定要重新选型,是错误的想法,只要将推挽输出变为开漏,再加上上拉到5v的电阻,就能解决这个问题。' Q9 D6 T4 o& j) w5 n6 M
+ R3 {# Z0 F$ B4 @3 v
顺便一提,上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小。反之亦然。
9 a5 Q/ f6 ?" m% b3 v! d4 U4 R' c* e* ?) b# \9 c
; F. l0 E/ P* U, ]
收藏 评论0 发布时间:2021-11-29 22:20

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版