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

【经验分享】STM32开发,使用HAL库函数实现独立看门狗功能

[复制链接]
STMCU小助手 发布时间:2022-5-6 09:26
1 概述
* R" S  O, O( `2 t7 G7 G1.1 资源概述
0 X/ m; m6 c6 i
开发板:ST官方NUCLEO-F103RB开发板
6 z( \) L# l+ U  vCUBEMX版本:1.3.0
" O* ?9 e. j7 tMDK版本:5.23
, ?" D9 X$ T& O- }1 P' u  J3 m! w3 {主控芯片型号:STM32F103RBT6
3 O9 ?) L( k; T  g) d* W
6 H& v; @, D: L- A+ T  A& r+ @9 ` 8%RJBQ@}2KTQAQPE~Q3B9.png
6 X' ^; G) M( ]; ^! V, ^/ t/ G; X) _8 a; }, ]' D  W9 X4 r
1.2 引脚资源分配- i* s% p7 T' J6 Z& a4 G4 d$ _8 R
/ r5 B4 x8 Q5 \
M)LO6WYVZTE24CT(%LK}W[3.png
8 A$ o8 @$ h( r( ]; X! k" ?" ?9 h8 v0 ~2 t9 P6 G6 U; }
1.3 独立看门狗概述) _$ r! V: e8 u' \6 X
独立看门狗可用来检测和解决由软件错误引起的故障;当计数器达到给定的超时值时,产生系统复位。独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精度要求较低的场合。9 Z$ l4 f" o; Y/ v$ J/ {
IWDG的主要性能. d7 X+ n  {  `! L! T# j# ~/ E) c
● 自由运行的递减计数器 ;" Y; ~! A! k) w: W9 [3 d
● 时钟由独立的RC振荡器提供(可在停止和待机模式下工作);9 o! v) C* f& D$ Y' i
● 看门狗被激活后,则在计数器计数至0x000时产生复位。, m$ n4 Q5 l9 J/ X
: U; X: V7 B6 c) b
1.4 实现功能  J, x9 L2 C! `8 B
1、上电初始化后,LED2灯亮;5 b2 @' h1 Q3 Q% ?& d
2、在While(1)中进行按键检测,若检测到按键,喂狗,将灯熄灭;
9 ?: u* S& x% k8 g6 ]$ N+ x3、若未检测到按键,系统自动复位;
  }* Q$ R0 x1 r* G: Z4、采用内部LSI时钟,16分频,预装载值4096(0xFFF)。6 t( \8 O: N  x, w. X' f

, q6 c8 T. z$ ~' i2 软件开发) t# R6 ~5 K8 r; s
2.1 CUBEMX配置$ ]7 M' c9 {" E/ i( c+ F! b
时钟配置
$ y7 `$ }# H0 l/ W- b 1 K7 s8 A; C' m* z2 r1 v$ s

. \8 V4 ^5 o  k/ J7 l- X/ e激活IDWG,分频系数改为16,预装载值设为4096。
: f. X$ p- |$ \" P2 G
0 A6 l# I: |& q9 C1 T 6({3SBZH$Z()%2[QPD~01Q8.png 2 ]9 i5 q. Y: U3 ^

