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

【经验分享】STM32开发,HAL函数实现待机唤醒功能以及SVN使用简介

[复制链接]
STMCU小助手 发布时间:2022-5-5 17:33
1 概述! l, c; O+ A1 W
1.1 资源概述
, e4 w7 P% p7 A9 e" Z! ]
开发板:正点原子STM32F103 Nano开发板
  _" }: b1 N& P/ V0 x7 SCUBEMX版本:1.3.0* v: A4 c+ _6 i8 v5 l% z
MDK版本:5.23; C& z8 n% Q) e$ M2 Q  O
主控芯片型号:STM32F103RBT6
  Y: S+ Z6 M: A+ z4 o
4 ]2 Z, h, g  T8 q; h/ N) _ V@%(W[%PF2CC0)1M4{PZ@}0.png
% J: q2 }) s$ M1 _, S+ L0 L/ I+ a
1.2 实现功能7 h8 j9 i" b  q
1,修改:将HAL官方例程工程PWR提出,driver对应的多余文件进行删除,形成一个独立的工程包;2 u/ {( V, u: Z9 D, b
2,include路径进行了重新定义;; ]% D( H$ O9 W7 g
3,LED(DS0)灯点亮5S,然后进入待机模式,按下KEYUP按键退出待机模式;0 f+ E5 O- q" @! B; ?6 l  N' X: ]
4,支持正点原子F103 nano开发板。1 q8 B. I) j+ N) Q, d0 _

