看门狗的作用:
在启动正常运行的时候,系统不能复位。
在系统跑飞(程序异常执行)的情况,系统复位,程序重新执行
STM32有两个看门狗:
独立看门狗(IWDG)由专用的低速时钟(LSI)驱动,即使主时钟发生故障它仍有效。独立看门狗适合应用于需要看门狗作为一个在主程序之外 能够完全独立工作,并且对时间精度要求低的场合。
窗口看门狗由从APB1时钟分频后得到时钟驱动。通过可配置的时间窗口来检测应用程序非正常的过迟或过早操作。 窗口看门狗最适合那些要求看门狗在精确计时窗口起作用的程序。
看门狗一般用法:
while(1) { 喂狗; if(定时标识) { 里面就是按键程序; } }12345678
计算一下,主循环执行一次的最大时间,看门狗定时是这个时间的一,二十倍,就可以了。不用再某个模块中喂狗,一个循环来一次。
窗口看门狗配置步骤:
取消寄存器写保护:IWDG_WriteAccessCmd();
设置独立看门狗的预分频系数,确定时钟: IWDG_SetPrescaler();
设置看门狗重装载值,确定溢出时间: IWDG_SetReload();
使能看门狗: IWDG_Enable();
应用程序喂狗: IWDG_ReloadCounter();
溢出时间计算:Tout=((4×2^prer) ×rlr) /40 (M3)
wdg.c
void IWDG_Init(u8 prer,u16 rlr) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //使能对寄存器IWDG_PR和IWDG_RLR的写操作 IWDG_SetPrescaler(prer); //设置IWDG预分频值:设置IWDG预分频值为64 IWDG_SetReload(rlr); //设置IWDG重装载值 IWDG_ReloadCounter(); //按照IWDG重装载寄存器的值重装载IWDG计数器 IWDG_Enable(); //使能IWDG}12345678
main.c
int main(void) { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //初始化与LED连接的硬件接口 KEY_Init(); //按键初始化 delay_ms(500); //让人看得到灭 IWDG_Init(4,625); //与分频数为64,重载值为625,溢出时间为1s LED0=0; //点亮LED0 while(1) { if(KEY_Scan(0)==WKUP_PRES) { IWDG_ReloadCounter();//如果WK_UP按下,则喂狗,LEDO亮,一直连按LED0一直亮 } delay_ms(10); }; }12345678910111213141516171819
窗口看门狗:
工作过程:
STM32F的窗口看门狗中有一个7位的递减计数器T[6:0],它会在出现下述2种情况之一时产生看门狗复位:
当喂狗的时候如果计数器的值大于某一设定数值W[6:0](上窗口值)时,此设定数值在WWDG_CFR寄存器定义。
当计数器的数值从0x40减到0x3F时【T6位跳变到0】。
如果启动了看门狗并且允许中断,当递减计数器等于0x40时产生早期唤醒中断(EWI),它可以用于喂狗以避免WWDG复位。
配置过程:
使能看门狗时钟:RCC_APB1PeriphClockCmd();
设置分频系数:WWDG_SetPrescaler();
设置上窗口值:WWDG_SetWindowValue();
开启提前唤醒中断并分组(可选):WWDG_EnableIT(); NVIC_Init();
使能看门狗:WWDG_Enable();
喂狗:WWDG_SetCounter();
编写中断服务函数:WWDG_IRQHandler();
wdg.c
void WWDG_Init(u8 tr,u8 wr,u32 fprer) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE); // WWDG时钟使能 WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT,设置计数值 WWDG_SetPrescaler(fprer);////设置IWDG预分频值 WWDG_SetWindowValue(wr);//设置窗口值 WWDG_Enable(WWDG_CNT); //使能看门狗 WWDG_ClearFlag();//清除提前唤醒中断标志位 WWDG_NVIC_Init();//初始化窗口看门狗 NVIC WWDG_EnableIT(); //开启窗口看门狗中断} //重设置WWDG计数器的值,喂狗void WWDG_Set_Counter(u8 cnt) { WWDG_Enable(cnt);//使能看门狗}//窗口看门狗中断服务程序void WWDG_NVIC_Init() { NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;//WWDG中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_InitStructure);//NVIC初始化}//中断服务函数void WWDG_IRQHandler(void) { WWDG_SetCounter(WWDG_CNT); //当禁掉此句后,窗口看门狗将产生复位 WWDG_ClearFlag(); //清除提前唤醒中断标志位 LED1=!LED1; //LED状态翻转}12345678910111213141516171819202122232425262728293031323334353637
main.c
int main(void) { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); KEY_Init(); //按键初始化 LED0=0; delay_ms(300); WWDG_Init(0X7F,0X5F,WWDG_Prescaler_8);//计数器值为7f,窗口寄存器为5f,分频数为8 while(1) { LED0=1; } }
上一篇:STM32系列第10篇--看门狗
下一篇:STM32系列第9篇--外部中断
推荐阅读最新更新时间:2024-03-16 15:38