1 GPIO简介 GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。) ]$ C5 L$ n/ S6 j " A5 U8 D" o" n2 x6 C- I5 p @ D6 N " e1 d" n: [; _/ N. u STM32F407有7组IO。分别为GPIOA~GPIOG,每组IO有16个IO口,共有112个IO口 通常称为 PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。 并且F4系列是基于Cortex-M4内核 $ h+ u2 }3 r$ H& w% L 4 J- A _' g( Q $ U( s" ]9 H. W0 t( f6 u p GPIO的复用:- T, Y9 u/ ?+ ~7 H 9 n8 v$ S6 L/ }; \/ D STM32F4 有很多的内置外设,这些外设的外部引脚都是与 GPIO 共用的。也就是说,一个引脚可以有很多作用,但是默认为IO口,如果想使用一个 GPIO内置外设的功能引脚,就需要GPIO的复用,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。 比如说串口 就是GPIO复用为串口 2 GPIO的工作模式 1、4种输入模式! Q. u& g+ y+ R+ z e (1)GPIO_Mode_IN_FLOATING 浮空输入 (2)GPIO_Mode_IPU 上拉输入 (3)GPIO_Mode_IPD 下拉输入8 P# }) d5 j2 n (4)GPIO_Mode_AIN 模拟输入3 | a* ^$ A7 L2 h; s. K 2 R: g, j- D6 A' y ( K7 |( w2 b0 k, E/ Z 2、4种输出模式 1 m+ W b2 ^: j# D/ R ; U/ \3 ]7 _* }# e: p4 t: b (5)GPIO_Mode_Out_OD 开漏输出(带上拉或者下拉)) C* l, J* @. M" r: I. c5 a (6)GPIO_Mode_AF_OD 复用开漏输出(带上拉或者下拉) (7)GPIO_Mode_Out_PP 推挽输出(带上拉或者下拉)% A6 H/ S9 K( _/ ]1 Z: ]$ N$ o (8)GPIO_Mode_AF_PP 复用推挽输出(带上拉或者下拉) 3、4种最大输出速度/ q, Y, x5 ~6 E+ `; y2 J (1)2MHZ (低速) (2)25MHZ (中速)! Z. r8 d6 w1 J+ l& H3 b% d" j0 e (3)50MHZ (快速) (4)100MHZ (高速) 关于他们的定义,都在 stm32f4xx_gpio.h 中,都为结构体形式的定义 3 GPIO框图剖析 我们所用到的每一个GPIO其内部结构都是这样,分别对应着GPIO的八种模式 这里我们简单的介绍下:) R/ T: }; ] j; H 保护二极管: IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁 上拉、下拉电阻:控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平, f5 T: p7 ?+ Z9 e; l& d TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,模拟信号转化为0和1的数字信号 也就是高低电平 并且是TTL电平协议 这也是为什么STM32是TTL电平协议的原因 P-MOS管和N-MOS管:信号由P-MOS管和N-MOS管,依据两个MOS管的工作方式,使得GPIO具有“推挽输出”和“开漏输出”的模式 P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭$ _7 x. q) I; `5 f) w" F 注: VDD_FT 代表IO口,兼容3.3V和5V,如果没有标注“FT”,就代表着不兼容5V ) `3 A1 w% W& O0 P; p2 p 在芯片数据手册的引脚定义中,会看到有“I/O电平”一列 有FT即为支持5V; K# n9 t: X' \: a- b2 x 4 GPIO的八种工作模式剖析:) \4 c8 V6 _ ~6 d& M2 I9 W! R. e 浮空输入模式 浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。MCU直接读取I/O口电平,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。 (接用电压表测量其引脚电压为1点几伏,这是个不确定值) 以用来做KEY识别 : F# F$ |2 O0 r+ [6 p7 A 上拉输入模式 IO内部接上拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平 如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平# x$ E! {2 S! T/ f% d7 }& d' Q F! J4 t- u( Z! A# L9 j1 J STM32的内部上拉是"弱上拉",即通过此上拉输出的电流是很弱的,如要求大电流还是需要外部上拉。) M* e" E- v, t' V; |( U : ~3 ^1 Y- J& S+ S" |2 i 3 O5 S8 \, A6 r [" { 下拉输入模式 IO内部接下拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平 如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平! V; h& j) Q2 X- `( T" F ' W( ]& L9 A: J# u( V( l 模拟输入模式 J. {, f, N( h 当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态 & i* }6 K3 W4 `. f" G 当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出 w G, g3 a: Z. _ , O* j W. W9 u2 {& X8 n3 | 1 {0 M& h0 e+ m% T& G4 w- d 除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式,+ ]# V, H& A5 ^4 }: n & }( P8 J3 E; F5 J+ h& M' N# s 开漏输出模式(带上拉或者下拉)5 E- g% s1 a; ~7 v1 {; _ 在开漏输出模式时,只有N-MOS管工作,如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1时,高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时I/O端口的电平就不会由输出的高电平决定,而是由I/O端口外部的上拉或者下拉决定 如果没有上拉或者下拉 IO口就处于悬空状态- Y4 v9 j& L- ?( Z$ V: w 9 ~/ \8 y3 P$ j! ?+ C: w/ a 并且此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。,I/O口的电平不一定是输出的电平 }$ w: I* t* ]" @# L# f 6 ~) w' w& m0 c0 U; C8 x4 c 推挽输出模式(带上拉或者下拉) 在推挽输出模式时,N-MOS管和P-MOS管都工作,如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1 高电平,则P-MOS管导通N-MOS管关闭,使输出高电平,I/O端口的电平就是高电平, 外部上拉和下拉的作用是控制在没有输出时IO口电平 ) P/ z, J a) u2 x, i: G; g* f 此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平一定是输出的电平 6 T. M+ x5 p! o* |1 j7 y 0 F9 }) A: O7 F o 复用开漏输出(带上拉或者下拉) GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变 其他与开漏输出功能相同 . f) _1 {9 Q0 s& J 复用推挽输出(带上拉或者下拉) GPIO复用为其他外设(如 I2C),输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变 其他与开漏输出功能相同 ' i4 k) s0 I$ \ U* M: D 开漏输出和推挽输出的区别:0 J& r$ |9 d1 \( c% f " ?: _6 x. R+ C: M6 U. q * y" f) w& s8 Z+ p% n3 @* }3 ~ 推挽输出:0 a( i; S, `9 v/ F# P 9 a' U: V. m/ R# L/ _( ~' m, d. d1 P- ^ ; r# B6 Z! B9 S% @ 可以输出强高低电平,连接数字器件 : R G1 V4 b2 C1 y: r 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止.# o( Z) Y0 C4 @4 ?7 R; w/ ~ " r7 P+ @+ U# p1 K; S; k6 v 开漏输出: $ ?* |+ }5 Z b; }" Z% l3 [ 2 ^/ X& r9 u0 k 可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 需要外接上拉电阻,才能实现输出高电平 合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内); 在使用任何一种开漏模式时,都需要接上拉电阻,否则只能输出低电平 推挽输出电路: 其中IN端输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当IN端输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平 5 ^# j# U# { B+ W' J2 \& ` % z+ q, g' x, g- e & j2 {4 ?/ o" B5 [! t! M: e 开漏输出电路:IN端输出低电平时,三极管导通,使输出接地,IN端输出高电平时,三极管截止,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须接上拉电阻, 9 A. ]4 J, W% q! T& l! g. M1 b; W 2 t! u6 N1 r2 r' F8 p$ N) n 在STM32中选用IO模式:6 @ y, V! ~! o$ t3 p4 G, X 8 H1 d" Y0 t f% q5 K/ q( I$ u3 ]* S0 f 上拉输入、下拉输入可以用来检测外部信号;例如,按键等;# Z/ n& v, ^% g! |- X6 l. u% U/ R 模拟输入 ——应用ADC模拟输入,或者低功耗下省电 开漏输出一般应用在I2C、SMBUS通讯等需要"线与"功能的总线电路中。 推挽输出模式一般应用在输出电平为0和3.3伏而且需要高速切换开关状态的场合。在STM32的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。 复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)$ q( n8 h) m4 G1 O( J! P 复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS) F4系列与F1系列区别: 本质上的区别是F4系列采用了Cortex-M4内核 而F1系列采用Cortex-M3内核 ) p. R7 R1 M5 B! u6 U7 X - W; R* Y, Q+ g F1系列(M3)IO口基本结构:: \) H# l" Y4 W( O F4系列(M4)IO口基本结构:6 q F5 o, ~/ Z F4系列设计的更加高级与人性化,他将外部上下拉电阻转移到了输出/输入驱动器外部,使得输出模式下也可以实现内部上拉与下拉,方便了用户的使用,增加了灵活性1 g7 s& q0 Q5 A1 K7 g 8 Q1 Y2 S, }7 g GPIO的初始化(F4) 这里我们以初始化LED为例: Z i `5 Z4 l9 ] 0 q4 m# U L. N+ a# f " h( O3 S( P% H# o 1.定义一个 GPIO_InitTypeDef 类型的结构体
2开启 LED 相关的 GPIO 外设时钟6 s( U2 ?3 I% |5 R
# X8 ]" I2 ]4 R " W- s) X5 ^1 C 任何外设都需要时钟,51单片机,stm32,430等等,因为寄存器是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。stm32是低功耗,他将所有的门都默认设置为disable(不使能),在你需要用哪个门的时候,开哪个门就可以,也就是说用到什么外设,只要打开对应外设的时钟就可以, 其他的没用到的可以还是disable(不使能),这样耗能就会减少。& |8 f3 ~6 H" M6 F f/ ? $ F# C& B0 C* x Q:为什么 STM32 要有多个时钟源呢? ~6 z, \7 i$ m3 \ 因为首 先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率, 比如看门狗以及 RTC 只需要几十 k 的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁 干扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。 4 p- H& |8 f% k1 o/ [- i" V7 G 而相对应的外设功能所使用的时钟 在stm32f4xx.h 中即可查看到) e7 m4 k, P* v# D0 k4 M8 Z( v 7 g$ a) J3 D9 Y2 M ) F9 T8 J: U- B8 B3 t& B" V& W6 b RCC_AHB1/ p! |# U& ]% d/ N b l8 B8 f! t RCC_APB1! {, R* M9 S" d* R 3选择要控制的 GPIO 引脚
4设置所选引脚的模式
5 设定所选引脚的输出类型. a3 ^. |# ]- o9 B( ?4 |7 v; K
只有输出模式才需要配置,输入模式下不需要配置 & B0 _3 |7 a- a0 P, E 6 设定所选管脚的速度0 Z& E/ p4 H a+ C) |* a2 Y+ w
7 设定所选管脚的上拉与下拉
8初始化GPIO
; \3 D* o6 \; X GPIO的初始化(F1) F4的初始化相较于F1系列有了很大的改变,在配置F1系列时,结构体只有三个参数 ! `, o7 p) ^4 ~3 u8 B # q1 L- u4 s, q9 Y) H6 l, a- n ' O& r$ S6 W! Q2 `5 V GPIO_InitTypeDef 类型的结构体9 }5 t7 _ [- q6 B9 G% J! m. z 所选管脚的速度 所选管脚的8种模式 区别:+ V. Q3 b' m8 K# e& x# e! I u F1(M-3)系列管脚速度只有三种模式 并且管脚的模式配置八种模式全部都在一起定义,直接设置即可3 q' {$ f( L5 g8 B. G# M1 n+ x Y - I% t" o) }1 r6 s/ U* L 总归还是大同小异,不做过多介绍,看下下方配置即可$ ?) @: S! L, ^3 k6 l, k+ L5 |
: v5 ~- L8 Z! F) \! ?. L9 ` " `! s; @: ^) ~, L |
STM32固件库分享,超全系列整理
【中文文档】AN3965_STM32F40x和STM32F41x基于串口的IAP
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32F4中文用户手册
基于STM32F407的FreeRTOS阶段性的总结(13)
STM32F400、STM32F402 Cortex-M4超值单片机
基于STM32F407的FreeRTOS获取各任务运行时间及占用情况(4)
基于STM32F407的FreeRTOS任务的挂起与恢复(3)
基于STM32F407的FreeRTOS任务的创建与删除经验分享(2)
基于STM32F407的FreeRTOS环境搭建经验分享(1)