" K# I6 L  Q8 I/ s* [/ I! z9 E2 程序实现
4 @4 N( {$ b* F4 u% u' L' s2.1实现原理
4 T6 G; O; I4 y9 Q! n+ f/ W
待机模式的进入和退出条件如下表。4 f2 i0 n$ S# c0 v. Y
FW{7{{[G2@JMH@5C5C}[XMW.png
! n# ?8 l5 g9 w+ J* W/ n4 T9 }6 o; x1 F
芯片对应的PA00为芯片的Wakeup功能键,对应正点原子wake% [/ b4 {' u, g& [* v5 b* I
up按键。我们需要将此按键初始化这个功能即可。
) z$ D7 x+ @4 R! l5 A$ `9 t+ q
5 S8 n! t2 y' p2.2 程序源码; R  k- y/ Y) x) n2 r: X
在原官方例程上增加了LED2,用来指示单板是否进入了待机模式。LED2采用单板上的DS0。9 c  `0 n7 f, r2 Z8 L0 `: {

) p2 b; J: b$ ^( Q/ G' Y: `
  1. int main(void)
    : n: D2 o, c7 {2 J0 {; Z% k
  2. {
    . {2 h4 x+ E) x  g6 K( X: l
  3.   /* STM32F103xB HAL library initialization:
    : X/ Y/ I* S% d& P% ]7 a) h
  4.        - Configure the Flash prefetch
      b* J0 k3 z/ h& Q2 a- U7 y4 r
  5.        - Systick timer is configured by default as source of time base, but user * e: @8 S3 Y4 Q( U, a
  6.          can eventually implement his proper time base source (a general purpose
    & c' a  q$ T5 [# R  N/ ~
  7.          timer for example or other time source), keeping in mind that Time base * r) a0 n1 g* B6 G9 s. y' g
  8.          duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
    : V/ A5 J5 s/ h
  9.          handled in milliseconds basis." d. J) X6 V0 W  i  X7 _" t
  10.        - Set NVIC Group Priority to 43 w) k" a! \! ?/ M+ k* e  V
  11.        - Low Level Initialization
      r- a- h5 v& G- d9 P( o3 h
  12.      */
    6 n! s7 I2 O$ X: c! x2 H  K
  13.   HAL_Init();
    5 n9 _$ m. Y3 Z8 F3 ?

  14. ! z5 P' l/ t( N  @. M" _3 |: n, ^
  15.   /* Configure the system clock to 64 MHz */
    . z; g+ Q, c0 M, C! l- D
  16.   SystemClock_Config();8 u9 g5 R+ P& p- I9 d2 X
  17. 9 ^! ]  E9 y! E6 y% A0 U$ |
  18.   /* Configure the system Power 配置系统电源 */
    ' \1 W7 I: R9 m& b5 s" j, H
  19.   SystemPower_Config();; ^/ l4 e% x. D
  20. 5 i1 X) p- S: X7 r
  21.           /* Check and handle if the system was resumed from Standby mode 确认系统是否从待机模式恢复*/
    / r* p9 u3 K- ]7 B! I2 ^+ c; m( {
  22.   if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
    0 q" o7 \7 o: o! ?
  23.   {$ _) c4 e) L- D, P6 b
  24.     /* Clear Standby flag 如果恢复则清楚待机标志位*/
    8 d2 F7 C9 _  u" W
  25.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
    ) i7 ^3 M0 j' J
  26.   }
    3 L3 W+ ^/ F( |4 F5 p+ n

  27. ( i! G# Y4 Z( {6 b6 M! Y& E

  28. 2 W: Q8 F( H( j1 N' X: y
  29.   /* -2- Configure IO in output push-pull mode to drive external LEDs初始化LED2灯,上电时点亮 */5 P0 `, l4 R" \  s
  30.   LED2_GPIO_CLK_ENABLE();  @/ S% Y) q3 u) a7 ?- O
  31.   GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    6 L% W9 e# O2 r" ?
  32.   GPIO_InitStruct.Pull  = GPIO_PULLUP;
    - X  ]* ^# b5 O2 a$ V: C+ l  g
  33.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;4 y6 ~$ g9 D5 L- {
  34.   GPIO_InitStruct.Pin = LED2_PIN;
    , o" R$ v( n0 V3 c9 {; t" e
  35.   HAL_GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStruct);- l( B. G2 P( _8 d) D
  36.   HAL_GPIO_WritePin(LED2_GPIO_PORT,LED2_PIN,GPIO_PIN_RESET);
    ( {' \: d% c8 z
  37. 5 L1 |4 x3 e8 k; b
  38.   /* Insert 5 seconds delay 延时5S*/( V6 E  u; B6 X! ~
  39.   HAL_Delay(5000);
    # l" }; f( Q) t& n* P
  40. ) z; _" |: e) o. Q) Q. W* j% T1 y
  41. /* The Following Wakeup sequence is highly recommended prior to each Standby mode entry* T# l; j5 L. _* x! Z/ z3 p
  42.     mainly when using more than one wakeup source this is to not miss any wakeup event.
    ; \& G. b9 f& H/ f8 d1 Z% D/ W
  43.      - Disable all used wakeup sources,
    ( q! M, Q/ q' q6 g" e1 l
  44.      - Clear all related wakeup flags,
    ; I- T7 j  D* I: n" V, t8 K2 K9 p
  45.      - Re-enable all used wakeup sources,
    3 s7 R' Z/ K  O% r/ ^" ~
  46.      - Enter the Standby mode.7 n9 F! t* w. C! H; w7 Z
  47.   */3 {9 g% Y9 V; _/ I6 N0 x8 K% F
  48. ! K" b  [% H% Y
  49.   /* Disable all used wakeup sources: PWR_WAKEUP_PIN1 */
    9 n5 R/ |0 f$ q- K7 j" y
  50.   HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
    . i/ T& D- i* w  A' z4 F) \7 B

  51. ! H8 r/ i- F7 P8 J
  52.   /* Clear all related wakeup flags*/
    $ `9 \2 T& x! S& ^4 c% i) m" B- o; r. `- l
  53.   __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
    8 [( f$ i0 D, A+ A. G% ?6 V* s1 ]" I

  54. ; g& V6 g& `; N9 C7 l
  55.   /* Enable WakeUp Pin PWR_WAKEUP_PIN1 connected to PA.00 使能PA00的唤醒功能*/
    ) \# n+ h/ e. r" h$ t
  56.   HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);  m( J) }, D$ O% e1 k
  57. 9 Y/ X5 a& G0 m- W; {
  58.   /* Enter the Standby mode进入待机模式 */
    # v/ k7 `/ B" z
  59.   HAL_PWR_EnterSTANDBYMode();
    . _1 o, @( Y1 I  G. Z9 w* c. S2 v
  60. 2 W$ P7 _4 w& q0 ~
  61.   /* This code will never be reached!如果没有进入待机模式则进入此循环 */
    1 p) g( G$ z7 ?
  62.   while (1)
    - v$ w. u0 u2 }6 q8 K1 O
  63.   {
    / _2 j5 \2 E$ j3 u
  64.          /* Insert delay 500 ms */$ F: N% w' V: L) e. y# X5 Z4 A
  65.           HAL_Delay(500);; E5 l0 c  o; J( P' E: N
  66.           HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);  //用于检测是否进入待机模式,若没进入将500ms一次闪烁LED2灯 * D( W. Q/ d. Y0 J

  67. , p2 p/ d5 m0 \2 w1 Y7 r& }' a
  68.   }. o( T% R/ z# T
  69. }
    2 m$ w1 F+ [# o( S+ a6 @
复制代码
* L" L9 c  j  H  o0 A
其中HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1)函数的作用是使能PWR_CSR的相关寄存器,用于使能唤醒按键的操作。
# e% G$ C+ h6 X  k+ K! _4 C$ n* k0 @. k7 f
IM8S6O3ZSA@`AEOY}~7WZGC.png & ]; N1 q1 h' P
3 M# C0 I) w# U- l- `  M3 D
HAL_PWR_EnterSTANDBYMode 函数则是对进入的条件写了一遍+ t: |9 M* ^( v$ h" t+ H# p* ?
5 q6 Z' H$ \" G
  1. void HAL_PWR_EnterSTANDBYMode(void)
    : u: a" J* R+ u1 u. q
  2. {
    9 I9 g) N7 c& l- j, i
  3.   /* Select Standby mode */9 A9 U) a9 ]  l# @0 l( A. M$ C/ `  m
  4.   SET_BIT(PWR->CR, PWR_CR_PDDS);
    : u' E7 d7 T2 A6 f
  5. / z$ {4 \$ d* d' Z& E9 o4 T$ ~+ v
  6.   /* Set SLEEPDEEP bit of Cortex System Control Register */5 O. P/ f) |+ B) q# P/ f+ Y
  7.   SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));0 O, M" z, Z9 \1 `! B

  8. : V: a1 V# J1 {2 l8 s2 X! j5 X
  9.   /* This option is used to ensure that store operations are completed */
    $ H1 R9 Z  F9 ^6 Y# A' V3 p$ M5 E4 F
  10. #if defined ( __CC_ARM)
    ! \8 n" u; L' `9 \$ h4 |* T. N
  11.   __force_stores();
    - }! ?+ `7 S. b6 x
  12. #endif
    2 t" j9 m6 F# R
  13.   /* Request Wait For Interrupt */5 L* p' p2 u- k5 h9 d# P
  14.   __WFI();7 a% z" u3 p7 H9 E
  15. }
复制代码
' R) v; J" k; ]
移植野火程序的经验总结3 V/ @3 s# R) D. @& l, R
在使用待机功能时,需要一开始就使能时钟。函数名为. t/ B- ^% V; f8 P  j' l
* R4 N+ D# B3 G1 a. u
  1. _HAL_RCC_PWR_CLK_ENABLE();
复制代码
3 I& w  I9 R# `% z/ _2 y
否则将会导致进入待机模式里无法使用WKUP唤醒。使用WKUP按键时,需要一开始对其按键进行初始化为输入下拉,否则将出现不按下WKUP也能自动唤醒的情况。5 ?- G% a' i3 m! y

* D) _6 G; f* f! r" f) ?6 ]3 SVN简介
( Q# G+ D8 j2 @* X+ q# C# y9 v4 [  g2 g. TSVN运行用户将程序保存在云端(第三方的服务器),方便使用者备份,回退版本,保存多个版本等,是一个非常好用的工具,我使用的是SVNBUCKET,免费版本提供100M的空间,对于STM简单的例程是足够用了。如果文件进行了修改,文件符号会出现一个问号,可以进行提交(传到网上的服务器上),将服务器版本进行更新。假如改错了,可以回滚到之前版本,而不用关心是否已经提交。还可以对提交的代码进行比较。这里不详细介绍,可以在B站上找到介绍视频。使用非常灵活。
& _! w# P% W6 e; \# b0 _9 ~4 f3 B+ |5 N- W/ q$ O! X
95`{2SM[$GI62C937WKGPED.png
& K% W" j' l$ x8 m/ m/ |: S, X. v* m5 |
下面是我在SVNBUCKET上提交的两个项目,使用了3MB。当然对于自己开公司的或者重要大项目还是建议保存本地备份,以免SVN服务提供商哪天黄了或者跑路。
4 [+ d/ h; b7 y! c, u* v: }
  o. P' O9 G) V& B. E/ E `T2FJQ3V@2LO1Y758}A@T3W.png
. W5 W/ `3 T3 ~: ^4 h6 i# t( S3 |) c( {
4官方例程库driver精简
, y5 S$ d- Z9 b* D7 f2 ]' D+ M为了充分利用SVN的100M,我对Driver文件夹进行了精简,下面是精简的文件夹结构,删除掉多余LL库,第三方器件支持等
6 K; J; O0 L. F# h% |3 f+ G3 G9 u! C7 F7 u! t& q( e
2020041915400450.png
8 d4 k# ~! O9 g+ ?
5 Q/ v' ^. E/ z! M4 UBSP即为Board support pack,文件夹下为单板支持的一个头文件和一个C文件
) N& c3 e. b/ H; O. j' W2 j6 }0 u
3 M) h% o* H, P; m' S 20200419154214971.png $ q" \5 b  @/ C9 v0 X
2 t+ l# r) B; p
Device为芯片平台支持的文件夹,三个文件。
! p/ M' C  p8 g! {
0 Q; G7 r$ a4 C" Q; Z. X 20200419154300246.png & {, S0 c5 z/ q5 q) w4 n7 @

0 i4 [* n2 ~1 B2 Z, J3 zHal_drive 文件夹即为Hal函数的库文件(函数声明)和C文件(函数定义)。可以依据项目需要进行裁剪。% e6 c+ c& @/ h1 }3 y# D8 h
项目的.S文件放置工程文件夹中MDK_ARM中。最后精简后的工程可以进行独立编译,大小仅为5MB  |. N0 d  A2 k+ G7 v: l6 g
" V. D7 u) H+ Q: p- a/ E7 [2 ]
IG05N%5RW8XIO9WFKF3]]ZV.png : S1 b4 G2 ?& Z. ^
" l6 N* p4 S( A6 ^0 E; ~
头文件进行了重新指向,否则工程将会报错,找不到目标文件。
8 m0 x+ _& L3 ~; O) e2 o0 C* r5 P# T* l) {, z! L
89O57J]@Z{J)SSQ`2]$~B6S.png 7 p; i! d* T6 P% q+ U% S; \5 Z' K* r4 E

7 `2 G2 _  q7 V8 N) E4 P8 O5实验结果
: K8 |& ~$ ^/ H) J( o5 ~; i; `% C实验结果在Nano板上实现,符合预期。1 U, ]/ v) |) ?1 A* ~

0 j  t4 t7 O+ x4 p: c& C 20200419155938967.gif 3 k" E, Z% g( Q& Z4 `8 w5 a& c
赞 收藏 评论0 发布时间:2022-5-5 17:33

举报

0个回答

所属标签

相似技术帖

官网相关资源

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