14.1 stm32看门狗简介在单片机构成的微型计算机系统中,单片机的工作可能会受到外界的电磁干扰或者程序运行的bug导致程序指针错误,或者其他错误导致的死循环,引发整个系统陷入停滞状态,所以需要一个与系统独立的定时器来监控单片机的运行状态,这个定时器在系统正常运转的时候,不停的刷新定时器的计数器,例如隔一段时间给这个定时器的计数器写100,然后在定时器减运算到0之前再一次写入100,这样,就保证了定时器不计数到0,也就意味着通过判断这个定时器是否计数到0来判断系统是否陷入死机状态,实现这种功能的定时器就称为看门狗,不停的刷新计数器值的行为就称为“喂狗”,一般计数器计数到0后会直接对单片机进行复位,用于避免系统陷入死循环。
stm32内部有两种看门狗模块,一种是窗口看门狗wwdg,另一种是独立看门狗iwdg,stm32的独立看门狗由内部专门的40khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。独立看门狗的时钟是一个内部rc时钟,所以并不是准确的40khz,而是在30~60khz之间的一个可变化的时钟,只是我们在估算的时候,以40khz的频率来计算。窗口看门狗通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在t6位变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个mcu复位。在递减计数器达到窗口配置寄存器数值之前,如果7位的递减计数器数值在控制寄存器中被刷新,那么也将产生一个mcu复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。
14.2 独立看门狗相关寄存器14.2.1 键值寄存器iwdg_kr1514131211109876543210
key[15:0]
该寄存器属于只写寄存器,读取的值为0x0000,软件必须以一定间隔写入0xaaaa,否则,当计数器为0时,看门狗会产生复位;
写入0x5555表示允许访问iwdg_pr和iwdg_rlr寄存器;
写入0xcccc表示启动看门狗工作,如果选择了硬件看门狗则不受此命令字限制。
14.2.2 预分频寄存器iwdg_pr1514131211109876543210
- pr[2:0]
bit 2~bit 0:预分频因子
000:预分频因子=4
001:预分频因子=8
010:预分频因子=16
011:预分频因子=32
100:预分频因子=64
101:预分频因子=128
110:预分频因子=256
111:预分频因子=256
14.2.3 重装载寄存器iwdg_rlr1514131211109876543210
- rlr[11:0]
bit 11~bit 0:看门狗计数器重装载值:每当向iwdg_kr寄存器写入0xaaaa时,重装载值会被传送到计数器中,随后计数器从这个值开始递减计数。
14.3 窗口看门狗相关寄存器14.3.1 控制寄存器wwdg_cr1514131211109876543210
- wdga t6 t5 t4 t3 t2 t1 t0
bit 7:激活位:,此位由软件置1,但仅能由硬件在复位后清0。当wdga=1时,看门狗可以产生复位
0:禁止看门狗
1:启用看门狗
bit 6~bit 0:7位计数器,存储看门狗的计数器值。每(4096x2 ^wdgtb^ )个pclk1周期减1。当t6变成0产生看门狗复位
14.3.2 配置寄存器wwdg_cfr1514131211109876543210
- ewi tb1 tb0 w6 w5 w4 w3 w2 w1 w0
bit 9:提前唤醒中断,此位若置1,则当计数器值达到40h,即产生中断,此中断只能由硬件在复位后清除
bit 8:预分频器时基
00:ck计时器时钟不分频
01:ck计时器时钟2分频
10:ck计时器时钟4分频
11:ck计时器时钟8分频
bit6~bit 5:7位窗口值,用来与递减计数器进行比较用的窗口值
14.3.3 状态寄存器wwdg_sr1514131211109876543210
- ewif
bit 0:提前唤醒中断标志,当计数器值达到40h时,此位由硬件置1。它必须通过软件写0来清除。若中断未被使能,此位也会被置1
14.4 实验例程14.4.1 独立看门狗实验功能:如果看门狗没有复位,接在pb5上的led常亮,如果pa0的按键按下,就喂狗,只要按键不停的按,看门狗就一直不会产生复位,保持ds0的常亮,一旦超过看门狗定溢出时间,那么将导致程序重启,这将导致ds0熄灭一次。
(1)创建wdg.h文件输入以下代码。
#ifndef _wdg_h_#define _wdg_h_#include sys.h/********************************************************************************************************* 函 数 列 表*********************************************************************************************************/void iwdg_init( u8 prer, u16 rlr ) ; //独立看门狗初始化#endif(2)创建wdg.c文件输入以下代码。
#include wdg.h/***************************************************name :iwdg_initfunction :独立看门狗初始化paramater : prer:分频数:0~7 rlr:重装载寄存器值return :none***************************************************/void iwdg_init( u8 prer, u16 rlr ){ iwdg->kr = 0x5555 ; //使能对iwdg->pr和iwdg->rlr的写 iwdg->pr = prer ; //设置分频系数 iwdg->rlr = rlr ; //从加载寄存器 iwdg->rlr iwdg->kr = 0xaaaa ; //更新计数器 iwdg->kr = 0xcccc ; //使能看门狗}(3)在1.c文件中输入以下代码。
#include sys.h#include delay.h#include usart1.h#include wdg.h/***************************************************name :led_initfunction :led初始化parameter :nonereturn :none***************************************************/#define led pbout( 5 ) //定义led端口void led_init(){ rcc->apb2enr |= 1crl |= 0x00300000 ; led = 1 ;}/***************************************************name :key_initfunction :key初始化parameter :nonereturn :none***************************************************/#define key pain( 0 ) //定义按键端口void key_init(){ rcc->apb2enr |= 1crl |= 0x00000008;}/***************************************************name :mainfunction :主函数parameter :nonereturn :none***************************************************/int main(){ stm32_clock_init( 9 ) ; //stm32时钟初始化 systick_init( 72 ) ; //systick初始化 usart1_init( 72, 115200 ) ; //初始化串口1波特率115200 led_init() ; //led初始化 key_init() ; //按键初始化 delay_ms( 500 ) ; //延时500ms,让人可以看到ds0灭的状态 iwdg_init( 4, 625 ) ; //与分频数为64,重载值为625,溢出时间为1s led = 0 ; //点亮ds0 while( 1 ) { if( key==1 ) { delay_ms( 10 ) ; if( key==1 ) { iwdg->kr = 0xaaaa ; //喂狗 } } delay_ms( 20 ) ; }}14.4.2 窗口看门狗实验功能:程序一运行使得接在pb5上的led1亮300ms后关闭,进入死循环。等待wwdg中断的到来,在中断里面,喂狗,并对pe5上的led2进行翻转操作。可以看到led2不停的闪烁,led1只在刚启动的时候闪一下。
(1)在上一个实验的wdg.h文件的函数列表区域添加以下代码。
void wwdg_init( u8 tr, u8 wr, u8 fprer ) ; //窗口看门狗初始化
(2)在上一个实验的wdg.c文件末尾添加以下代码。
/***************************************************name :wwdg_irqhandlerfunction :窗口看门狗中断服务程序paramater :nonereturn :none***************************************************/void wwdg_irqhandler(){ wwdg->cr = 0x7f ; //重设置7位计数器 wwdg->sr = 0x00 ; //清除提前唤醒中断标志位 led2 != led2 ;}/***************************************************name :wwdg_initfunction :窗口看门狗初始化paramater : tr:计数器值 wr:窗口值 fprer:分频系数return :none***************************************************/void wwdg_init( u8 tr, u8 wr, u8 fprer ){ rcc->apb1enr |= 1
cr |= tr&0x7f ; //设定计数器值 wwdg->cr |= 1cfr |= 1apb2enr |= 1crl |= 0x00300000 ; led1 = 1 ; led2 = 1 ;}(5)在1.c文件中输入以下代码。
#include sys.h#include delay.h#include usart1.h#include led.h#include wdg.h/***************************************************name :mainfunction :主函数parameter :nonereturn :none***************************************************/int main(){ stm32_clock_init( 9 ) ; //stm32时钟初始化 systick_init( 72 ) ; //systick初始化 usart1_init( 72, 115200 ) ; //初始化串口1波特率115200 led_init() ; //led初始化 led1 = 0 ; //点亮ds0 delay_ms( 300 ) ; //延时300ms,让人可以看到ds0亮的状态 wwdg_init( 0x7f, 0x5f, 3 ) ; //计数器值为7f,窗口寄存器为5f,分频数为8 while( 1 ) { led1 = 1 ; //熄灭led1 }}14.5 为何stm32要同时存在窗口看门狗与独立看门狗14.5.1 独立看门狗的使用条件(1)程序跑飞
(2)出现死循环
(3)睡眠与休眠不合理
(4)外部主晶振损坏
(5)需要重新复位,且不保留任何数据
14.5.2 窗口看门狗使用条件(1)软件逻辑出现错误
(2)死机或者死循环
(3)软件执行不按预期效果执行
(4)软件需要重新复位,但是保留所有数据
14.5.3 两者的区别(1)独立看门狗使用内部专用40khz低速时钟
窗口看门狗则使用pclk1的时钟(2)独立看门狗没有中断,超时直接复位
窗口看门狗有中断,超时可以在中断服务函数中操作或者喂狗(3)独立看门狗一般用于避免程序跑飞或者死循环
窗口看门狗则是为了避免程序不按照预先设定的逻辑执行(4)独立看门狗是12位递减操作
窗口看门狗则是6位递减操作
运用CAN232B转换器实现RS232/CAN网络的数据智能转换
如何画架构图
美格智能高算力智能模组SNM951助力云游戏产业快速发展
ST-Ericsson出货逾650万 领跑TD芯片市场
谷歌发布了3D模型查看器Article,将兼容所有的浏览器
看门狗实验
海信打造智能家居全链路 为用户带来全新的消费体验
用于视频监控摄像头的简单高效的发光二极管驱动器
中兴通讯Q3季度净利润为26.6亿元,预计将扭亏为盈
带你了解地物光谱仪产品特性
漫步者辅听产品践行企业社会责任 助力国家老龄事业发展
pcb行业中所有你需要知道如何选择电子合同制造商 华强PC
为什么中国厂商开始转向14nm制程的订单?
可惜魅族没有后悔药
电磁兼容的国际标准化组织介绍
电子车速里程表的单片机实现方案
公路隧道电气管理方案
国产奥比中光也能做手机3D摄像头
戈埃尔科技:5G通讯类产品FIP点胶加工
用于高分辨率激光雷达的氮化镓HEMT电路拓扑结构