|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 hunterccc 于 2021-9-16 11:28 编辑 : ]$ f9 |/ t% q( m5 b0 B9 y
8 A4 r) L. Q" P4 y1. GPIO简介
' \' X8 l' a2 i: D5 h1 IGPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。最简单的helloworld级别的例子: 将GPIO引脚接到LED灯,通过控制引脚的输出高、低电平试下开关控制LED;将按键接到GPIO引脚,通过读取GPIO引脚区分按键是按下还是松开。
$ F+ M1 N0 d9 i1 `/ C) \; R# L W; I) f! u
接下来干嘛?肯定是上那副经典的GPIO内部结构图了:
+ c% @6 W- E, j4 h6 N6 u8 _* w4 K+ }+ T* I) B
4 U6 W+ K x0 t; ]- g' \
+ `4 i: Q. k" J3 g% I2 ^" s
1.1 保护二极管) E1 e# q+ g7 v1 I' {- I
IO引脚上下两边两个二极管用于防止引脚外部过高/过低的电压输入,当引脚电压高于VDD时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。# z8 \! T+ _, `3 z
7 {) v2 x" W3 |' u9 y& ?2 Q8 V
1.2 P-MOS管和N-MOS管
" C, \; N4 c* H# s+ B3 h' D# M输出模式的GPIO,由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这两个MOS管接管电路的输入信号是由GPIO的输出数据寄存器GPIOx_ODR提供的,也就是我们可以通过编程修改GPIOx_ODR寄存器的值从而影响该单元电路的输出。" U i# }' m0 w) p! H" W6 ~
常用的还用置位/复位寄存器GPIOx_BSRR和复位寄存器GPIOx_BRR,设置这两个寄存器后也能影响GPIOx_ODR,进而影响单元电路输出。
4 Y, {' t) A$ L8 X! G+ f除此,还有复用功能输出,意思是指STM32的其它片上外设对GPIO引脚进行控制,此时该引脚作为外设功能的一部分。片上外设数据信号作为双MOS管接管的输入,进而输出到GPIO引脚中。例如USART串口通讯,要用到某个GPIO 引脚作为通讯发送引脚,就可以把该GPIO 引脚配置成USART 串口复用功能,由串口外设控制该引脚,发送数据。
* y [& `& I$ r% T; L0 g' I- a1 k, }6 E! S1 v" h) X
1.3 TTL肖特基触发器7 E& t, p `2 z; ?$ N2 l
输入模式的GPIO,GPIO引脚经过内部上/下拉电阻配置成上/下拉、或者浮空输入,然后连接到触发器。信号经过触发器后,模拟信号转化为0和1的数字信号,然后存储在输入寄存器GPIOx_IDR中,通过读取GPIOx_IDR寄存器就可以知道GPIO的电平状态。
/ U/ C/ ?+ k8 b3 e$ F1 o; G, O同理,与复用功能输出类似,这里也有复用功能输入,GPIO引脚的输入信号会传输到STM32的其他片上外设,由外设去读取该引脚状态。例如使用USART串口通讯,用某个GPIO引脚作为通讯的接收引脚。
: J0 Y# R9 W6 N另外,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。类似的,当GPIO引脚用于DAC模拟电压输出通道时,此时作为“模拟输出”功能,DAC信号输出不经过双MOS管。
& ?: i {' x1 Z/ ~4 P/ u3 E7 D2 Q8 K9 ]2 R$ c% W" `$ T, B6 W2 y+ ~
2. GPIO的工作模式/ g( _' F4 c6 ^3 Y% I8 ~
GPIO的硬件结构,决定了GPIO可以配置成的工作模式有:
$ V# j K& {' F. U) C
; g5 f* }$ x* i1 J% m, K1 K8 itypedef enum
& x- v M$ N9 v" F9 I2 w4 w: \. w{ GPIO_Mode_AIN = 0x0, //模拟输入
" c/ {/ A7 S3 ^* |. F8 L GPIO_Mode_IN_FLOATING = 0x04, //浮空输入
$ Y8 |& K* ?% O. C, Z8 \* B5 @8 W GPIO_Mode_IPD = 0x28, //下拉输入/ K1 w6 _$ V+ t) o
GPIO_Mode_IPU = 0x48, //上拉输入
$ p2 H& T% x+ E( ^/ E4 V GPIO_Mode_Out_OD = 0x14, //开漏输入
0 j' V& t n5 X9 r; A$ o: Q; ~- w# L3 @2 n/ {3 l% `
GPIO_Mode_Out_PP = 0x10, //推挽输出! k5 @2 H# P: i" m9 ?5 H/ ^
GPIO_Mode_AF_OD = 0x1C, //复用开漏输出
$ }+ f% M: |/ o" e2 p2 K5 e2 q GPIO_Mode_AF_PP = 0x18 //复用推挽输出
. ]" k1 F6 k! X6 n3 [}GPIOMode_TypeDef;
6 a5 c3 F+ }$ J7 q0 \# s. K3 R* v. m
2.1 输入模式(上拉/下拉/浮空/模拟). T. k0 x8 ?0 U6 N0 f
GPIO在输入模式中,肖特基触发器被打开,输出被禁止,通过GPIOx_IDR读取I/O状态。上拉/下拉输入,其默认电平由上拉/下拉决定,浮空输入的电平则是不确定的,完全由外部决定,一般按键就是采用浮空输入;模拟输入用于ADC采样。! V8 P4 D4 x% i1 N/ P$ W
9 P3 a0 e5 h* V% x6 Q6 h+ y. \) Z2.2 输出模式(推挽/开漏)" Q' d/ T8 i& A; @; B! e
GPIO在输出模式中,肖特基触发器同样被打开着的,即输入可用,这样通过输入数据寄存器GPIOx_IDR可以读取到IO实际状态。推挽模式时,双MOS以轮流方式工作,开漏模式下,只有N-MOS管工作。输出寄存器GPIOx_ODR可控制是输出高低电平;输出的速率可配,有2MHz/10MHz/50MHz。频率越高,功耗越大,效率也越高。* L) A, E0 W. j" n0 j5 P) J
7 `% a) e' G" K! V
2.3 复用功能, O7 `0 C5 a4 W. Q6 \2 d9 v
复用功能中,输出输入都使能,可工作与开漏或推挽模式,但是输出信号源于片上外设,输出数据寄存器GPIOx_ODR无效,输入寄存器GPIOx_IDR仍然有效,可通过它获取IO实际状态,片上外设相关寄存器也是通过GPIOx_IDR获取该数据信号。# B7 n+ t3 ^3 t- j8 V6 s Q0 Z
, B7 g; x( s- u) L% @1 A
控制GPIO端口工作模式寄存器是GPIOx_CRL和GPIOx_CRH,它们都是32位的寄存器,分别管控GPIO的低8位IO和高8位IO。另外涉及到的寄存器还有:1 z" w: K% q3 f- z K. n* K) Z4 p
GPIOx_ODR: 设置输出数据
# P+ `! h) r" r A2 PGPIOx_IDR:读取输入数据0 @& r6 Y8 j/ T/ c6 v5 t' i& [
GPIOx_BSRR:置1/清零GPIO的相应引脚6 L, \2 O3 a Q
GPIOx_BRR:清零GPIO的相应引脚4 V. v8 \& }) M3 V3 w3 \
这些寄存器的设置参照STM32中文参考手册即可,很简单,不赘述。另外,要让GPIO正常工作,记得打开GPIO的时钟。
' ?# L8 g% m+ v2 }. q5 f* r7 s {+ M0 L% o
; e6 v) ^) x; k) |0 L
|
|