tag 标签: iwdg

相关博文
  • 热度 4
    2020-11-13 13:40
    1149 次阅读|
    0 个评论
    MM32 MCU内置了两个内置了两个看门狗(独立看门狗和窗口看门狗),为软件系统增加了更加安全的检测机制。 IWDG 由专门的低速时钟( LSI )驱动,即使主时钟发生故障它也仍然有效,使得它能够工作于低功耗模式下。 IWDG 最适合应用于那些需要看门狗作为一个正在主程序外,能够完全独立工作,并且对时间精度要求低的场合。 IWDG看门狗的原理是:MCU系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种情况的发生。看门狗的作用就是在一定时间内(通过递减计数器实现)没有接收喂狗信号(表示MCU未正常运行),便实现处理器的自动复位重启(发送复位信号)。 从IWDG看门狗的功能框图来看,它分为两个部分,配置寄存器在 1.8V 供电区,计数器的核心部分以及复位信号在 VDD 供电区 ( 这使得即使在停机 / 待机模式下计数器也能计数 ) ;由于处在不同的电源域,每次加载新数据时都需检测状态位。 1.IWDG超时时间计算及喂狗 IWDG的工作流程为:在键值寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值0xFFF递减计数。当计数器计数到末尾0x000时,会产生一个复位信号(IWDG_RESET)。无论何时,只要键寄存器IWDG_KR中被写入0xAAAA,IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位。IWDG_PR和IWDG_RLR寄存器具有写保护功能。要修改这两个寄存器的值,必须先向IWDG_KR寄存器中写入0x5555。将其他值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装载操作(即写入0xAAAA)也会启动写保护功能。 以下为看门狗超时时间说明表: 结合上表,正确的计算IWDG看门狗超时时间的公式为: Tout=(4 * 2^PR * (RL+1) ) / 40 ms 其中Tout为看门狗溢出时间(单位为ms);PR为看门狗时钟预分频值(IWDG_PR值),范围为0~7,0对应4分频,1对应8分频,......所以时间计算公式要乘以4;RL为看门狗的重装载值(IWDG_RLR的值)。 注意事项:看门狗的时钟不是准确的 40KHz,所以在喂狗的时候,最好不要太晚了,否则有可能发生看门狗复位! 2.IWDG中断做延时功能 为了满足某些场合的需求,可将IWDG产生的复位更改配置为产生中断,从而实现类似定时器的更新中断功能。 在初始化IWDG的时候,需要将 LSI 时钟开启,将 CR bit0 位置为“溢出后产生中断 ”,以下为还需要注意的初始化代码片段: IWDG_WriteAccessCmd(0x5555); IWDG_SetPrescaler(IWDG_Prescaler); PVU_CheckStatus();//看门狗预分频更新状态位检测,该语句必须置于以上两句之后而不能在其前!!! IWDG_WriteAccessCmd(0x5555); IWDG_SetReload(Reload & 0xfff); RVU_CheckStatus();//看门狗计数器重装载值更新状态位检测,该语句必须置于以上两句之后而不能在其前!!! 以下为看门狗中断服务程序中要注意的代码片段: void WWDG_IRQHandler(void) { LED2_OFF();//用作调试,指示延时时间 CR bit1 清除IWDG中断标志 Write_Iwdg_ON(IWDG_Prescaler_4,992);//必须重新配置并开启看门狗!!! EXTI_ClearFlag(EXTI_Line24);//清除外部中断线标志,以实际芯片的映射为准 LED2_ON(); } 注意事项: IWDG 看门狗的时钟不是准确的 40KHz ,且进出中断都会消耗时间,不建议用此方式来做精准的延时 ! 3.IWDG硬件看门狗模式 在某些严苛的应用环境下软件看门狗可能都已经跑飞或者无法正常生效,就需要开启硬件看门狗来作为系统稳定运行的保障。MM32 MCU的IWDG具有软件看门狗和硬件看门狗模式,默认状态下为软件看门狗模式。 如果用户在选择字节中启动了‘硬件看门狗’功能,在系统上电复位后,看门狗会自动开始运行 而不需要软件开启看门狗;硬件看门狗开启后如同软件看门狗一样,需要及时做喂狗处理,否则系统会产生复位;该模式开启后,在调试程序时也无法停止和关闭看门狗,想要关闭则必须对选项字节对应位进行修改或者擦除 。 以下为可供参考的实现功能的样例代码片段: RCC_LSICmd(ENABLE);//LSI启动并且等待LSI起振标志位置位 while ((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)&&temp<250) { temp++; //delay_ms(10); } =250)return 1;//LSI启动超时,出错返回 OBR&FLASH_OBR_WDG_SW)//若为软件看门狗,首次运行会进这里 { //Write_Iwdg_ON(IWDG_Prescaler_32,0xFFF);//可根据实际需求改变预分频值和重载值 FLASH_Unlock(); FLASH_UserOptionByteConfig(OB_IWDG_HW,OB_STOP_NoRST,OB_STDBY_NoRST);//改用硬件看门狗,写法一 //FLASH_ProgramOptionHalfWord(0x1ffff802,0,0x00FE);//改用硬件看门狗,写法二 FLASH_Lock(); NVIC_SystemReset();//复位以生效Flash的操作 } 注意事项: 建议不同版本的芯片都将LSI启动以保证硬件看门狗正常开启! 4.IWDG与低功耗模式 在开发中经常会用到独立看门狗(IWDG)和低功耗模式,看门狗是为了检测和解决由软件错误引起的故障,低功耗模式是为了在 CPU 不需要继续运行时进入到休眠模式用以节省电能。其中独立看门狗的时钟由独立的 RC 振荡器提供,即使在主时钟出现故障时,也仍然有效,因此可以在停止和待机模式下工作。 IWDG可以在低功耗模式下正常计数,它的复位能够使系统退出Standby模式。 IWDG与 Stop 低功耗模式共存的解决思路有——进 Stop 低功耗模式之前把 LSI 时钟关闭,这样就关掉了看门狗的时钟使得看门狗不工作;系统如果具备 RTC 功能,可以使用闹钟定时喂狗,喂完狗再继续休眠。比如看门狗复位的时间间隔为 10s 。那么在进入休眠模式前设置 RTC 闹钟中断时间为 5s 。这样每隔 5s 唤醒一次喂一次狗,便可以很好的解决这个问题。 5. 使用高速振荡器时钟计算内部LSI时钟频率 在 使用内部LSI时钟作为RTC的计数时钟 源时 , 考虑到 LSI的频率 为 40 KHz 左右 但不准确 , 在设置 RTC 的预分频值时可能需要先计算到较为准确的LSI时钟频率。通过 IWDG 复位的协助可以实现此功能,以下为大致思路: IWDG的应用案例分享到这, 原创第三篇,祝大家身体健康,工作顺利! Have fun!GGSD,DDUP!
  • 热度 19
    2013-7-9 20:08
    904 次阅读|
    1 个评论
     STM32F10x系列内置有两个看门狗:独立看门狗(IWDG)和窗口看门狗(WWDG)。    独立看门狗由内部专门的40Khz低速时钟驱动,即使主时钟发生故障,它也仍然有效。但是,独立看门狗的时钟并不是准确的40Khz,而是在30~60Khz之间变化的一个时钟。     使用独立看门狗我们需要用到几个寄存器:     1)键寄存器(IWDG_KR),在键寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从复位值0xFFF递减计数。当计数器计数到末尾0x00时,会产生一个复位信号(IWDG_RESET)。无论何时,只要键寄存器IWDG_KR总被写入0xAAAA,IWDG_RLR中的值就会被重新加载到计数器中从而避免产生看门狗复位。     2)预分频寄存器(IWDG_PR),低3位有效,具有写保护功能。要改变预分频因子,I状态寄存器(WDG_SR)的PVU位必须为0.     3)重装载寄存器(IWDG_RLR)低12位有效,具有写保护功能。每当向键寄存器(IWDG_KR)写入0xAAAA时,重装载值会被传送到计数器中,随后计数器从这个值开始递减计数。      启动独立看门狗需要进行一下操作:     1)向键寄存器(IWDG_KR)写入0x5555,通过写入值取消预分频寄存器(IWDG_PR)和重装载寄存器(IWDG_RLR)的写保护。喂狗时间:Tout=40Khz/(4*2^prer)*rlr)     2)向键寄存器(IWDG_KR)写入0xAAAA,是STM32重新加载IWDG_RLR的值到看门狗计数器里面。     3)向键寄存器(IWDG_KR)写入0xCCCC,启动STM32的看门狗。 参考程序: /*************************************************************************************** **************************************************************************************** * FILE : IWDG.c * Description : Init Independent watchdog  *  prer:Prescaler : 0~7   (the last 3 bit are effective) *  Division factor=4*2^prer. =256 *  rlr::IWGD_RLR: low 12 bit are effective *  Time calculate:  Tout=40K/((4*2^prer)*rlr)   *   * Study STM32 record. *  * History:           LED0             PB.0           KEY01           PB.5           KEY00           PB.4  KEY10           PC.10 * Version Name       Date Description        1.0                  Penny        2013/6/18         **************************************************************************************** ****************************************************************************************/    #include "ms5.h"   void IWDG_Init(u8 prer, u16 rlr) { IWDG-KR=0x5555;       //使能预分频寄存器IWDG-PR 和重装载寄存器IWDG-RLR写功能   IWDG-PR=prer;         //设置预分频值: LSI/32=40Khz/4*2^pre IWDG-RLR=rlr;          //设置重加载值: 重加载寄存器IWDG-RLR IWDG-KR=0xAAAA;    //按照IWDG重装载寄存器的值重装载IWDG计数器 IWDG-KR=0xCCCC;    //使能看门狗 }     //喂独立看门狗 void IWDG_Feed(void) { IWDG-KR=0xAAAA;      //reload }  
相关资源