电子产业一站式赋能平台

PCB联盟网

搜索
查看: 107|回复: 0
收起左侧

蓝桥杯的第一个项目,点亮一个LED

[复制链接]

359

主题

364

帖子

2887

积分

三级会员

Rank: 3Rank: 3

积分
2887
发表于 2025-1-2 21:00:00 | 显示全部楼层 |阅读模式
第一节 IO简介
, {3 y: [. T+ }5 O. S# S   GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。每个GPIO内部都有这样的一个电路结构:$ G8 d1 r( m  e, t

cezmbga0lhm64047186852.png

cezmbga0lhm64047186852.png
1 g. L  j4 t  P  [) H0 F

$ m$ A1 k" R  d9 q" L/ K% C- D3 {这边的电路图稍微提一下:+ \: K2 E, q. m1 i8 J8 l, T" n$ g
保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。; e, [6 F8 C8 \
P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。; Y8 Y+ }# D% V
Q-TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“模拟输入”功能,此时信号不再经过触发器进行TTL电平转换。ADC外设要采集到的原始的模拟信号。   
4 V7 R/ }+ G" y6 f3 w9 A这里需要注意的是,在查看数据手册中,会看到有“FT”一列,这代表着这个GPIO口时兼容3.3V和5V的;如果没有标注“FT”,就代表着不兼容5V。
! z; j2 f9 z* t. [6 n' I% o- W           
, A) C7 j2 l; x. f$ f' g" B3 @GPIO支持4种输入模式(浮空输入、上拉输入、下拉输入、模拟输入)和4种输出模式(开漏输出、开漏复用输出、推挽输出、推挽复用输出)。同时,GPIO还支持三种最大翻转速度。每个I/O口可以自由编程,但I/O口寄存器必须按32位字被访问。下面将具体介绍GPIO的这八种工作方式。
9 O6 m4 c) Q! G# y; ]" u7 ~- W( @! A
; \+ ^: [, q# H- K1,浮空输入模式         浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。
1 x$ o% K4 A! X2 b           
( F5 Y% C' F5 @. w2,上拉输入模式  . Q5 v- |0 w9 ?, H0 \% w( x0 P

hbar3elrgul64047186952.png

hbar3elrgul64047186952.png
2 f/ x1 R+ g4 E1 T; N* E8 ~2 p" ]
上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平也还是低电平。       ; S+ d: v3 I6 ^/ e. A! N# ]8 x
3,下拉输入模式% a& D  l# j) k+ |# p" G4 G

r2hwlvmalbe64047187052.png

r2hwlvmalbe64047187052.png
# P4 L& z# _1 b5 t: Y* ^/ S
下拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端的电平也还是高电平。    2 A, B+ ?$ |# O7 ~# M6 N
           
) Q/ y+ X4 z* k$ |5 L+ p2 ^4,模拟输入模式# c5 ?/ H1 x" K* _+ ]' p

mzbbi4n44ex64047187152.png

mzbbi4n44ex64047187152.png

/ J0 c! o! B/ g, w7 O& K  k模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。" `$ L0 q; I! r) |& ^5 B# u
           
' w9 x7 r8 u% [) u5,开漏输出模式9 _2 X$ s* A7 N

zd5ixfqebmq64047187252.png

zd5ixfqebmq64047187252.png

" s; x2 T' o3 a* F开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经N-MOS管,最终输出到I/O端口。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。    ( S# U: l5 A3 u6 N. H
           
" j0 G* c" D) V+ |+ \! W6 k! A, z6,开漏复用输出模式
7 @0 G1 @% I4 p$ O9 O: M

ao3a3u4wfkr64047187352.png

