STM32独立看门狗调试
johncheapon 于 2019年05月13日 发表在 嵌入式开发笔记

看门狗的作用

程序意外跑飞(死机)的时候可以给系统复位,回到一个确定的状态。在程序的主循环中,必须每隔一个固定周期喂狗,即重置计数器,如果程序跑飞,看门狗就不会得到重置,从而计到阈值触发复位。

为什么叫独立看门狗?

因为它的时钟源是LSI,内部RC振荡器,频率约为32KHz,独立于系统时钟,以和WWDG(窗口看门狗)相区别。

优点:即便主时钟没起来,看门狗也能正常工作。

缺点:LSI是RC振荡器,频率不稳定,受温度影响很大,需要校准补偿。

如何启动计数?

IWDG_KR寄存器写0x0000CCCC

如何喂狗?

IWDG_KR寄存器写0x0000 AAAA

如何设置计数周期?

1. 设置预分频比。IWDG的计数时钟就是LSI经过预分频以后得到的,取值范围为0~256.

2. 设置计数值。多少个计数时钟后超时。

比如要想1秒钟以内喂狗,否则复位。那么就可以将预分频比设为32,计数值设为1000.

ST官方例程解析

主循环中,每隔0.99s喂狗并闪一下LED灯。

按键触发外部中断,在中断服务程序中向地址0x00040001写入0xFF,因为0x00040001正好位于STM32G071地址空间的未定义区域(如下图):

操作该地址会被MCU视为“非法操作”,跳转到Hard_Fault(硬件错误)。通过这种方式可以模拟“意外情况”。看门狗复位后,若检测到复位来源为“IWDG”,就亮灯4秒。

考虑到LSI频率不准,所以在初始化阶段就用定时器TIM16采集一次LSI信号,计算出频率,根据算得的结果来初始化独立看门狗。

由于笔者并未使用ST官方开发板NUCLEO-G071RB,硬件电路不同,所以对程序做了简单的移植

1. 按键中断由PC13改为PC7。NUCLEO-G071RB上PC13有4.7K上拉电阻,但笔者的板子上PC7未上拉,为了有一个确定的初始状态,将其设置为内部上拉。

2. 加入了UART打印,更好地查看程序运行状态。

主程序的流程基本未变,如下:

(1)初始化Flash和Systick

(2)初始化时钟

(3)初始化GPIO和USART,此处按照官方例程使能中断,非法操作在外部中断服务程序中模拟。

(4)打印“**********IWDG Test*************”

(5)查看复位源。若确认为看门狗复位,就亮灯4秒。

(6)计算并打印LSI频率

(7)初始化IWDG。执行完这一步后IWDG开始计数。计数时钟频率为1KHz,计数周期1s。

(8)进入主循环。每隔990ms喂狗并翻转一次LED。

调试过程中碰到的问题

有时手不小心碰到按键电路时会导致死机,尽管触发了中断后执行了非法操作并导致复位,但复位后程序却卡了“**********IWDG Test*************”这一步

原因分析

IO内部上拉电阻较弱,阻值为25KΩ~55KΩ,容易受外部干扰。人手是导体,会改变电路周围的分布参数,使得IO输入端出现扰动,引发外部中断。

分析主程序流程不难发现,在看门狗初始化之前,外部中断就被使能了,而如果在这段时间干扰信号注入引发“非法操作”,程序还未在看门狗起作用之前就死机了,自然得不到复位。

解决办法

注释掉GPIO初始化函数中的中断使语句,将其拷贝至看门狗初始化语句和主循环之间。实测发现,即便误触按键电路也不会引起死机。

注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。

标签:MCU使用,ARM,STM32