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

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

[复制链接]
STMCU小助手 发布时间:2021-11-29 22:20
stm32的引脚有两种用途:GPIO(general purpose io)和AFIO(alternate function io)
$ F- B' e# x5 b% C8 w, w4 k8 _1 r* }# Z& \# O8 ^" N! ?# `
对于一些引脚(视芯片而定),这两种用途都没有,如在64脚产品中,OSC_IN/OSC_OUT与作为GPIO端口的PD0/PD1共用一样的引脚,而在100、144引脚产品中,这四个功能各有引脚与之对应,不互相冲突,所以OSC_IN/OSC_OUT既不作GPIO也不作AFIO,当然,这样的引脚不是讨论重点。9 N# C5 H# z) k' N
" ?/ a: {( \/ `: @
1、引脚的配置
: r4 y8 E9 m( K7 L% w# U
7 B7 M$ D* q( p8 q1 J7 K不论是作GPIO还是做AFIO,都要对引脚进行配置。在固件库函数中,用GPIO_Init()函数对引脚进行配置,并不是说这个函数带了“GPIO”字样就是要当做GPIO来用,而是把它纳入GPIO的范畴来讨论。
/ k' }  n+ h* _% {( t0 s2 I$ _2 x/ w& n/ U3 M/ i( m
所谓配置,就是引脚上的片上资源连接方式,如上拉电阻、密特触发等等。理解了配置,也就能明白配置与模式的区别。4 `9 G) ]' z" t3 B' e$ W' {, I7 p
* t& k) ]" C. e
特别得,在下文中将会专门讨论一下输出配置中的推挽与开漏。
6 f& J, H) Z  X: m
% }3 C( ^+ t. f/ ?$ j% y2、复用功能" r. M$ i1 N8 \: r3 t$ I1 K. A4 b
* G% V1 G/ Q# m) N  N
复用功能有两种:没有重映像、重映像(包括部分重映像、完全重映像),使用引脚用作AFIO功能,同样需要对其进行配置。0 v/ u6 \& J# F
! a8 W1 D( L6 j4 {
1341810945_5803.jpg
  G5 S" M/ Q+ W+ G
这三句话来自参考手册,但我对第一句和注意有疑问,第三节讲。如果把端口配置成复用输出功能,则引脚和输出寄存器断开,并和片上外设的输出信号连接。输入配置则与GPIO没有区别。" {, [  L0 e! X  I- I7 W! P2 c3 p

/ R7 e* R# M% ~6 _  R' _6 A( {! y; |为什么输出模式有专门的复用模式而输入则没有呢。因为输出是由芯片内部电路驱动的,必须选择这个驱动来自哪一个外设,是GPIO还是复用此管脚的其他外设,也就是选择该管脚在内部是与哪个外设相连的,不说明这个就会发生信号的错乱。而输入则不同了,输入信号是由芯片外的信号驱动的,虽然该信号进入芯片内部后可能有不同的去向,但不需要对此进行配置,因为不会发生信号的冲突,最坏的情况就是多驱动了个寄存器而已。事实上,当将引脚作为GPIO输入时,相应的AFIO外设是处在关闭的状态,并不会耗电;当引脚作为AFIO的输入时,可能GPIO是读不进来的,这是我猜的,没有验证,能不能读进来无所谓的,不必纠结于此。$ e4 U' r. S) a5 u7 H- M7 P3 j4 [
8 p' [5 n. b$ m2 w6 ?+ K9 o7 \5 |
1341809146_6021.jpg
7 a+ a4 A( n% _! J
若选择了复用,则默认是没有重映像的,可以直接使用外设,不需要再软件做设置。7 m9 m$ ]* _1 E. k$ \
$ ]/ S  c2 w2 c6 u4 n
但若要重映射,则需要简单设置一下,
3 Q  C4 A# C- B( L/ B! h7 Y: @; q' h: }, R
先要配置重映射后对应的管脚,可参看参考手册或数据手册引脚定义章节,开AFIO时钟,使能重映射。例如重映射USART1,全部代码如下:
9 L) W$ M0 M8 ]- i% ?4 J
3 w% b8 p* {1 c1 i6 n8 C  R' H  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 5 Z" @  H2 `; w6 Q$ I" k9 E

7 `) E' g$ \% o% _. ^  /*对寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX进行读写操作前,即重映射和选择外部中断线前,应当首先打开AFIO的时钟*/
- `& O( V1 m1 D/ ~: m
0 S- B" ]: m" g) Z; B
  1. <p>  /* Configure USART1 Tx (PA.09) as alternate function push-pull */</p><p>" @; P; H) `$ d+ `- }
  2. </p><p>  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;</p><p>
    ) f7 u3 \* [1 O7 [" {
  3. </p><p>  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;</p><p>
    ' w2 }& u8 S" Z% ?' E" O
  4. </p><p>  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;</p><p>
    - y7 q8 d4 n* C0 e0 {+ ?8 k* P% h
  5. </p><p>  GPIO_Init(GPIOB, &GPIO_InitStructure);</p><p>: c( K, L" |* z
  6. </p><p>    </p><p>
    & b0 Q# j1 m! m2 b
  7. </p><p>  /* Configure USART1 Rx (PA.10) as input floating */</p><p>
    / c8 R* i- |2 Z5 Z+ ^
  8. </p><p>  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;</p><p>( o8 W4 w! Z  G. f9 P8 m
  9. </p><p>  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;</p><p>
    ( H  x& W. V' t
  10. </p><p>  GPIO_Init(GPIOB, &GPIO_InitStructure);</p><p>
    8 ~6 F% L8 J+ b
  11. </p><p>  GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);</p>
复制代码
7 x8 e' f  d5 H9 O' X
这就完成了IO口的配置和重映射,下边再配置相关的外设(USART1)就可以使用了。
4 W* M/ C4 [& P# \/ z* V
+ G# R/ N: i& G7 X3 z5 n8 O外部中断线也是可以映射的,并且需要开AFIO时钟,不用GPIO_PinRemap函数,用GPIO_EXTILineConfig重映射引脚到中断线。其实与其说是映射,不如说是选择,选择引脚连接到外部中断线。' [0 ^9 v1 w6 G

7 y: b2 R2 x0 g2 C重映射不是任意的,只能重映射到指定的管脚。9 N. z  W5 \0 C+ Q' K5 m" C$ u7 a# m

8 v8 I) {# s8 E; T) Q3、关于第二节讲到那个疑问,为甚么不能配置成模拟输入?模拟输入与浮空什么区别?
" \5 ~4 d) n2 ?1 L1 G! m6 b: p
- U& Q) E+ |! f$ h4 E% R答案是可以配置成模拟输入,官方3.5版固件库例子和alientek例程都是将ADC输入引脚配置成GPIO_Mode_AIN7 ~1 _. P' D* r" u4 j, \$ q5 z

6 v" E1 D/ v6 @9 b7 L, y那么配置成浮空行么,还能ADC么?
2 R' Z/ M. U1 u# z  T/ F
  1. <p><span style="background-color: rgb(255, 255, 255);"> </span>   //例程</p><p>
    ' s# x0 D& v: F/ \! K2 p9 i
  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>
    & w. a0 s4 C& w" ^( l1 ?
  3. </p><p>     //修改</p><p>
    , ]  d( m; x8 A: v2 U. r+ e! w
  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>
复制代码
3 `1 h* `& o' {# Q0 }' i
实验证明,这两种配置都能实现ADC。那么USART的Tx应配置成GPIO_Mode_IN_FLOATING,如果配置成GPIO_Mode_AIN,还能接受数据么?金牛板实验结果是不能,ST不我欺也。总之:
3 h+ m; e7 T/ G8 W. I* H- t* I- K
( \* i( T4 g6 T2 m! x9 j可以将引脚配置成模拟输入,使用相应的复用功能;  s' g1 G, z1 @  n, F1 x1 @. Z0 T
: P9 H. G) u3 ^3 z, L
浮空与模拟这两种配置是不同的。. j- u% T0 M+ k& ~7 S. {
) C# D3 p8 N* c' i$ B
关于第二节里那个“注意“,我也不知道是什么意思。我猜测是这样的:打开某外设,这个外设将某引脚当做输入,我们偏偏把这个引脚配置为GPIO输出,这样可以操作GPIO来”欺骗“这个外设,这种用法应该是很微妙的。
2 I8 p5 C2 Z, K6 R7 p% F1 I* c
5 \/ M8 s7 h7 m' {3 U0 [4、推挽与开漏
# \1 N0 s. _! E' }3 K. w3 N; h
( c% Q+ n8 }* K& f! M4 O) B不仅仅stm32有这种配置,实际上,这两种已经广泛应用在很多场合。
+ E% V, m7 c' O- E, |. D" b1 p8 }4 q0 M
推挽,又叫做推拉,是个很形象的名字,一般是指两个三极管(MOS管)分别受两互补信号(或者一个信号,但是用互补对管)的控制,总是在一个三极管导通的时候另一个截止,这样的电路被称为推挽式(互补式):, Q/ n) z0 A. E4 J
  ?$ T( Q  S* O5 l" P* Y1 W
1346657973_9578.png
% b6 s4 g4 I& m; g3 T1 [
这种电路在放大中通常被用作输出级,在STM32中,推挽配置就是这种,如图:
- h5 V* {' ]$ N& u, [6 ]6 S0 X% J, j# Y) o. ]8 l
1346657791_8272.jpg

; g8 o. A0 P: f! E9 k1 Q在相应位置1时,P-MOS导,通N-MOS截止,输出电压为VDD;在相应位置0时,N-MOS导通,P-MOS截止,输出电压为VSS,这就是所谓的推挽。是比较简单的。
$ ~5 S8 s' L& I7 Y* ]
) Z% Y. l+ l4 ]而所谓的开漏(对三极管而言是开集,一样的原理),则要巧妙一些。所谓开漏电路概念中提到的“漏”就是指MOS FET的漏极。同理,开集电路中的“集”就是指三极管的集电极。开漏电路就是指以MOS FET的漏极为输出的电路。一般的用法是会在漏极外部的电路添加上拉电阻。完整的开漏电路应该由开漏器件和开漏上拉电阻组成。
" \/ V6 m0 X# R8 R9 x( [7 v3 b4 ]. o4 s/ s7 Z9 W: y
对于stm32,开漏就是失能了P-MOS,这样,当相应位置1时,引脚实际上是处在了浮空的状态,而通过外接的上拉电阻,将其拉高。$ X3 q0 f. L. v/ f8 g$ P, [
4 H0 V' Z, Z5 [! Q+ i
这么做有如下的好处:! [5 y8 |  n- r, c# C% e& [3 s9 V

$ m: @, Z0 q9 _6 \1、可以将多个开漏输出的引脚,连接到一条线上。形成“与逻辑”关系。当多个引脚任意一个变低后,开漏线上的逻辑就为0了。这也是I2C,SMBus等总线判断总线占用状态的原理。% ~6 x$ F) c2 X3 o" J$ E
2、 可以利用改变上拉电源的电压,改变传输电平。这样我们就可以用低电平逻辑控制输出高电平逻辑了。想想当初认为stm32输出3.3v电压带不动IRF540,就直接断定要重新选型,是错误的想法,只要将推挽输出变为开漏,再加上上拉到5v的电阻,就能解决这个问题。  G" m- ]1 t7 b3 P# q- n

; \5 o/ \5 R% V% J顺便一提,上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小。反之亦然。
% T, O7 e# y+ A6 [5 [# }& }8 ~; A7 c+ ^4 C7 G/ o- j

1 l1 x  m8 i: W" G9 {
赞 收藏 评论0 发布时间:2021-11-29 22:20

举报

0个回答

所属标签

相似技术帖

官网相关资源

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