|

第一节 IO简介8 N+ I) ~& b2 [3 ^! I' r; s
GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。每个GPIO内部都有这样的一个电路结构:; O P3 u) `! O
cezmbga0lhm64047186852.png
7 y7 c0 A" r& }& o
; |& Z7 w S/ _
这边的电路图稍微提一下:: y( X E* S' ]
保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。
1 A- c. c% [2 qP-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。
: H. m" _1 P8 I- TQ-TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。 2 a1 i1 V% i+ _. l& y
这里需要注意的是,在查看数据手册中,会看到有“FT”一列,这代表着这个GPIO口时兼容3.3V和5V的;如果没有标注“FT”,就代表着不兼容5V。" y* O7 t" E; `# x* X" g
& h$ s* H+ {$ Z" U: b; e* D, Q
GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度。每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。下面将具体介绍GPIO的这八种工作方式。
3 f# {! G5 h, H0 [) {, V+ I; o, q
' w7 i; J# g; D& s4 ]- s. }" j1,浮空输入模式 浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。
& ], D7 h, L! n, @% B* g2 @9 Q
! M& r# L& \$ U; q& m5 O8 m- U+ r2,上拉输入模式 ( U& O3 Y2 U" }( B% c9 W
hbar3elrgul64047186952.png
+ a( I/ \7 m" @4 @上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。
. L( }# K. l% }# o6 p: e- \3,下拉输入模式% i; F5 y/ N6 Y( e! D5 g
r2hwlvmalbe64047187052.png
+ }5 d4 F& i4 A5 P3 l3 P
下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。 : L4 o5 X! a2 P9 M% }7 f4 R
% I8 {7 ` W- f% N, Y! v4,模拟输入模式
& ]4 P# O: V1 F1 i/ _
mzbbi4n44ex64047187152.png
3 L1 b: j0 m+ ]模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。. `! S6 G! J" R m9 Y2 i8 ^1 D
$ @# v0 L- b( \0 C) F
5,开漏输出模式6 g6 N: ^8 L, c: y
zd5ixfqebmq64047187252.png
- }* s9 s( n# J; `5 M开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。
( ], C2 T* J/ R+ ? Y2 I9 F ! Y: ~7 w7 U* r9 \1 ?" @
6,开漏复用输出模式" \' e+ W) I Z; K8 H/ `
ao3a3u4wfkr64047187352.png
8 j# y* @( _7 c c8 z' o开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
5 i: s! V; ~. z2 @ . U4 Q7 [. h: R* @. M
7,推挽输出模式
" F0 J* t# c" C0 M! C4 u- R
bgoksw5vx1k64047187452.png
$ V5 W" k# f6 n' i/ s) p
推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经P-MOS管和N-MOS管,最终输出到I/O端口。这里要注意P-MOS管和N-MOS管,当设置输出的值为高电平的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定:高电平;当设置输出的值为低电平的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定:低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。
' s, t1 @& o1 I. G ; ^$ M3 q9 H; p5 `
8,推挽复用输出模式
1 U; [. p7 x/ q: d( L5 k+ E8 S: L/ \
sswvqvlp1zi64047187552.png
/ r1 X8 ?8 V0 B4 s1 Y) Z推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。
% M( E' x' f4 ^! [! U# f9 y第二节 硬件解读
! `: m6 y" E& u5 {& n) O) c 先看看原理图:0 ]" g# F! E% {. G
f4arhfjfb0264047187653.png
& g) K# y+ V) Q3 V A- b开发板上面一共有3颗可编程LED,控制的引脚分别是PB2,PB5和PB12,LED右侧通过一共限流电阻上拉到3.3V,所有stm32给一个低电平就会点亮LED,反之则熄灭。
$ k Y( O: G+ q# W" q第三节 CubeMX配置
6 q8 D0 s* W4 j 第一步:双击打开STM32CubeMX,如下图,新建项目。【注意:新建项目本教程只介绍一次,以后项目的建立不在重复】 : D% Q0 S1 @6 x7 H
urpx552o2gn64047187753.png
# {( P/ j) \8 T) ]' n% L7 U
第二步:在英文状态下搜索芯片:STM32WLE5CCU6【注意:尽可能靠近该芯片,不一定是STM32WLE5CCU6,不同STM32CubeMX版本,芯片的名字不一样的】选后选择对应的芯片即可。
* }+ c$ w4 Q: Z4 r% H, G
1x1mmy2b4pc64047187853.png
% X4 L d! X3 _& B- ]
第三步:在1处查看芯片的视图,选择2处后可以看见芯片所有的功能,选择3处的RCC时钟,在4处配置外部高速时钟,一切配置完了之后,会在5处看见GPIO变绿色。,如下图。【注意:本教程晶振配置仅配置一遍,后续教程将不再重复】 4 U) m8 i8 s' E6 R* G! ?
3aonp1d5r5264047187953.png
+ D- [+ A8 [. A; u
第四步:在1处切换到时钟树页面,在2处配置外部晶振大小,蓝桥杯物联网开发板外接高速晶振为32MHZ,所以这里配置成32MZH,在3处配置HCLK时钟为最大时钟,最大时钟为48MHZ。如下图。【注意:本教程时钟树配置仅配置一遍,后续教程将不再重复】. O; H. r1 d+ E7 F1 w' O+ n- J
v1b3t0hf4nu64047188053.png
* M8 s" ~6 y, j% b5 D5 [ 4 d) [3 C7 R/ i
gywyut2hfrj64047188153.png
n4 V: G& T' O+ y第五步:配置下载器,在3处选择DEBUG,在4处选择JTAG模式,之后就可以看见5处和6处的GPIO变绿色了。【注意:本教程下载器配置仅配置一遍,后续教程将不再重复】9 o1 K8 }5 h7 e; z' l
t0sdw01lhmr64047188254.png
6 ^$ p+ ^1 w, @ h第六步:配置STM32的PB2引脚为GPIO_Output,如下图: ; `5 [6 q p; _% T2 a Z! x! |% n$ \
qkaytxhj31b64047188354.png
+ R' Q( i5 _0 i" c4 b# ]7 [9 X
第七步:以同样配置STM32的PB5和PB12引脚为GPIO_Output,如下图:
& B, Y6 K" o$ j, ?
otfa1hh3xsl64047188454.png
* E0 f5 A5 U% M1 U |) F, p第八步:在1处可以看见选中GPIO的配置,在2处看见GPIO的输入输出的引脚,在3处选择PB2,在4处配置GPIO的默认高低电平,因为低电平LED亮,我们默认低电平,在5处配置为上拉,和硬件配置保持一致,在6处配置用户标签,便于管理。如下图: * {. `0 X% |9 Z! c9 V7 L. B5 q
dcltdnxlaix64047188554.png
( w* F, R/ m; T: P' S% V0 ?- r2 @5 y9 }
, Z0 W! v J' J' _8 M* W$ o其中:具体配置信息如下:2 D' U0 r# j* \1 T3 D+ [$ r! g$ W
$ t0 q$ j! ]( X# g# F# j J) f ZGPIO output leve:表示上电的默认电平,可配置高(High)或者低(Low);
+ v1 t# O0 J; ]0 x6 l0 b8 e
! G: n6 ], L6 [) `; EGPIO mode:表示输出模式,可为Output Push Pull(推挽输出)或Output Open Drain(开漏输出);
" [6 o1 _. |( ?9 ?$ ~ - @: N, e" U. h: f L& v! }: v
GPIO Pull-up/Pull-down:表示是否上下拉,可配置为上拉(Pull-up)或者下拉(Pull-down)或不上拉也不下拉(No Pull-up and no Pull-down);
+ \+ b2 l9 t. K + |( M% v/ y% }# t
Maximum output speed:表示输出速度,可配置为低速(Low)或者中速(Medium)或高速(High)或超高速(Very High);
3 I/ R ^+ Q. h) Z$ O+ w+ \ ( o9 n4 {. q3 v9 v! o# e
User Label:表示用户标签,可修改IO口名称,比如可写入LED,把IO口名称变为LED;
7 d: l2 ?6 S1 q' C) h
! |2 c2 O- n' P: Q" Y9 k3 \0 k8 N# q4 ~第九步:和PB2一样配置其他2个GPIO。
- E$ B# b C j/ _' S# T' u. |第十步:选择项目信息,如下配置:2处是项目的名字;3处是项目的路径;4处是编译器;5处是编译器版本。【注意:项目路径不能包含中文等其他非法字符;编译器一定要选择MDK-ARM;编译器版本要选择最新的,本教程为v5.37。后续教程将不在重复本步操作】 q* n/ H9 X; M8 w4 m' C h
qoswz1sygyv64047188654.png
- k% S3 I& ]& T# V- [' z! ?1 [
第十一步:如下图,将3,4处的按钮勾选,点击5处,生成Keil工程。【注意:后续教程将不在重复本步操作】
. Z8 \& ^3 t! t9 W# t, Y
dvealf0fqm164047188754.png
/ b4 K7 ~: ^; J) y" S
. Z, ?) d5 N: {, x, Z7 t 3 ^& k4 f3 ^. o& s) r
8 w1 y% s4 O1 G2 ^第十二步:点击上步的5处之后,会有一个对话框,意思分别是:打开项目文件夹位置;打开项目;关闭本窗口。【注意:这里灵活处理,打开文件夹和项目都可以。后续教程将不在重复本步操作】( n$ t3 a7 T9 v/ Q
# }1 ?: u; |) h" l' ]
( N! p5 @# w9 Z$ J6 S6 N2 b* A
第四节 MDK代码
( E% d _0 ~7 [ 第一步,编译代码,检查STM32CubeMX生成的代码是否正常。如下图,点击1处编译,之后在2处可以看见一个警告,是因为MDK版本太新,高于CubeMX选择的V5.37,导致编译器不一样,但是不影响程序运行。【注意:后续教程将不在重复本步操作】# h3 {; I: k5 u" B% T

) i0 x; w9 m% A3 d+ c1 I: B第二步:配置下载器,这一步很多步骤,希望大家仔细一点,一步一步来。【注意:不要忘记点击“OK”,后续教程将不在重复本步操作】
! \8 l/ h% Y" c . b, c+ k# z1 X) S
第三步:新建.h文件。在“项目名/Core/Inc”中新建一个“zsdz.h”的文件。【注意:后续教程将不在重复本步操作】
% b- i2 X7 a3 b0 s/ j t 9 ?4 @$ n, l; ?
第四步:新建.c文件。在“项目名/Core/Src”中新建一个“zsdz.c”的文件。【注意:后续教程将不在重复本步操作】
9 p; d9 f9 }2 _; w7 L) C + y7 k# a/ ]: R3 X, j" U
第五步:添加“zsdz.c”文件。点击1处,可以看见项目的所有的文件,点击2,3处,准备添加“zsdz.c”文件,但是发现没有“zsdz.c”文件,如下图:需要返回到上一层文件目录中,点击4处。【注意:后续教程将不在重复本步操作】 S F, j, @, [1 e! A

. d( @, v' Q) Y4 \& _如下图:虽然没有发现“zsdz.c”文件,但是我们看见了Core文件夹,还记得我们的“zsdz.c”文件保存在哪吗?在“项目名/Core/Src”中,所以我们进入到“/Core/Src”,找到“zsdz.c”文件即可。【注意:后续教程将不在重复本步操作】 9 e6 k) y# |# f& m7 t

7 q6 q& X8 O) p* ~8 e$ K
- v, M* h6 K& H9 c# S0 y
6 x& x) u4 O7 u. r. }$ j第六步:如下图,代表添加成功。【注意:后续教程将不在重复本步操作】 & s, X( @( t( V4 `9 d8 `: C+ y
, N7 s/ ~ y* N; b- W" Z
第七步:如下,点击1处,可以看见MDK中的“zsdz.c”文件。【注意:如果利用STM32CubeMX生成MDK项目,“zsdz.c”文件可能会从MDK项目中移除,请重新添加】
- n A( R% ^) R9 T8 V+ I
9 y- O8 Y# x: ]+ A, |) V第八步:编写“zsdz.c”文件的代码,如下:【注意:后续教程将不在重复本步操作】
1 a; ?# X% T% Y$ F7 G
' u# c% E- E" g第九步:进入到“zsdz.h”文件,右键,选择“Go to Headerfile‘zsdz.h’”。【注意:后续教程将不在重复本步操作】+ t; V n* O9 z6 z' H. w

1 I+ e o; x, U" h+ c& e第十步:编写“Zsdz.h”文件的代码,如下:【注意:后续教程将不在重复本步操作】
; U1 I/ B. o, X' h3 u4 t4 _) s + d8 `% D- r" c" ?6 }2 Q, S K
第十一步:在Main中添加“zsdz.h文件”,如下:【注意:只可以添加在“USER CODE BEGIN”和“USER CODE BEGINEND”之间,否则等下次利用STM32CubeMX生成MDK项目时,不在“USER CODE BEGIN”和“USER CODE END”之间的代码会被覆盖】 2 m3 G/ ] Y8 p7 b8 A

$ \, }3 c g" k! g% ?第十二步:编写LED的函数模板,具体如下:【注意:不要忘记声明gpio.c文件。注意:后续教程将不在重复本步操作】
: b7 R* T) s0 k9 M3 s, z$ P. }2 m' i8 r ! p/ o4 U1 U3 f8 Z
第十三步:以上就是LED所有的封装函数了,我们在“zsdz.h”文件中声明他们,如下图:【注意:后续教程将不在重复本步操作】
: W" S( l1 G# ^" _* v* V
9 q# Z2 |0 X$ z% z* u5 T3 u第十四步:现在随便在main函数中写几个,看看效果。
. p" d$ |( E, B0 S
& }! H( Y( ~4 y, b$ A# o! i第十五步:编译检查代码并下载。点击1处编译代码,之后在2处可以看见0错误0警告。代码没有问题之后,点击3处下载代码,在4处看见Flash Load finished at xxxx,就证明代码下载成功。【注意:后续教程将不在重复本步操作】
' B% {2 Q m3 W" e$ x7 Q1 ~
8 G+ H3 P. ^7 g, S) u, h* |
, i8 i) R: g) l& p第五节 实验现象- O. c6 D# t" K; J; V# k
注意:
9 r2 Y; Q" Z! ^+ S. { k% O1,请用USB线连接电脑与开发板。
9 P, [5 H% I' y8 o2,请选择A开发板。% l/ }5 Q7 r' J! w1 Q
现象:AL2以400ms为间隔闪烁。
8 O: m8 _4 x9 a来源:撞上电子微信公众号, l, ~3 R* ]# h- U+ Y+ P# ^
版权:东莞市东城墨竹公子电子工作室' [8 i7 @$ j# C/ z3 C
日期:2024.11.03
( v' x2 R) {4 {: g# ?7 ]第六节 课后作业: ?2 s* T* _4 g0 O
请让AL1长亮,AL2以500ms为间隔闪烁,AL3以1000ms为间隔闪烁。 |
|