ao3a3u4wfkr64047187352.png
! y5 e4 b! U" v0 G* J1 g. S7 p# }
开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。  {2 U4 s! C! E
           
; b3 P" [$ W" n% l" q7 d! t7,推挽输出模式   
8 `& |+ O4 I. n- S

bgoksw5vx1k64047187452.png

bgoksw5vx1k64047187452.png

9 J+ y% m* u! c1 B4 V) O推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,途经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端口的电平一定是输出的电平。
9 z- l. P0 @* |2 R5 t# T' L           - B& P+ J( y0 z
8,推挽复用输出模式   . e1 [# B3 [- E  v2 w

sswvqvlp1zi64047187552.png

sswvqvlp1zi64047187552.png
: o2 t9 _% K: ^8 f7 G3 s- A
推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。) G9 ]: Y! n, x% L
第二节 硬件解读
* R/ \5 t( x+ Q2 d# O   先看看原理图:- a3 m/ Z3 ?; N6 F, |- e

f4arhfjfb0264047187653.png

f4arhfjfb0264047187653.png
. O+ O* L% Q3 s! S+ c: M7 J
开发板上面一共有3颗可编程LED,控制的引脚分别是PB2,PB5和PB12,LED右侧通过一共限流电阻上拉到3.3V,所有stm32给一个低电平就会点亮LED,反之则熄灭。
+ o: ~+ ?0 {" h# }% {9 U1 g1 I第三节 CubeMX配置/ `; ]% a# l: K: h' f
   第一步:双击打开STM32CubeMX,如下图,新建项目。【注意:新建项目本教程只介绍一次,以后项目的建立不在重复】    # e, O, n$ Z9 v* t1 z

urpx552o2gn64047187753.png

urpx552o2gn64047187753.png
+ {6 n8 O8 y# S
第二步:在英文状态下搜索芯片:STM32WLE5CCU6【注意:尽可能靠近该芯片,不一定是STM32WLE5CCU6,不同STM32CubeMX版本,芯片的名字不一样的】选后选择对应的芯片即可。' \4 P; }) Y( t  n# Z

1x1mmy2b4pc64047187853.png

1x1mmy2b4pc64047187853.png
/ [8 v4 Z, k6 a& A
第三步:在1处查看芯片的视图,选择2处后可以看见芯片所有的功能,选择3处的RCC时钟,在4处配置外部高速时钟,一切配置完了之后,会在5处看见GPIO变绿色。,如下图。【注意:本教程晶振配置仅配置一遍,后续教程将不再重复】   
8 i& @6 J$ ^& u: }

3aonp1d5r5264047187953.png

3aonp1d5r5264047187953.png
) G9 N% x0 E) ]! Z3 x* B; q
第四步:在1处切换到时钟树页面,在2处配置外部晶振大小,蓝桥杯物联网开发板外接高速晶振为32MHZ,所以这里配置成32MZH,在3处配置HCLK时钟为最大时钟,最大时钟为48MHZ。如下图。【注意:本教程时钟树配置仅配置一遍,后续教程将不再重复】# c( G* A& @& h3 T- x

v1b3t0hf4nu64047188053.png

v1b3t0hf4nu64047188053.png

- w" e1 l7 k0 D   
* b) b5 n; E4 u! O# j: @+ ~

gywyut2hfrj64047188153.png

gywyut2hfrj64047188153.png
: U% J1 s  v! P9 }4 d0 W4 ]7 y# R
第五步:配置下载器,在3处选择DEBUG,在4处选择JTAG模式,之后就可以看见5处和6处的GPIO变绿色了。【注意:本教程下载器配置仅配置一遍,后续教程将不再重复】
9 b& V* k& T4 p& ?9 s5 P5 j

t0sdw01lhmr64047188254.png

t0sdw01lhmr64047188254.png

