你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32G4之LED实验

[复制链接]
STMCU小助手 发布时间:2022-7-6 14:23
一、实验原理
' P+ y, ^6 v, m" k7 v. [, Z8 ^7 \1.LED原理
; p3 I- X5 B* p* O% F" }+ F开发板原理图
5 A! ~/ s7 r' X) W
" S8 b' s# @9 T6 Y% e Y4WJKN)9LJ`){_14ZEBY0`H.png
  n) o; r+ {1 @! f" \# D
: d+ |# x$ g7 O4 qLED的一端接入高电平,所以只要给另外一端(PC9-15)引脚输出低电平LED即可点亮5 S, a8 ]' f2 r0 w* j+ I
& W# }  R; V; g4 C
2.74H573锁存器
+ q) ^* S$ ^# J* Y+ o3 ^! P但是,LED灯的控制引脚与驱动LCD的引脚有重叠部分,所以在使用LCD的时候会影响LED的使用情况,所以LED需要使用锁存器4 K! ^2 s- u8 H, H) }
& n0 n% Y9 i( @9 q
WW9](R{DDT4G[{WP`CT0)2L.png 2 P6 V& K) f: E

. B% u6 W( e) e2 Y锁存器原理图
4 g3 I) V/ A+ M7 E/ b
/ B2 n3 t8 I& A* J9 t6 M. N 9FR0O)PR$LI99Q[}YT}1Z30.png + d/ M$ p+ n( Z# c9 s
~N7FE@9`~L(TLK2F)AOA$~K.png ; \5 s4 k, V, D0 O; _( d

( \( y' |5 D" @; g* C4 QOE为高电平时,无论LE与D端为何种电平状态,其输出都为高阻态,此时芯片处于不可控状态。所以在设计电路直接将OE接地,74HC573一直处于使能状态
# E; w8 ^/ T/ g( L( E
9 u# W2 Z, V. a  ?! n+ X8 h当LE为高电平时,D与Q同时为H或L,处于直通状态7 l) E* @- T7 m4 y0 I. X
当LE为低电平时,无论D为何种电平,Q都保持上一次的数据状态,处于锁存状态  j. w- Q& a1 r" w$ _- \! O

/ M( ~. b5 c7 k1 d锁存器就是把当前的状态锁存起来,使输入的数据在接口电路的输出端保持一段时间锁存后状态不再发生变化,直到解除锁存。锁存引脚LE高电平表示直通状态,为低电平表示锁存状态,可以通过控制锁存引脚,控制74HC573后端输出数据
3 d* L4 _$ |6 H. f# C: E1 L1 r( z! t% ~# w0 k
3078a4dc5a564efa86589a58c3372297.png
  _  j0 P5 ~: @0 Z/ M9 `; B! V8 e8 T) }# w6 b; n
在控制LED的时候,只需在输出对应电平后,给锁存器的LE(N—LE,对应PD2)管脚一个下降沿脉冲即可把对应的电平锁存到锁存器的输出端(Q1~Q8),从而控制LED+ o3 Q% N, E* T+ Z9 w

2 j# {" ~0 n" \& [$ [0 x) w二、工程模板
- T! O$ z& p* F0 {: F, {2 a先建立HAL_LED_TEXT文件夹和HAL_PROJECT_SOURCE文件夹 ![在这里插入图片描述]() HAL_LED_TEXT: 用户编写程序 HAL_PROJECT_SOURCE:利用CubeMX初始化辅助编写,移植到测试文件中
1 }1 g. `  C5 x( y# J2 V1.使用CubeMX初始化时钟在HAL_LED_TEXT文件夹中5 @6 _0 U6 D% h1 X" ^) Q

4 r; M( K: Q$ Q* @' X3 T0 Z
, ?$ q) P& j& B5 p+ D8 R$ E% B- B" a7 S  A! V
_N`N4YEBJS~A2W$V}4`PT0P.png
" X, _, d  {2 D- j$ d6 J5 G" Q% f. T9 I' B( m$ S7 S# n
文件夹下目录: e9 r$ c, f0 k. B- J

+ W5 L+ i$ S" U' i  i {1HED6[Z`@88@DN~@DSWJ[S.png # v4 n; f. x4 k0 C; }4 v

6 p/ Y) O) p( E4 \# W注:此时工程中缺少启动文件,一定要从例程(MDK-ARM)中将启动文件添加到工程中。
* i+ f$ N6 v9 }1 k. {
9 l" A6 t! c! i9 I  N2 d2 Y) w2.复制HAL_LED_TEXT文件夹到HAL_PROJECT_SOURCE下
/ i) P1 P5 A& H3 B0 I+ u: Y在HAL_PROJECT_SOURCE进行GPIO引脚的配置(不在刚才的文件下进行,是为了等下好移植,使工程层次更清晰)0 b1 ]) t) w3 @% g5 [: f& x7 I5 d& i0 t
. P- T3 e9 Z7 j
KKGD[JL0[C8U]SRKGQSSSTG.png
$ Q6 V  b0 s2 a, x- w
4 \1 q# Y) d3 Z' a上电默认LED灯全灭(PC8~PC12为高电平)、锁存器不通(PD2为低电平)、全部为推挽输出、全部无上下拉、全部为低速
- D* F) x: g' h8 A3 m# g
9 P/ ~) |$ ^( l# }* O) A" ?0 I4 J3.重构HAL_LED_TEXT文件夹目录1 N" N5 v4 p1 s6 A
建立中间层BSP,目录结构:HAL_LED_TEXT\Inc\BSP\LED 在该目录下在建立bsp_led.h头文件;HAL_LED_TEXT\Src\BSP\LED 在该目录下在建立bsp_led.c源文件;9 U& t  Q! d8 F7 {3 N! h6 h

) X% v6 S) q/ }  b5 T7 @7 [然后将上层目录结构添加到Keil工程里面,并删除gpio.c文件,主要是把源文件添加到工程里面3 H% C3 r8 j* g2 N+ p$ [) V: N5 j' I* f

4 V& h# ^# i  J5 ^& v4 U 1@Q]Q88R9A@PESNQ4RFB_FG.png % B; d  B$ W1 j! p+ e4 }

4 y/ H/ j: ~$ m+ r添加头文件路径
2 }+ |8 R+ G1 W5 X% m! p( M( w  R* U! u  _8 v" J" f( {
LDQ7IEJY4{_HOERAXP%M.png
5 D) J. O5 [- E8 {1 C2 X/ J5 W+ J0 G- o! w: s) Q
由于这里只添加到BSP目录路径,所以在引用头文件的时候,我们要采用) u% R- U5 l" g# v  r6 z; R
如下格式:(因为该目录下可能含有多个外设)- k& z2 _: ?. w
/ O! J1 D, t, U, D' x% L- H- A
  1. #include "LED/bsp_led.h"
复制代码

  J" q* |6 Y) x1 S- N% Q0 E三、程序编写3 m& Z# \- i' V% @6 Q# Q+ {
1.移植函数
9 `8 }6 y4 B; W. H将HAL_PROJECT_SOURCE中gpio的初始化移植到bsp_led.c中
9 A5 g. y, b, n4 O, D  M1 X( X: K. R2 Q# J. k3 B  Y+ G" Z
EBGZ$@%~_EH0T1HFPSQ]37X.png 0 U  a0 ^9 Q  m: Q* b
; u% c9 ~! b% S2 g
2.LED应用函数
1 O% P; x/ ?- {根据ucled的值将对应的8个led点亮(最高位对应LED8)+ ^, V* x: x2 t  M: |  ^$ \& m& [

9 D8 u4 y1 F/ W: f$ Y
  1. void LED_Display(unsigned char ucled), \* V. L3 J3 \: D5 P+ w9 Z
  2. {
    - g: j' R2 }  Q% U/ e
  3.         // 0x882 e; N" D, h$ _' G4 P4 s1 u
  4.         // 1000 1000/ r$ `2 ?0 n& n3 V
  5.         // 8-->1(灯的顺序)6 Q- v2 @7 p: z! R$ h1 q; V7 R
  6.         //拉高 ,上电默认熄灭8 F0 C( v4 W' d3 m* X/ Z
  7.         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
    8 p4 O, g" d7 j7 @* w3 _/ ]
  8.                           |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);+ w) k1 T: p" w) _9 Z7 Y9 ]
  9.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    ) P$ P4 ~: v& U2 t
  10.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
    ! A& z( a- J# _: B, ?! C7 F
  11.         
    6 t! |; A+ ?1 B, P) [" \
  12.         // 根据ucled的值控制led的亮灭* P+ _$ F% n6 i; Q6 }# Y
  13.         HAL_GPIO_WritePin(GPIOC,ucled<<8,GPIO_PIN_RESET);
    3 B" F) H6 [; C4 N
  14.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);1 a7 q' S+ d8 z5 \& M' ?
  15.         HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
    . m$ z, D0 e  l4 |4 z- @
  16. }
复制代码

- z, s! a) {3 Jucled<<8原因:" b% b  J% v) j" w, g4 Z
HAL_GPIO_WritePin()操作的BSRR和BRR寄存器
4 M: [9 |( e, P+ P* L( Y& P- e* \( x- t& y) I# a, b7 I
  1. void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
    ; y  n: S9 J) z) a& w) @5 U" v% m
  2. {
    8 @& p' H, h% S* L
  3.   /* Check the parameters */
    , ^% X, B4 J0 q' {  n
  4.   assert_param(IS_GPIO_PIN(GPIO_Pin));, T+ q3 {2 }- P
  5.   assert_param(IS_GPIO_PIN_ACTION(PinState));! @2 B8 Q( s4 T1 C' A# B4 E+ ~
  6. $ J% i: _' |$ V8 H1 j0 F9 J
  7.   if (PinState != GPIO_PIN_RESET). B8 n# B* m0 F. E' K( j! q. n
  8.   {
    ' K* \# ]/ z+ y& |
  9.     GPIOx->BSRR = (uint32_t)GPIO_Pin;
    0 Q+ m! E# X7 z0 s+ K2 j5 e
  10.   }
    2 W* i6 l8 h( V2 G  g  `5 M
  11.   else5 q% N* N1 A0 e) J% r
  12.   {
    + Q  g% ~8 Z. s/ q  [/ T( M% J
  13.     GPIOx->BRR = (uint32_t)GPIO_Pin;
    - ^6 `% F3 r* [9 X4 W' ~
  14.   }1 G$ Z: O# S+ f* e5 M% G/ U
  15. }
复制代码

# H" p. f1 C: V  }: L6 E8 Y7 a根据传入的参数PinState是将该引脚赋值为高电平还是低电平,操作不同的寄存器
: U; Y0 z# O9 {8 H4 C: ~
* T5 c. A2 D: m' }- k' MGPIOx_BRR:GPIO位复位寄存器 “低”/ ~2 i9 C* W# s- k
GPIOx_BSRR :GPIO 端口置位/复位寄存器 “高”  r* z5 S5 g) W: x& K- H
BRSS寄存器:( F% H1 ?9 @. p2 Y! l
3 L$ G; X) Y( F. E& E  E
8T((66~$S7$RWJ1[LRBKP}U.png
+ O, q. N+ ]1 a" [2 s0 M
8 v% m* m$ f8 l6 l% M4 OBit 31:16 复位 BR[15:0]
4 k; l% j$ ]4 {- t+ }. d) z# ?0:对相应的ODx位不执行任何操作5 H+ c4 c* M# c- g; X, |
1:复位相应的ODx位(0)0 v9 }" R% `9 z9 E9 R6 J
Bit 15: 0 置位 BS[15:0]
1 D% _) n) {5 [0:对相应的ODx位不执行任何操作
4 Y; l1 a- s  c1:置位相应的ODx位(1)
$ p5 k* U: R2 ]: O* w# C0 k  B. [BRR寄存器:
- H5 c8 a8 v2 j2 p
* N1 u7 \" I6 }" _! y5 I7 T! u' h 7852EG7E~$(8TI79]@3YV7P.png - o- \* l! ^! z( z/ f) [" y& F( w8 e

# ?/ ^  n; a) v6 ?- P+ C. D$ I6 n0:对相应的ODx位不执行任何操作" d5 ~8 ~! B$ }* u6 n6 A6 h
1:重置相应的ODx位# L! w  _, u1 C" I- V' ^; R: m4 Z
( }9 N# E. d8 Y' U5 y
GPIOx->BSRR = (uint32_t)GPIO_Pin:1 n7 f! u( i1 t7 M( _& {
这里是将该引脚的BSRR寄存器写入GPIO_PIN_X
5 d' o/ D7 i) D1 m4 n/ I( ?( K# U1 e7 d) P3 O5 O
6CTR_LR}NV%0LMAM%ZF}{@C.png 7 A7 k; g- \' ~% s0 c
5 q7 M& T# _7 N  E; q& x9 e3 S$ [
赋值给 BSRR 、BRR 的 0 或 1 用于控制输出数据寄存器OD(选中对0~15中的某一引脚进行配置):
7 _9 F1 ~4 e5 A3 L% \9 z& \4 cBSRR 得到1后映射到OD,相应的位置位(1);4 R" r4 r7 f) E) q/ u+ @$ R& A+ j
BRR 得到1后映射到OD,相应的位复位(0)
5 q$ o4 T9 d. g% X0 J6 m0 b) p' P- m: R! D* S& Q$ ^0 \2 c; U
HAL_GPIO_WritePin(GPIOC,ucled<<8,GPIO_PIN_RESET):
  V0 m) i# d3 F4 A7 z
4 R7 g' @0 S4 n/ f7 C* ` YRCT{{9P7A)58H1XTH2)7`U.png
1 v5 Q4 \: T8 H% f: l0 w, g. z6 l2 S2 ?. _  [, R3 X
总结:
( N4 c, M! s- y# G7 A1 C7 \( ]HAL_GPIO_WritePin() 中的 (uint16_t)GPIO_Pin 由输出数据寄存器OD决定, 输出数据寄存器 OD 由 BSRR、BRR 决定,BSRR、BRR 由 (uint32_t)GPIO_Pin 决定  T! r0 T& k& J7 n7 u5 n
7 O7 }- w' q" N& n- V

3 a* t7 [! v# k* [. M& \9 a( T
5 [; y$ Y2 p7 S5 _1 ?
赞 收藏 评论0 发布时间:2022-7-6 14:23

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版