独立看门狗
7 d8 N# ^& D" F. a, B; z9 P( S3 B3 n5 f' N* ~& I9 y ], h0 U
1. 独立看门狗简介. I2 W" @& O e2 n4 D1 x4 D V
看门狗其实就是一个定时器,从功能上说它可以让微控制器在程序发生意外(程序进入死循环或跑飞)的时候,能重新回复到系统刚上电状态,以保障系统出问题的时候可以重启一次。说的复杂一点,看门狗就是能让程序出问题是能重新启动系统
e% k! Y% z$ x7 bSTM32的独立看门狗(IWDG)由内部专门的40KHz低速时钟驱动,即使主时钟发生故障,它也仍然有效。注意IWDG的时钟是一个内部RC时钟,是一个在30~60KHz之间的一个可变化的时钟,只是我们在估算的时候以40KHz的频率来计算,看门狗对时间的要求不是很精确$ P0 q3 a# a% s' v% h2 \% c
独立看门口功能框图如下。实际上独立看门口狗是一个递减计数器,当计时器的值减到0时,IWDG会产生一个复位信号,系统复位重新启动。为避免产生看门狗复位,则需在计数器减到0之前重载计数器,即“喂狗”。当程序出错时没有刷新计数器,计数器递减到0,系统复位重新启动,避免程序继续错误运行
3 ~- g% c9 l6 ]" r+ y# U* @3 Q 0 {3 Y2 |2 c1 K
' @; \5 j) K- ?0 z8 v
: h( e: Q7 S/ S
独立看门狗超时时间(40KHz的输入时钟LSI)
( [9 b0 @4 s+ Q, M& _& s% M- c' J, w0 h
$ W! s i1 w7 j2 e: S+ L2. 硬件设计/ K& ^$ X( B6 L" u# G! [4 f
使用USART1来打印调试信息,PC0用来指示程序是否复位
$ r' _0 r8 V6 q' T; d' M. E. j3. 软件设计3.1 STM32CubeMX设置7 T% Q' p8 E: v. R* ]
- RCC设置外接HSE,时钟设置为72M;IWDG的时钟默认为LSI时钟
- PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
- USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位3 Z4 x2 c7 r; r4 z
/ c* F1 o5 J4 K5 ]9 B g( u( [& f5 Y
# t# ^& v- {+ K, k4 A- 激活IWDG,IWDG的时钟为40kHz,此时设置计数器时钟为32分频,则分频后的时钟频率为1.25KHz(时钟周期为1s/1250 = 0.8ms),递减基础器重载值(down-counter reload value)配置为1000,即800ms不刷新IWDG则系统复位& n' H! `8 o/ T% D* I3 R
6 [5 h! I+ [. \ O0 o _
- 输入工程名,选择工程路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
+ l- h) z8 W8 T# P- i
- S6 W7 g# v; ?" C: M" D9 O' I* t 6 m0 u- @( A1 ~. }% x/ t6 Z
' G, U. z' G7 X# S2 j1 g
3.2 MDK-ARM编程
; s2 O0 Y6 c: Y: T3 v- y
% _6 o) T q* A A+ u2 x# S- void MX_IWDG_Init(void){8 u- n8 w% z& _2 T
- hiwdg.Instance = IWDG;, o% E) x# S- \' J, j
- hiwdg.Init.Prescaler = IWDG_PRESCALER_32;8 e. h# [0 ^5 d: J0 Q- y+ P
- hiwdg.Init.Reload = 1000;5 f; _ z4 N/ n3 Z* m" R \2 d
- if (HAL_IWDG_Init(&hiwdg) != HAL_OK){% a% p1 ?' ~8 ^
- Error_Handler();8 E8 t5 `7 \: e: v) {. {$ h% n
- }# P0 T) V1 a. Y- @1 w8 R
- }
复制代码
$ Q3 X7 I7 [, y* g! L- 在main函数中编写代码,while循环里每500ms喂一次狗
% ^) ~3 i8 I0 d7 q' A3 G6 ]2 v
- int main(void){
- G) O3 X( Y2 w \( z) i. _4 |3 a; [( m - HAL_Init();
% y4 s, i8 _5 z% h - SystemClock_Config();5 v6 e; P1 }1 K: p
- /* Initialize all configured peripherals */
& O( D) B& C9 |, d" D+ L7 `* e0 M - MX_GPIO_Init();
. }# W# b5 [1 _( f - MX_IWDG_Init();$ A5 p& l- Y! n9 _! _4 y) \
- MX_USART1_UART_Init();
0 m2 z4 L( [0 O! O - /* USER CODE BEGIN 2 */
) n- P5 ]# R: m' T( i$ E- c% y5 U - printf("\r\n***** AndyXi IWDG test program *****\r\n");
. S7 B( r' m, j+ Y( M3 I& V7 t2 I - HAL_Delay(300);
+ \# i5 ?" I/ `: y) v! Y - HAL_GPIO_WritePin(GPIOC,LED1_Pin,GPIO_PIN_RESET);
! v' V& G& m5 H# H8 _ - /* USER CODE END 2 */7 [; H2 L$ T" B" e1 i7 z
- /* USER CODE BEGIN WHILE */# ]1 U! A6 S1 ^' k+ @
- while (1){
2 M" A& ?& w& y' l1 E, R - printf("\r\nRefreshes the IWDG...!\r\n");) X+ m" P' M w
- HAL_IWDG_Refresh(&hiwdg);
% { L0 I7 l9 q - HAL_Delay(500);
: y: z# Q, z0 x0 w' d; X - /* USER CODE END WHILE */9 w# A2 b: q; F1 _* \' z
- }
& W/ g$ n- {, l - }
复制代码
' v6 ]6 D0 G5 P2 Q. f* b" x
$ v3 |3 l- ^- M( _$ L }
+ U% J2 Z/ U& V$ v* ]2 j% ?4. 下载验证
" m% \) Q) I/ o( U- while循环里每500ms喂一次狗,因此程序不会被复位,LED1常亮
! n# N1 E: ~& r4 Y
' o* K3 V) m2 O+ l; c* _/ f+ O9 g2 e$ o4 j. _
( z! ]; R" m' [& a
- 如果注释掉while循环里的喂狗动作,程序会一直被复位,LED1闪烁. f. Z9 T" K; v c/ w
) v" G( X& e- z/ X7 o! F5 x+ v5 G: |8 T, y7 p% b/ m8 O2 @7 X! N
! E% n6 D9 ^ d( x- ]
1 `" T7 b7 X) |" N- r
I, E+ Q, ^$ u2 G
6 r6 x5 }5 ^: t2 m: C
7 v- \2 A+ d' {7 A, k' A5 l+ k A7 c/ R8 w$ j* v
1 \5 }- O1 A, K2 I h }9 t
6 b, [6 B: p( d# W R+ j$ e: W4 n% E# a E
|