" L2 l: E- W/ X) T( b) g( \第六步:配置STM32的PB2引脚为GPIO_Output,如下图:   
6 E& P! o% `+ }. g8 |! ?  _  A

qkaytxhj31b64047188354.png

qkaytxhj31b64047188354.png

: ]. A* c; v6 u, q# m第七步:以同样配置STM32的PB5和PB12引脚为GPIO_Output,如下图:    . c$ b4 A7 _- ?9 e) u; r4 c5 a* Y

otfa1hh3xsl64047188454.png

otfa1hh3xsl64047188454.png

% I! G3 B' Z; o1 O" b第八步:在1处可以看见选中GPIO的配置,在2处看见GPIO的输入输出的引脚,在3处选择PB2,在4处配置GPIO的默认高低电平,因为低电平LED亮,我们默认低电平,在5处配置为上拉,和硬件配置保持一致,在6处配置用户标签,便于管理。如下图:    - ?% F, G" X) q

dcltdnxlaix64047188554.png

dcltdnxlaix64047188554.png

# \9 B& l  J( i6 ^! U8 K           
) B7 w, e) f2 G" J$ T# ~8 B其中:具体配置信息如下:: \8 Y6 k9 I- t- B
           5 ]) P7 C" R! {" V
GPIO output leve:表示上电的默认电平,可配置高(High)或者低(Low);
& R7 L, r. N# I0 T           * p+ m3 E7 y6 e# s3 u  o! Y
GPIO mode:表示输出模式,可为Output Push Pull(推挽输出)或Output Open Drain(开漏输出);
' V. Q) l5 \, i' [5 i9 }+ n2 N0 ^           
/ l1 ~: J/ n6 A1 ^4 i7 D: Z: w' ?, sGPIO Pull-up/Pull-down:表示是否上下拉,可配置为上拉(Pull-up)或者下拉(Pull-down)或不上拉也不下拉(No Pull-up and no Pull-down);
/ S  C0 F: ?: l# }           
0 O. D- j8 K( {' K& JMaximum output speed:表示输出速度,可配置为低速(Low)或者中速(Medium)或高速(High)或超高速(Very High);5 s# f6 K8 \2 ^! {9 `6 O3 n
           % U, a; F3 P1 R" Z3 {0 n! V
User Label:表示用户标签,可修改IO口名称,比如可写入LED,把IO口名称变为LED;    5 A6 o5 n2 ]% J6 y, H! {5 `$ V
           
$ d0 D; |( y( {" b第九步:和PB2一样配置其他2个GPIO。  n9 F. o4 u6 L" S
第十步:选择项目信息,如下配置:2处是项目的名字;3处是项目的路径;4处是编译器;5处是编译器版本。【注意:项目路径不能包含中文等其他非法字符;编译器一定要选择MDK-ARM;编译器版本要选择最新的,本教程为v5.37。后续教程将不在重复本步操作】( ^. E: W6 ~) a

qoswz1sygyv64047188654.png

qoswz1sygyv64047188654.png

$ m- }$ y5 {! q3 o/ b7 ~! Z( K第十一步:如下图,将3,4处的按钮勾选,点击5处,生成Keil工程。【注意:后续教程将不在重复本步操作】
4 B5 ^7 Y3 W" X  S  F, j

dvealf0fqm164047188754.png

dvealf0fqm164047188754.png
& x0 v& Z( e* e+ H- B

; J) Q( D( G% }: I! f0 I  x; ?8 }1 g; e- _2 `2 H$ w
   
9 D* g/ e5 e6 a  C第十二步:点击上步的5处之后,会有一个对话框,意思分别是:打开项目文件夹位置;打开项目;关闭本窗口。【注意:这里灵活处理,打开文件夹和项目都可以。后续教程将不在重复本步操作】3 h5 @8 l2 v5 J- U0 l+ W) E  e
0 I0 G0 H# U2 Q+ ]& q' o

