STM32F103看门狗功能实现

您所在的位置:网站首页 看门狗2操作设置 STM32F103看门狗功能实现

STM32F103看门狗功能实现

2024-01-02 15:56| 来源: 网络整理| 查看: 265

  STM32F10xxx内置两个看门狗,提供了更高的安全性、时间的精确性和使用的灵活性。两个看 门狗设备( 独立看门狗 和 窗口看门狗 )可用来检测和解决由软件错误引起的故障;当计数器达到给 定的超时值时,触发一个中断(仅适用于窗口型看门狗)或产生系统复位。

  独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它也仍然有效。窗口看门 狗由从APB1时钟分频后得到的时钟驱动,通过可配置的时间窗口来检测应用程序非正常的过迟 或过早的操作。

  IWDG最适合应用于那些需要看门狗作为一个在主程序之外,能够完全独立工作,并且对时间精 度要求较低的场合。WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序。

  看门狗主要是用来对系统运行状态进行监控的,以免系统被干扰后代码跑飞了,导致系统混乱。看门狗的使用也比较简单,下面就分别来看一下独立看门狗和窗口看门狗的使用方法。

独立看门狗

//初始化独立看门狗 //prer:分频数:0~7(只有低 3 位有效!) //分频因子=4*2^prer.但最大值只能是 256! //rlr:重装载寄存器值:低 11 位有效. //时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). void IWDG_Init(u8 prer,u16 rlr) { // 1、取消寄存器写保护 写0x5555 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); // 2、设置独立看门狗预分频系数 IWDG_SetPrescaler(prer); // 3、设置独立看门狗重装载值 IWDG_SetReload(rlr);; // 4、重载计数值喂狗 写0xAAAA IWDG_ReloadCounter(); // 5、启动看门狗 写0xCCCC IWDG_Enable(); } void IWDG_Feed(void) { IWDG_ReloadCounter(); }

独立看门狗的初始化很简单,主要就是设置一下喂狗的时间。然后在程序运行过程中不停的喂狗。

int main(void) { u8 key = 0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_Init(); KEY_Init(); IWDG_Init(4, 625); //溢出时间为1s (4*2^4)*625/40=1000ms LED0 = 1; LED1 = 1; delay_ms(500); LED0 = 0; LED1 = 0; while(1) { key = KEY_Sacn(1); if( key == WKUP_PRES) { IWDG_Feed(); } delay_ms(10); } }

这里通过一个按键来模拟喂狗,当按键按一次,就会喂狗一次。如果按键超过喂狗时间没有按下时,独立看门狗就会使系统复位。

窗口看门狗

u8 WWDG_CNT = 0x7f; void WWDG_NVIC_Init(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } //初始化窗口看门狗 //tr :T[6:0],计数器值 //wr :W[6:0],窗口值 //fprer:分频系数(WDGTB),仅最低 2 位有效 //Fwwdg=PCLK1/(4096*2^fprer) void WWDG_Init(u8 tr, u8 wr, u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); //时钟使能 WWDG_CNT = tr & WWDG_CNT; WWDG_SetPrescaler(fprer); //设置预分频值 WWDG_SetWindowValue(wr); //设置窗口值 上窗口值 与喂狗间隔没关系 WWDG_Enable(WWDG_CNT); //使能看门狗,设置计数值 WWDG_ClearFlag(); //清除提前唤醒中断 WWDG_NVIC_Init(); //设置中断优先级 WWDG_EnableIT(); //开启窗口看门狗中断 } void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt); //使能看门狗,设置计数值 } void WWDG_IRQHandler(void) { WWDG_SetCounter(WWDG_CNT); //喂狗 WWDG_ClearFlag(); //清除提前唤醒中断 LED0=!LED0; }

由于窗口看门狗的喂狗时间很短,在程序运行过程中很难判断出什么时候该喂狗,所以这里喂狗使用中断来执行,在需要喂狗的时候,直接触发中断,在中断中进行喂狗,每喂一次狗,LED就取反一次。通过观察LED的闪烁就可看出中断函数的执行情况。

int main(void) { u8 key = 0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); LED_Init(); KEY_Init(); //IWDG_Init(4, 625); //溢出时间为1s (4*2^4)*625/40=1000ms LED0 = 1; LED1 = 1; delay_ms(500); LED0 = 0; LED1 = 0; //窗口看门狗喂狗间隔 只和 tr 低6位有关 wr 可以设置为0x40---0x7f 之间的任意值 // 4096*2^3*64/36000000 = 58.25ms (64为0x7f 低6位值) WWDG_Init(0x7f, 0x7f, WWDG_Prescaler_8); //计数器值7f,窗口寄存器5f,分频数为8 // 4096*2^3*31/36000000 =28.22ms (31为0x4f 低6位值) //WWDG_Init(0x5f, 0x5f, WWDG_Prescaler_8); // 4096*2^3*15/36000000 =13.65ms (15为0x4f 低6位值) //WWDG_Init(0x4f, 0x5f, WWDG_Prescaler_8); // 4096*2^3*1/36000000 =910us (1为0x41 低6位值) 窗口最小值为0x40 //WWDG_Init(0x41, 0x5f, WWDG_Prescaler_8); while(1) { } }

在主函数中通过设置不同的溢出时间来观察LED灯的闪烁频率。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3