STMCU小助手
发布时间:2022-3-24 23:38
|
1 GPIO简介7 B3 c, Z. e, Z' N- h {9 W+ o- z GPIO,即通用I/O(输入/输出)端口,是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 ' }+ x( A% K7 G# N2 e, y- m STM32F407有7组IO。分别为GPIOA~GPIOG,每组IO有16个IO口,共有112个IO口 通常称为 PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。 并且F4系列是基于Cortex-M4内核 # {1 w$ b) F) |5 ~ 4 t' q6 }( w+ K8 t' V GPIO的复用:2 q2 g0 s- y7 P: ~% g ( _+ }0 B( F9 p, _% @9 m/ v( `( i# X STM32F4 有很多的内置外设,这些外设的外部引脚都是与 GPIO 共用的。也就是说,一个引脚可以有很多作用,但是默认为IO口,如果想使用一个 GPIO内置外设的功能引脚,就需要GPIO的复用,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。 比如说串口 就是GPIO复用为串口 : ?/ x2 A4 X# _% ?( y 2 GPIO的工作模式4 {# L9 X! ?6 n$ T! X' u 1、4种输入模式 (1)GPIO_Mode_IN_FLOATING 浮空输入 (2)GPIO_Mode_IPU 上拉输入 (3)GPIO_Mode_IPD 下拉输入& r- s- Q( z# L B$ ^ (4)GPIO_Mode_AIN 模拟输入% m; E5 c) ?8 \3 g: c- b _ . t7 x8 h' Q* _! X6 a 2、4种输出模式 (5)GPIO_Mode_Out_OD 开漏输出(带上拉或者下拉)4 e8 N9 a$ O- _! w( ?7 \ (6)GPIO_Mode_AF_OD 复用开漏输出(带上拉或者下拉) (7)GPIO_Mode_Out_PP 推挽输出(带上拉或者下拉) (8)GPIO_Mode_AF_PP 复用推挽输出(带上拉或者下拉)7 o9 N$ ?8 b' b' I* U+ r6 S6 Q, E 3、4种最大输出速度$ z! _% _/ n8 e" V( X (1)2MHZ (低速) (2)25MHZ (中速)7 }' y3 R7 `0 w5 h$ W (3)50MHZ (快速) (4)100MHZ (高速) ; c- A! T" t5 p- o 关于他们的定义,都在 stm32f4xx_gpio.h 中,都为结构体形式的定义 3 GPIO框图剖析4 y+ @5 {" M- D6 I7 R @0 s2 R/ f# R5 d0 V- o0 V! s
我们所用到的每一个GPIO其内部结构都是这样,分别对应着GPIO的八种模式 这里我们简单的介绍下:% }, A3 L5 D% K! q8 e. x; o1 a 1 n% s( z$ ?& a4 n3 O% H 保护二极管: IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁 - h; P. z U! T0 M 上拉、下拉电阻:控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平 TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,模拟信号转化为0和1的数字信号 也就是高低电平 并且是TTL电平协议 这也是为什么STM32是TTL电平协议的原因 P-MOS管和N-MOS管:信号由P-MOS管和N-MOS管,依据两个MOS管的工作方式,使得GPIO具有“推挽输出”和“开漏输出”的模式 P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭5 Q5 N' \$ I" h( u1 N 注: VDD_FT 代表IO口,兼容3.3V和5V,如果没有标注“FT”,就代表着不兼容5V ) z8 _: _% {) l! b3 r$ o" W3 X$ i7 h 在芯片数据手册的引脚定义中,会看到有“I/O电平”一列 有FT即为支持5V0 F9 f, N% k7 l$ j0 n 3 E9 Q& r0 f) i! |% v. D9 u6 H
4 GPIO的八种工作模式剖析: 浮空输入模式 9 V& B) M( W* ]* I. k
2 B4 K) r) f3 a2 S* ]4 B' b 浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。MCU直接读取I/O口电平,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。 (接用电压表测量其引脚电压为1点几伏,这是个不确定值) 以用来做KEY识别 - ?# F6 y7 H8 O 上拉输入模式
IO内部接上拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平 如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平1 Q0 y# y3 ~" n- w! ` STM32的内部上拉是"弱上拉",即通过此上拉输出的电流是很弱的,如要求大电流还是需要外部上拉。+ U8 W4 S& c: a 下拉输入模式
- `( S- K2 m+ _' C8 x IO内部接下拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平 如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平( t5 w7 g# D6 Y ; ^8 S9 E$ Y3 I& {& O- d# T 模拟输入模式 : _5 e }4 A# L! C- K( Z7 a8 c
当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态' c& e5 u4 x0 x: s, L- s# M ! n0 I. w1 ~+ N& ~5 |" p 当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出 除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式,( ~( v% O1 T0 p. \ 8 E: n; I! L( R: u: g9 a: A 开漏输出模式(带上拉或者下拉)
6 T+ G8 ]0 u/ u- i0 K& h1 ] 1 o1 U% E+ {+ ]$ {# w1 P( o: P5 Q' M8 O6 g 在开漏输出模式时,只有N-MOS管工作,如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1时,高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时I/O端口的电平就不会由输出的高电平决定,而是由I/O端口外部的上拉或者下拉决定 如果没有上拉或者下拉 IO口就处于悬空状态9 f0 L5 C" G/ i 并且此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。,I/O口的电平不一定是输出的电平 ( A4 x4 Z4 u' ^$ U% j. T3 n% h# I7 j , q; \& L6 T) ` 推挽输出模式(带上拉或者下拉)9 g5 T' M2 @- L- T
# H" C# C/ o0 w" k& R: C 在推挽输出模式时,N-MOS管和P-MOS管都工作,如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平,若控制输出为1 高电平,则P-MOS管导通N-MOS管关闭,使输出高电平,I/O端口的电平就是高电平, 外部上拉和下拉的作用是控制在没有输出时IO口电平 此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平一定是输出的电平 & o5 m) I: t# o7 E * i8 X5 ?( }: l' D, u 复用开漏输出(带上拉或者下拉)
GPIO复用为其他外设,输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变 其他与开漏输出功能相同 4 V/ y! Z8 w; B% Y( d: r 复用推挽输出(带上拉或者下拉) $ a) [5 r! _' _5 X: X' I
3 o' `3 x b6 K* J# s GPIO复用为其他外设(如 I2C),输出数据寄存器GPIOx_ODR无效; 输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态 除了输出信号的来源改变 其他与开漏输出功能相同 1 l# f8 E6 {, H$ P 开漏输出和推挽输出的区别:. |; q2 s! x5 i* [+ p& ?* D' K 0 b% X/ R. ?6 v+ q! D/ H 推挽输出: 可以输出强高低电平,连接数字器件 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止. ! q: q0 W- k9 S/ h2 P& s% O 开漏输出: t6 a3 ~" f- D- E/ }( E 可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 需要外接上拉电阻,才能实现输出高电平 合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内); 5 [8 E4 _% \5 y2 `5 t, B 在使用任何一种开漏模式时,都需要接上拉电阻,否则只能输出低电平* L6 n' w) H6 X7 Q" F+ L- W ! W6 q. x! P9 _
推挽输出电路: 其中IN端输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当IN端输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平 ! ?0 L1 }0 Z! a, S5 _1 k 开漏输出电路:IN端输出低电平时,三极管导通,使输出接地,IN端输出高电平时,三极管截止,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须接上拉电阻, 在STM32中选用IO模式: - L+ V& L+ A) }. _+ H v b 上拉输入、下拉输入可以用来检测外部信号;例如,按键等; 模拟输入 ——应用ADC模拟输入,或者低功耗下省电- P+ N% g5 j" T0 D2 W& k, w. m3 `; ^ 开漏输出一般应用在I2C、SMBUS通讯等需要"线与"功能的总线电路中。8 ?4 I( e2 }, o. d 推挽输出模式一般应用在输出电平为0和3.3伏而且需要高速切换开关状态的场合。在STM32的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。8 Y o0 ^* O3 T$ q* l 复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)% f1 V- q: \: e2 d1 O+ x 复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS) F4系列与F1系列区别:5 g6 Z* C/ Q$ f( J0 ~ 本质上的区别是F4系列采用了Cortex-M4内核 而F1系列采用Cortex-M3内核+ d% B+ M4 E1 F3 N i F1系列(M3)IO口基本结构:; E+ P) B& @: A: x % [) d* C) B3 W& ~0 ]
F4系列(M4)IO口基本结构:7 Z3 U4 B" L7 U- ^* C: A& I
F4系列设计的更加高级与人性化,他将外部上下拉电阻转移到了输出/输入驱动器外部,使得输出模式下也可以实现内部上拉与下拉,方便了用户的使用,增加了灵活性. N3 O {- q" E4 X( j2 N) O# k9 [ GPIO的初始化(F4) 这里我们以初始化LED为例) m, D; B6 T9 @# ~7 e 1.定义一个 GPIO_InitTypeDef 类型的结构体) A! n4 n: [7 ~% I, c4 H# E. ~ & p- H9 N$ h% U
一共有5个参数/ S4 a w2 B! U
$ i6 L! T* u5 }5 u- } 2开启 LED 相关的 GPIO 外设时钟 ' L2 x3 I6 Y0 ]3 e( N
Q:为什么要设置时钟?1 n: n% s1 X0 m" H% h4 l 任何外设都需要时钟,51单片机,stm32,430等等,因为寄存器是由D触发器组成的,往触发器里面写东西,前提条件是有时钟输入。stm32是低功耗,他将所有的门都默认设置为disable(不使能),在你需要用哪个门的时候,开哪个门就可以,也就是说用到什么外设,只要打开对应外设的时钟就可以, 其他的没用到的可以还是disable(不使能),这样耗能就会减少。! j G5 K$ q) D Q:为什么 STM32 要有多个时钟源呢?1 J$ N' s4 Y" ~+ A$ j( J' x * z# }0 U' j* T3 Z5 Q' A 因为首 先 STM32 本身非常复杂,外设非常的多,但是并不是所有外设都需要系统时钟这么高的频率, 比如看门狗以及 RTC 只需要几十 k 的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁 干扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。/ ^, ~ d( X& u& d9 t 而相对应的外设功能所使用的时钟 在stm32f4xx.h 中即可查看到 RCC_AHB1; @9 C! B* H7 I e8 I; \
( i; ^$ `4 h) ?0 t1 w RCC_APB18 a- a& n( n0 ^% w; E0 }
3选择要控制的 GPIO 引脚& s8 ^* k% D5 f; B2 X* k- m
可选引脚为0-15 一组IO口有16个引脚% S( B8 {" W& Q: | 2 s+ p. L7 _: S! c
( ]# m5 p* q! G- n3 C 4设置所选引脚的模式6 c$ k0 M6 d1 U4 N
引脚的模式共有四种,分别为输入,输出,复用,和模拟模式* L p8 s8 g: y' n: T1 Z9 l
5 设定所选引脚的输出类型
输出模式有两种:推挽输出和开漏输出
& Z& d( V) S: P% ?7 w 只有输出模式才需要配置,输入模式下不需要配置) d0 [8 g, b' T7 L5 s7 G 6 Y8 U( D9 H8 }9 Q( u! o 6 设定所选管脚的速度 " j% {: J+ ?5 [( x
7 设定所选管脚的上拉与下拉
可设置为:上拉,下拉,与浮空 9 C9 e( x) J I6 F& I0 g9 N/ R
8 |1 V/ I2 V% `7 E: w! |; E 8初始化GPIO
- v3 f$ Z$ E4 k! j0 W9 f 6 g. w/ X) a0 x8 _- w$ K1 h+ A GPIO的初始化(F1)4 X. b5 x, _; d F4的初始化相较于F1系列有了很大的改变,在配置F1系列时,结构体只有三个参数 GPIO_InitTypeDef 类型的结构体* B' v( K3 `! P& I ; R6 g) {- P0 E
所选管脚的速度* _* E! Q+ j9 _$ y# L$ Y- B 1 K5 ^, K" a! p/ k
所选管脚的8种模式: R- G, Z3 n# D( R, T a/ S Z
: j3 d J% K- a3 W o 区别:" v( |* u" R5 p6 f) ?$ i + V, ~5 M7 N5 R- Q4 d( t$ g! \ F1(M-3)系列管脚速度只有三种模式 并且管脚的模式配置八种模式全部都在一起定义,直接设置即可# X0 a2 Q: n2 ^0 `- S 4 x- k. M7 g4 ] 总归还是大同小异,不做过多介绍,看下下方配置即可
' W% P4 e7 b X1 z, ?8 R3 d* [ |
【经验分享】STM32语音识别的智能蓝牙音箱(源程序+原理图+PCB+设计说明书+PPT)
想找个ST芯片
[GPIO] 使用新型抽象开始C++嵌入式编程,从GPIO开始
技术手册stm32f1xx中的一个小问题
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
微信公众号
手机版