: T* B  r% C  ^  G6 |1 a  ]独立看门狗由LSI提供时钟
9 N- E: x( [5 N7 P8 F' N) X4 }  M8 I& L- R
20200405091416635.png
* Y8 T% l5 V: p, ^: o/ [# l' F6 G2 j. w% A
这里可以计算得到看门狗复位时间如下,这个时间足够我们操作按键喂狗。+ a* X2 G) J* C  d5 [! F! {) L
t=1/(400000Hz/16)×4096=1.638S
9 y$ f! }/ R4 A9 h  n8 K8 B0 Q
: _9 Y( [$ N0 w3 w2.2 代码编写
* B. W) |  w; y5 G7 g1、使用CUBEMX生成代码后,会自动生成前面配置的独立看门狗的初始化函数(分频系数和预装载值)。
& I0 m& n5 y" E, ?2 X: l. O) k* @8 \: m0 ?
  1.   MX_IWDG_Init();//看门狗初始化程序
复制代码

0 u  r6 u: `0 y& |, A6 F# q下面是这个函数的定义。
! w. x( c  Z- u3 f
! I1 J4 z9 A: S3 j  Z7 }' [  ~
  1. void MX_IWDG_Init(void)0 p; b; q) Y, A/ G
  2. {) W' j* t: n% e3 R0 @2 M

  3. * T- p$ @$ [- ?  ?
  4.   hiwdg.Instance = IWDG;9 w. r5 w) ^3 J/ @
  5.   hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
    * y  W( m# T" \, F6 p
  6.   hiwdg.Init.Reload = 4095;" Z( T. S. d* d9 x
  7.   if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
    * f3 {4 \, s) n, k7 U+ a8 V
  8.   {8 V! U' x* y! h) H
  9.     Error_Handler();: m$ @7 [- I& }) @
  10.   }8 ~2 E4 r+ v3 I9 R( J
  11. 4 l( _9 q1 n6 t7 T! V1 |# L
  12. }
复制代码

7 p; _  w; ^4 I" V我们需要在main函数中初始化LED2灯,点亮。
/ l) E* ]$ c! D! n& I) n9 Y1 A+ s7 k7 C! ^
  1. HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);//初始化时将LED2灯点亮
复制代码
3 h, \8 z& C+ r( S' c# S8 O
2、在while(1)中增加按键检测和喂狗操作。当检测到按键时,执行喂狗以及将LED2灯熄灭。0 M1 S" ?4 [0 ?8 |, o

! \* a) e. D9 J; g' q
  1.   while (1)
    & A. b1 G8 u. y5 v
  2.   {" Z4 p/ j: c9 u# O
  3.     /* USER CODE END WHILE */4 i' l, B* u$ M- B* ^+ k

  4. & c( c$ |0 z0 J3 r- u8 c
  5.     /* USER CODE BEGIN 3 */) r9 A0 l3 m. P- A2 G2 x; M* Q9 m
  6. if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port,BUTTON_Pin)==RESET)//假设检测到按键操作1 U8 G0 J# q) Q/ w( j7 w
  7.          
    & j; y" d& \* s+ H1 Z7 j: O* a
  8.           {
    2 u; I5 k! d+ K2 J" d
  9.          HAL_Delay(20);//按键抖动检测                 
    * q* F$ l4 _1 Z
  10.                 if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port,BUTTON_Pin)==RESET)//假设检测到按键操作
    ) i4 x. D% z3 Y2 u" K% m* s! ^: C/ `
  11.                 {
    ) k' g3 d1 e5 k9 K5 h8 M! G. e8 l+ J
  12.                         HAL_IWDG_Refresh(&hiwdg);//执行喂狗操作
    3 w) a" i* b8 m) i
  13.                           4 F* b6 |- C5 J; s1 B
  14.                         HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);//LED熄灭
    4 t* }+ c' c% O8 M4 i  f  q& j  D
  15.                 }         
    , C1 s; u8 n5 S* I
  16.           }
      M) ]% p7 v. l; l
  17.   }
复制代码
; h+ ~3 Z) ]5 B# w
这里的HAL_IWDG_Refresh函数的功能是在键寄存器IWDG_KR中写入0xAAAA,也就是喂狗操作。
$ a% s9 R! m- w0 Y7 Q这里的按键检测,是不严谨的,因为按键会抖动,所以这里可能存在喂狗多次,下面是按键检测的函数,加入了while();循环,只有在按键弹起时才返回数据。2 H. F' G" l1 M# W: [& ~7 |
在初始化按键的IO口,切记要注意上下拉操作,如果是低电平有效就上拉,如果是高电平有效就下拉,不配置或者配置相反,都有可能导致按键不可用,或者不符合逻辑。! ~5 p" e3 r/ [  `

6 B/ i! r# \+ v  K. k: h
  1. uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
    2 |& E! R* h& ?, v$ X( Z$ Z# \7 J7 j
  2. 5 w: c& y2 L( i$ i1 o9 \$ V
  3. {                        % j" L8 m6 B$ w7 \6 y7 [
  4.   @' B; f  m+ A3 ?) e% K' E
  5.         /*检测是否有按键按下 */
    5 Q5 A! X2 i& x) Z

  6. ' k7 X. m1 A5 _5 E& [$ P
  7.         if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_ON )  : _! p+ Z4 W; u& L4 }

  8. + `4 Q. j6 n5 h% f% ~
  9.         {         
    7 V1 i2 C+ o3 c5 Q$ c+ n, L! O7 v
  10. ; \/ D- r6 k, Z: |9 a" E% g
  11.                 /*等待按键释放 */
    ! _& ^. ^' \8 i
  12.                 HAL_Delay(10);
    2 @8 F) V% L+ A% a/ @7 H- D, k+ E
  13.                 if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_ON )
    7 }- x. L+ A( z5 k
  14.                 {' O- r2 `2 {3 T, A. A& p" d
  15.                         while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_ON);                           
    ; a% L0 z3 M8 F4 ~6 n0 F- }
  16.                         return         KEY_ON;         
    5 q& a+ b" \& I4 X7 Y7 p" v. Y
  17.                 }/ o5 M! m' o) |* }: H7 Q2 I2 c$ A
  18.                 " b# ^5 D; j0 i# r
  19.         }
    1 _: x: x2 o1 A3 K; l6 ?
  20.         return KEY_OFF;
    9 w* Z9 W& I. l; D7 Q! w' a$ g% R. S

  21. ' x" q% i4 F3 }) R7 }  D
  22. }
复制代码

  R6 o) I% `3 o; G3 实验结果" {* D9 F( @7 m' S. Y; x
实验结果:未检测到按键时,LED2灯常亮,当在规定的时间内按键操作,LED2灯熄灭。# \& l$ i0 P: u' }

8 I$ R: |  \) C' ~ 20200405100526444.gif ; V/ v( U% T' n5 Z3 _$ Y' F
赞 收藏 评论0 发布时间:2022-5-6 09:26

举报

0个回答

所属标签

相似技术帖

官网相关资源

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