7 k- Y( t: L( g! e# C第四节 MDK代码
8 S4 C& [( x% j5 t# @) |" G' v   第一步,编译代码,检查STM32CubeMX生成的代码是否正常。如下图,点击1处编译,之后在2处可以看见一个警告,是因为MDK版本太新,高于CubeMX选择的V5.37,导致编译器不一样,但是不影响程序运行。【注意:后续教程将不在重复本步操作】
" j2 C% p& ~# t% P
$ f) U$ r. p- ~+ [- B第二步:配置下载器,这一步很多步骤,希望大家仔细一点,一步一步来。【注意:不要忘记点击“OK”,后续教程将不在重复本步操作】   
1 Q2 M6 A3 I* u1 r
% {, a& a% P4 @; Y第三步:新建.h文件。在“项目名/Core/Inc”中新建一个“zsdz.h”的文件。【注意:后续教程将不在重复本步操作】8 z) z- R: Y0 E

! y+ Y8 l$ d+ x( J7 @" G第四步:新建.c文件。在“项目名/Core/Src”中新建一个“zsdz.c”的文件。【注意:后续教程将不在重复本步操作】   
6 U, n2 g4 V" [
- S6 j6 K) A9 O2 ~$ ?第五步:添加“zsdz.c”文件。点击1处,可以看见项目的所有的文件,点击2,3处,准备添加“zsdz.c”文件,但是发现没有“zsdz.c”文件,如下图:需要返回到上一层文件目录中,点击4处。【注意:后续教程将不在重复本步操作】5 Q) x/ Y- ~  x; ^& F

4 x3 D* z! p) m4 g/ ?1 A如下图:虽然没有发现“zsdz.c”文件,但是我们看见了Core文件夹,还记得我们的“zsdz.c”文件保存在哪吗?在“项目名/Core/Src”中,所以我们进入到“/Core/Src”,找到“zsdz.c”文件即可。【注意:后续教程将不在重复本步操作】   
7 Y8 n2 {5 p, ^0 V  t+ L% q4 `" O. e* y
/ {/ h5 q, h$ u) h
" ?8 w, ^* H$ P/ @$ ^$ Y
第六步:如下图,代表添加成功。【注意:后续教程将不在重复本步操作】    + F; r; I/ N2 J1 s
, i2 ]# r! k, T
第七步:如下,点击1处,可以看见MDK中的“zsdz.c”文件。【注意:如果利用STM32CubeMX生成MDK项目,“zsdz.c”文件可能会从MDK项目中移除,请重新添加】
% }. _% y2 Y; G$ x  c8 u
/ y6 T  |1 W0 h6 v, d- f, L第八步:编写“zsdz.c”文件的代码,如下:【注意:后续教程将不在重复本步操作】   
1 R% ?! e) C- e& y! m9 o  P6 I$ N
第九步:进入到“zsdz.h”文件,右键,选择“Go to Headerfile‘zsdz.h’”。【注意:后续教程将不在重复本步操作】
6 c. |. S# J# f4 k; @7 c4 L8 Z$ A$ I/ f* e
第十步:编写“Zsdz.h”文件的代码,如下:【注意:后续教程将不在重复本步操作】
2 S4 p2 Z. T6 v/ E5 h
$ f) t' I) B5 s第十一步:在Main中添加“zsdz.h文件”,如下:【注意:只可以添加在“USER CODE BEGIN”和“USER CODE BEGINEND”之间,否则等下次利用STM32CubeMX生成MDK项目时,不在“USER CODE BEGIN”和“USER CODE END”之间的代码会被覆盖】    + z& j' }+ N  M, G8 i2 Y

  p6 ?2 E: g6 l& ~- w! b: m第十二步:编写LED的函数模板,具体如下:【注意:不要忘记声明gpio.c文件。注意:后续教程将不在重复本步操作】    ' X  R0 Z* e3 \/ C5 l0 ^
; @' u" R% P- b7 S* f
第十三步:以上就是LED所有的封装函数了,我们在“zsdz.h”文件中声明他们,如下图:【注意:后续教程将不在重复本步操作】# f( m# I' Z7 @3 u+ E; U/ |* S
% K/ M7 U& M' J3 P8 ~
第十四步:现在随便在main函数中写几个,看看效果。    ' h7 z0 ?6 V8 S: d: S0 J, k
* r) Y1 @4 |3 w! u: k1 h
第十五步:编译检查代码并下载。点击1处编译代码,之后在2处可以看见0错误0警告。代码没有问题之后,点击3处下载代码,在4处看见Flash Load finished at xxxx,就证明代码下载成功。【注意:后续教程将不在重复本步操作】
3 @% H1 `5 G! K! w' J% E
! p# H9 f7 F5 ?3 v* \8 |+ f+ j. d  I3 M    ; r' _8 y( m, I
第五节 实验现象
7 z* u8 M$ X2 c  A3 T   注意:
& Z8 F5 a6 W' y3 h3 |. z1,请用USB线连接电脑与开发板。
" c8 L  P! m# L& ^  |2,请选择A开发板。4 M) w0 l8 L; z1 p2 Z# W
现象:AL2以400ms为间隔闪烁。; p7 G! Y6 i* @2 Q( J
来源:撞上电子微信公众号  u' g4 ]1 J& o1 r  z1 `
版权:东莞市东城墨竹公子电子工作室
! o# J: b8 i4 o6 L* W日期:2024.11.03
/ R$ _, L. ?: B+ X第六节 课后作业
, K$ K& i: ]. [5 Y# G$ W8 t   请让AL1长亮,AL2以500ms为间隔闪烁,AL3以1000ms为间隔闪烁。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表