第四讲:STM32平台看门狗实战
STM32 IWDG配置步骤
好,咱们直接进入正题。STM32的独立看门狗,简称IWDG,说白了就是一个独立于主系统之外的定时器。它自己跑自己的,就算主程序死机了,它照样计时。一旦超时没被喂狗,它就强制复位整个芯片。
我刚开始用STM32时,总觉得看门狗配置挺麻烦的。后来发现,其实就那么几个步骤,走一遍就熟了。
第一步:开启LSI时钟
IWDG的时钟源是LSI,也就是低速内部振荡器。这个时钟大概40kHz,但不同芯片有差异。你需要先把它使能起来。
RCC_LSICmd(ENABLE); // 开启LSI时钟
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); // 等待稳定
第二步:取消写保护
IWDG的寄存器默认是写保护的。你得先解锁,才能配置预分频器和重装载值。
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 取消写保护
第三步:配置预分频器和重装载值
这一步是关键。预分频器决定时钟分频倍数,重装载值决定计数时长。两者配合,算出你想要的超时时间。
IWDG_SetPrescaler(IWDG_Prescaler_64); // 预分频64
IWDG_SetReload(0xFFF); // 重装载值4095
第四步:重装载计数器并启动
配置完成后,把重装载值写入计数器,然后启动看门狗。
IWDG_ReloadCounter(); // 喂一次狗,把重装载值写入计数器
IWDG_Enable(); // 启动看门狗
嗯,这里要注意:一旦使能IWDG,就无法再关闭了。除非你复位芯片。所以调试阶段,我建议先别急着开狗,等程序稳定了再打开。
预分频器与重装载值计算
这个计算其实不复杂,但很多人容易搞混。我给大家拆开讲。
超时时间的公式是这样的:
Tout = (4 × 2^预分频系数) × 重装载值 / LSI频率
其中预分频系数可以取0、1、2、3、4、5、6,对应分频倍数4、8、16、32、64、128、256。
举个例子,假设LSI频率是40kHz,我选预分频64,重装载值4095:
Tout = (4 × 2^4) × 4095 / 40000
= 64 × 4095 / 40000
≈ 6.55秒
也就是说,大约6.55秒内必须喂一次狗,否则芯片复位。
我在项目中遇到过一个问题:LSI频率其实不太准,不同芯片之间可能有±10%的偏差。所以计算出来的时间只是个参考值。实际使用时,我一般会留出30%的余量。比如我需要5秒超时,我会按3.5秒来配置。
常用配置参考表(LSI=40kHz)
| 预分频系数 | 分频倍数 | 重装载值 | 超时时间 |
|---|---|---|---|
| 0 | 4 | 0xFFF | 0.41秒 |
| 2 | 16 | 0xFFF | 1.64秒 |
| 4 | 64 | 0xFFF | 6.55秒 |
| 6 | 256 | 0xFFF | 26.21秒 |
你想想看,如果我要一个2秒左右的超时,选预分频16、重装载值2000,算出来大概1.28秒。嗯,留点余量,实际用起来刚好。
喂狗函数编写
喂狗函数其实就一句话:
void IWDG_Feed(void)
{
IWDG_ReloadCounter(); // 把重装载值重新写入计数器
}
就这么简单。但关键是——在哪里喂狗?
我见过不少新手把喂狗放在主循环里:
while(1)
{
IWDG_Feed();
// 其他任务...
}
这样做有个问题:就算其他任务卡死了,主循环还在跑,喂狗照常执行。看门狗根本起不到作用。
我个人习惯的做法是:在关键任务完成后喂狗。比如传感器采集、数据处理、显示刷新,每个大任务完成后喂一次。这样如果某个任务卡住,看门狗就会复位。
void main_task(void)
{
while(1)
{
if(sensor_read() == SUCCESS)
{
IWDG_Feed(); // 传感器读取成功,喂狗
}
if(data_process() == SUCCESS)
{
IWDG_Feed(); // 数据处理完成,喂狗
}
display_update(); // 显示刷新
IWDG_Feed(); // 刷新完成,喂狗
}
}
小技巧:在调试阶段,可以用一个全局变量记录喂狗次数。如果发现喂狗次数异常,说明某个任务执行时间过长。我曾经用这个方法抓到一个传感器驱动里的死循环bug。
警告:不要在中断服务函数里喂狗!如果主程序死机但中断还能响应,看门狗会被中断一直喂着,永远不复位。这是很多嵌入式工程师踩过的坑,包括我。
好了,这一讲的内容就这些。配置步骤、预分频器计算、喂狗函数,三个知识点串起来,你就能在STM32上用好独立看门狗了。下一讲我们聊聊窗口看门狗,那个玩法又不一样了。