1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > STM32看门狗(独立看门狗与窗口看门狗)

STM32看门狗(独立看门狗与窗口看门狗)

时间:2024-06-07 13:35:14

相关推荐

STM32看门狗(独立看门狗与窗口看门狗)

简介

STM32 有两个看门狗,一个是独立看门狗(IWDG)另外一个是窗口看门狗(WWDG),独立看门狗号称宠物狗,窗口看门狗号称警犬。

独立看门狗用通俗一点的话来解释就是一个 12 位的递减计数器,当计数器的值从某个值一直减到 0 的时候,系统就会产生一个复位信号,即IWDG_RESET。如果在计数没减到 0 之前,刷新了计数器的值的话,那么就不会产生复位信号,这个动作就是我们经常说的喂狗。看门狗功能由 VDD 电压域供电,在停止模式和待机模式下仍能工作。

独立定时器比较简单就不讲了,直接递减触发复位。

窗口看门狗就是一个7位的递减计数器往下记,设定一个上窗口值,下窗口值固定,只能在上窗口和下窗口值之间进行复位,复位前可以触发一次紧急中断,可以做复位前觉得最重要的事件。

分频

我的看门狗所在时钟是APB1的时钟主频是42M,数据手册上规定看门狗必须除于4096,你还可以通过CFR寄存器再进行一次分频(1,2,4,8)。CNT_CK=PCLK1/4096/(2^WDGTB)

窗口值

窗口值是由CFR寄存器决定的,下窗口值是固定的,寄存器的初始化值是0x7F,二进制为01111111,下窗口值为0x3F,所以上窗口值设定只能在0x3F到0X7F之间,即63到127之间。

超时计算

寄存器介绍

代码

中断优先级初始化

// WWDG 中断优先级初始化static void WWDG_NVIC_Config(void){NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

WWDG配置函数

/* WWDG 配置函数* tr :递减计时器的值, 取值范围为:0x7f~0x40,超出范围会直接复位* wr :窗口值,取值范围为:0x7f~0x40* prv:预分频器值,取值可以是*@arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1(42MHz)/4096)/1 约10253Hz 97us*@arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1(42MHz)/4096)/2 约5126Hz195us*@arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1(42MHz)/4096)/4 约2563Hz390us*@arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1(42MHz)/4096)/8 约1281Hz780us**例:tr = 127(0x7f,tr的最大值) wr = 80(0x50, 0x40为最小wr最小值) prv = WWDG_Prescaler_8*~780 * (127-80) = 36.6ms < 刷新窗口 < ~780 * 64 = 49.9ms*也就是说调用WWDG_Config进行这样的配置,若在之后的36.6ms前喂狗,系统会复位,在49.9ms后没有喂狗,系统也会复位。*需要在刷新窗口的时间内喂狗,系统才不会复位。*/void WWDG_Config(uint8_t tr, uint8_t wr, uint32_t prv){// 开启 WWDG 时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);// 设置递减计数器的值WWDG_SetCounter( tr );// 设置预分频器的值WWDG_SetPrescaler( prv );// 设置上窗口值WWDG_SetWindowValue( wr );// 设置计数器的值,使能 WWDGWWDG_Enable(WWDG_CNT);// 清除提前唤醒中断标志位WWDG_ClearFlag();// 配置 WWDG 中断优先级WWDG_NVIC_Config();// 开 WWDG 中断WWDG_EnableIT();}

死前中断函数

// WWDG 中断复服务程序,如果发生了此中断,表示程序已经出现了故障,// 这是一个死前中断。在此中断服务程序中应该干最重要的事,// 比如保存重要的数据等,这个时间具体有多长,要// 由 WDGTB 的值决定:// WDGTB:0 113us// WDGTB:1 227us// WDGTB:2 455us// WDGTB:3 910usvoid WWDG_IRQHandler(void){// 清除中断标志位WWDG_ClearFlag();//LED2 亮,点亮 LED 只是示意性的操作,//真正使用的时候,这里应该是做最重要的事情LED2(ON);}

喂狗函数

// 喂狗void WWDG_Feed(void){// 喂狗,刷新递减计数器的值,设置成最大WDG_CNT=0X7FWWDG_SetCounter( wwdg_cnt );}

main函数

int main(void){Debug_USART_Config();printf("\r\n这是一个看门狗例程\r\n");uint8_t wwdg_tr, wwdg_wr;/* LED 端口初始化 */LED_GPIO_Config();// BLUE 蓝色灯亮LED3(ON);Delay(0XFFFFFF);// WWDG配置/* WWDG 配置函数* tr :递减计时器的值, 取值范围为:0x7f~0x40,超出范围会直接复位* wr :窗口值,取值范围为:0x7f~0x40* prv:预分频器值,取值可以是*@arg WWDG_Prescaler_1: WWDG counter clock = (PCLK1(42MHz)/4096)/1 约10253Hz 97us*@arg WWDG_Prescaler_2: WWDG counter clock = (PCLK1(42MHz)/4096)/2 约5126Hz195us*@arg WWDG_Prescaler_4: WWDG counter clock = (PCLK1(42MHz)/4096)/4 约2563Hz390us*@arg WWDG_Prescaler_8: WWDG counter clock = (PCLK1(42MHz)/4096)/8 约1281Hz780us**例:tr = 127(0x7f,tr的最大值) wr = 80(0x50, 0x40为最小wr最小值) prv = WWDG_Prescaler_8*~780 * (127-80) = 36.6ms < 刷新窗口 < ~780 * 64 = 49.9ms*也就是说调用WWDG_Config进行这样的配置,若在之后的36.6ms前喂狗,系统会复位,在49.9ms后没有喂狗,系统也会复位。*需要在刷新窗口的时间内喂狗,系统才不会复位。*/// 初始化WWDG:配置计数器初始值,配置上窗口值,启动WWDG,使能提前唤醒中断WWDG_Config(127,80,WWDG_Prescaler_8);// 窗口值我们在初始化的时候设置成0X5F,这个值不会改变wwdg_wr = WWDG->CFR & 0X7F;while(1){// BLUE 蓝色灯LED3(OFF);//-----------------------------------------------------// 这部分应该写需要被WWDG监控的程序,这段程序运行的时间// 决定了窗口值应该设置成多大。//-----------------------------------------------------// 计时器值,初始化成最大0X7F,当开启WWDG时候,这个值会不断减小// 当计数器的值大于窗口值时喂狗的话,会复位,当计数器减少到0X40// 还没有喂狗的话就非常非常危险了,计数器再减一次到了0X3F时就复位// 所以要当计数器的值在窗口值和0X40之间的时候喂狗,其中0X40是固定的。wwdg_tr = WWDG->CR & 0X7F;if( wwdg_tr < wwdg_wr ){// 喂狗,重新设置计数器的值为最大0X7FWWDG_Feed();}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。