zoukankan      html  css  js  c++  java
  • STM8S——watchdog(IWDG)

    IWDG工作原理:

      1、当键值寄存器(IWDG_KR)中写入数值0xCC后,独立看门狗就会被启动,计数器开始从它的复位值0xFF开始递减计数,当计数减到0x00时就会产生一个复位信号。

      2、使用IWDG_PR和IWDG_RLR寄存器配独立看门狗。

      (1)IWDG_PR寄存器是用于选择驱动计数器时钟的预分频系数。

      (2)当KEY_REFRESH的数值(0xAA)写入到IWDG_KR寄存器时,独立看门狗将用IWDG_RLR的数值刷新计数器的内容,从而避免了产生看门狗的复位。

      3、IWDG_PR和IWDG_RLR寄存器具有写保护功能,要修改它们前,需首先在IWDG_KR寄存器写入KEY_ACCESS代码(0x55);在IWDG_KR写入0xAA将恢复写保护状态。

     IWDG工作细节:

    1、为了避免程序忙跑跑死了没反应,加上一个看门狗watchdog实时监控着程序,一旦程序没有在规定的时间喂狗,则狗叫使得单片机复位。

    2、Independent watchdog(IWDG)内部有时钟源(128kHz),所以即使主时钟挂了watchdog还是能继续工作的。

       另外还有个Window watchdog (WWDG),比IWDG复杂得多,我们没有采用。

    3、由于内部是128kHz,所以watchdog能允许的最大延迟时间为510ms(当RL[7:0]= 0xFF时),最小延迟时间为2ms(当RL[7:0]= 0x00时);我们选取510ms。

      也就是说一旦打开看门狗,最迟每隔510ms就要进行喂狗操作,否则看门狗将会打开复位。

    4、看门狗的实现不难,难点在于怎样验证自己设置的看门狗是否正确,难点在与想办法测试watchdog。

       方法是在while(1)的循环里延时510ms以上(如延时600ms),通过对相关寄存器特征值的显示查看,来判断单片机是否被复位,若被复位则验证成功。

    5、值得注意的是,开门狗一旦打开就无法关闭,只有通过不断的喂狗来防止复位。

    6、下面给出代码思路并且附带详细注释:

       由于延时函数如果延时太久会无法实现喂狗操作,所以应该在原来的Delay1ms()函数的基础上,再另外定义一个newDelay()函数,目的是每次延时250ms时(即调用Delay1ms(250))喂狗;

      1 /*-- private variable --*/
      2 __IO uint32_t space_reloadTM = 250;//define every after 250 ms reload IWDG
      3 
      4 /*-- private function --*/
      5 void NewDelay(__IO uint32_t nTime);//include reload IWDG
      6 
      7 static void IWDG_Config_Enable(void);//config and enable IWDG
      8 
      9 
     10 /*-- main function --*/
     11 int main()
     12 {
     13     IWDG_Config_Enable(); //config and enable IWDG 
     14 
     15     //for test
     16     while (1)
     17     {
     18         Delay1ms(600); //timeout and reset happend
     19         
     20         /*-- never runs here --*/
     21       
     22         //Reload IWDG counter
     23         IWDG_ReloadCounter();
     24     }
     25 }
     26 
     27 
     28 
     29 void NewDelay(__IO uint32_t nTime)
     30 {
     31     uint32_t time_divisor = nTime/space_reloadTM;
     32     uint32_t time_remainder = nTime%space_reloadTM;
     33     uint8_t i;
     34     
     35     /* every after 250ms reload IWDG */
     36     for(i=0;i<time_divisor;i++)
     37     {
     38         Delay1ms(space_reloadTM);
     39         //Reload IWDG counter
     40         IWDG_ReloadCounter();
     41     }
     42     
     43     /* delay the remain time */
     44     Delay1ms(time_remainder);
     45     //Reload IWDG counter
     46     IWDG_ReloadCounter();
     47 }
     48 /*
     49 void Delay1ms(__IO uint32_t nTime)
     50 {
     51   TimingDelay = nTime;
     52 
     53   while (TimingDelay != 0);
     54 }
     55 */
     56 
     57 
     58 
     59 /**
     60  * @brief  Configures the IWDG to generate a Reset if it is not refreshed at the
     61  *         correct time.
     62  * @param  None
     63  * @retval None
     64  */
     65 static void IWDG_Config_Enable(void)
     66 {
     67     /* Check if the system has resumed from IWDG reset */
     68     if (RST_GetFlagStatus(RST_FLAG_IWDGF) != RESET)
     69     {
     70         printf("
    
    ");
     71         uart2str(uartbuff,RST->SR,8,2,'0');   //output RST register
     72         printf("Timeout, RST_SR=%s
    
    ",uartbuff);
     73         
     74         printf("timeout!!!");
     75         
     76         /* IWDGF flag set */
     77         /* Clear IWDGF Flag */
     78         RST_ClearFlag(RST_FLAG_IWDGF);
     79     }
     80     else
     81     {
     82         //IWDGF flag is not set
     83     }
     84     
     85     
     86     /* --- IWDG Configuration --- */
     87     
     88     /* Enable IWDG (the LSI oscillator will be enabled by hardware) */
     89     IWDG_Enable(); //0xCC
     90     
     91     /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency
     92      dispersion) */
     93     /* Enable write access to IWDG_PR and IWDG_RLR registers */
     94     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //0x55
     95     
     96     /* IWDG counter clock: LSI/128 */
     97     IWDG_SetPrescaler(IWDG_Prescaler_128);
     98     
     99     /* Set counter reload value to obtain 250ms IWDG Timeout.
    100      Counter Reload Value = 250ms/IWDG counter clock period
    101      = 250ms / (LSI/128)
    102      = 0.25s / (LsiFreq/128)
    103      = LsiFreq/(128 * 4)
    104      = LsiFreq/512
    105      */
    106     IWDG_SetReload((uint8_t)(0xFF));//510ms
    107     
    108     /* Reload IWDG counter */
    109     IWDG_ReloadCounter(); //0xAA
    110 }
    watchdog

       为了验证代码的可实现性,故意在主函数中调用Delay1ms(600),所以正确的执行结果应该是:执行Delay1ms(600),watchdog启动复位,输出timeout之类的提示;

       其中证明是否是watchdog启动的复位:查看RST->SR(Reset status register)中Bit1的值,为1表示An IWDG reset occurred,为0表示No IWDG reset occurred。

  • 相关阅读:
    SQL Server 链接服务器连接 SQLite数据库文件
    HighCharts初测试
    集锦
    MDX 脚本语句 -- Scope
    七年一轮回
    20145205武钰《网络对抗》web安全基础实践
    20145205 武钰 《网络对抗》Exp8 Web基础
    20145205《网络攻防》网络欺诈技术防范
    20145205《网络对抗》信息收集和漏洞扫描技术
    20145205武钰_Exp5 MSF基础应用
  • 原文地址:https://www.cnblogs.com/Christal-R/p/7072066.html
Copyright © 2011-2022 走看看