本文介绍STM8L051F3的IWDG相关知识。内容分为以下几部分:
1、IWDG简介IWDG(Independent watchdog):独立看门狗。独立看门狗外设可以用于解决系统由于硬件或软件产生的故障。独立看门狗的时钟是LSI时钟作为时钟源,所以当主时钟故障它也能够保持工作。
往IWDG_KR寄存器写入0xCC时,独立看门狗开始从复位值0xFF向下计数,当计数值达到0x00时产生一个AWDG复位。一旦使能,独立看门狗就能通过IWDG_PR和AWDG_RLR寄存器进行配置,IWDG_PR寄存器用于配置计数器时钟的预分频,当往AWDG寄存器写入KEY_REFRESH(0xAA)值时,独立看门狗将装载AWDG_RLR值进行刷新来防止看门狗复位产生。IWDG_PR和IWDG_RLR寄存器是写保护的,如果想要修改它们就要往IWDG_KR寄存器写入KEY_ACCESS(0x55)值,写入0xAA会重新恢复写保护。IWDG模块的框图如下:
独立看门狗可以通过两种方法开启:
- 软件使能:在IWDG_KR寄存器写入0xCC
- 硬件使能:配置选项字节IWDG_HW位,重新上电时会自动打开独立看门狗功能
独立看门狗的溢出时间可以根据下表设置:
独立看门狗IWDG理解及应用可分为以下几部分:
- IWDG一共有3个寄存器
- IWDG_RLR与IWDG_PR寄存器用于配置计数器溢出时间,但默认处于写保护状态,需要往 IWDG_KR寄存器写入0x55来解除写保护
- 往IWDG_KR寄存器写入0xCC用于启动IWDG
- 往IWDG_KR寄存器写入0xAA用于刷新IWDG(喂狗)
2、IWDG复位2.1 IWDG配置本小节介绍如何使用IWDG,并通过KEY来触发一次IWDG复位,然后通过LED2来表示(LED2表示有IWDG复位产生)。使用的例程:STM8L051F3_15_IWDG。例程的内容为:配置EXTI,配置IWDG(溢出时间约为431ms),在主函数中每300ms对LED1状态取反和IWDG进行刷新一次以防止系统复位,并且检测标志位。当KEY按下时进入中断,标志位被置位,循环中检测到标志位不为0,进入死循环,从而IWDG没有刷新导致系统复位,复位后在主函数初始化时检测有IWDG复位发生,LED2点亮。IWDG的配置步骤如下:
1)使能LSI时钟,等待LSI时钟稳定
2)使能IWDG
3)设置IWDG时钟分频64
4)设置IWDG重装载值256(溢出时间约为431.16ms)
5)开启IWDG计时
2.2 例程介绍IWDG配置函数(在main.c文件下)如下所示:
static void IWDG_Config(void)
{
/* 使能LSI时钟 */ CLK_LSICmd(ENABLE); /* 等待LSI时钟稳定 */ while(CLK_GetFlagStatus(CLK_FLAG_LSIRDY)== RESET); /* 使能IWDG */ IWDG_Enable(); /* 使能写 IWDG_PR 和 IWDG_RLR 寄存器 */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* 设IWDG的时钟预分频为64 */ IWDG_SetPrescaler(IWDG_Prescaler_64); /* 设置重装载值为256,看门狗复位时间为:(256*64) / 38000 = 431.16ms */ IWDG_SetReload(0xff); /* 重装载看门狗,开始计时 */ IWDG_ReloadCounter(); }
中断函数(在stm8l15x_it.c文件下)如下:
INTERRUPT_HANDLER(EXTI4_IRQHandler,12)
{
/* In order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction. */ //清除中断标志位 EXTI_ClearITPendingBit(EXTI_IT_Pin4); //延迟消抖 delay_ms(10); //松手检测 while(GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY_GPIO_PINS)== 0); //标志位置1 EXTI_Flags = 1; }
主函数如下:
void main(void)
{
LED_Init(); //初始化LED EXTI_Init(); //EXTI初始化 IWDG_Config();//IWDG初始化 enableInterrupts(); //开总中断 /* 检测系统复位是否由IWDG复位引起 */ if(RST_GetFlagStatus(RST_FLAG_IWDGF)!= RESET) { /* 是:点亮LED2 */ GPIO_ResetBits(LED2_GPIO_PORT, LED2_GPIO_PINS); /* 清除IWDG标志位 */ RST_ClearFlag(RST_FLAG_IWDGF); } else /* 否:关闭LED2 */ GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PINS); while(1) { if(EXTI_Flags != 0) //检测标志位 { EXTI_Flags = 0; //标志位清零 while(1); } IWDG_ReloadCounter(); //每300ms,IWDG喂狗 GPIO_ToggleBits(LED1_GPIO_PORT, LED1_GPIO_PINS); //切换LED1状态 delay_ms(300); } }
使用ST-LINK把程序下载到开发板,LED1闪烁,按一下KEY(长按效果一样),LED2亮。
|