zoukankan      html  css  js  c++  java
  • 窗口看门狗 WWDG

    一,窗口看门狗

    二,喂狗注意事项

    三,程序设计

    1.检查复位状态,有助于观察当前工作的可靠性

     /* Check if the system has resumed from WWDG reset ,检查是否窗口看门狗导致的复位,如果发现由窗口看门狗导致的复位,输出打印信息*/
             if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
             { 
                       /* WWDGRST flag set */
                       printf("wwdg reset cpu
    ");
     
                       /* Clear reset flags */
                       RCC_ClearFlag();
             }
             else
             {
                       /* WWDGRST flag is not set */
                       printf("normal reset cpu
    ");
             }
             
             delay_ms(500);delay_ms(500);

    2.     看门狗的初始化

     

       

          /* WWDG configuration ,窗口看门狗的配置*/
             /* Enable WWDG clock ,使能看门狗的时钟*/
             RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
     
             /* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us)  */
             WWDG_SetPrescaler(WWDG_Prescaler_8);
     
             /* Set Window value to 80; WWDG counter should be refreshed only when the counter
               is below 80 (and greater than 0x40) otherwise a reset will be generated 
             设置窗口的上限值为80
             */
             WWDG_SetWindowValue(80);
     
             /* 设置计数值的初值为127,则窗口看门狗的超时时间 = 780 us * 64 = 49.92 ms 
                       这个时候窗口刷新时间如下
            ~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms
     
             
             */
             WWDG_Enable(127);
     
             //WWDG NVIC 配置
             NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;                        //窗口看门狗中断通道
             NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;               //抢占优先级0
             NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                    //子优先级0
             NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                     //IRQ通道使能
             NVIC_Init(&NVIC_InitStructure);                                   //根据指定的参数初始化VIC寄存器         
             
             
             //清空提前唤醒中断标志位
             WWDG_ClearFlag();
             
             //使能提前唤醒中断
             WWDG_EnableIT();

     

    3.     看门狗中断服务函数

    void WWDG_IRQHandler(void)
    {
             if(WWDG_GetFlagStatus()==SET)
             {
                       //进行喂狗
                       WWDG_SetCounter(127);
     
                       //清空提前唤醒中断标志位
                       WWDG_ClearFlag();         
             
             }
    }
    #include "stm32f4xx.h"
    #include "stm32f4xx_gpio.h"
    #include "stm32f4xx_rcc.h"
    #include "stm32f4xx_usart.h"
    #include "stdio.h"
    #include "sys.h"
    
    static GPIO_InitTypeDef      GPIO_InitStructure;
    static USART_InitTypeDef     USART_InitStructure;
    static NVIC_InitTypeDef     NVIC_InitStructure;        
    
    
    
    
    //重定义fputc函数 
    int fputc(int ch, FILE *f)
    {     
        USART_SendData(USART1,ch);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);  
        
        return ch;
    }   
    
    void delay_us(uint32_t nus)
    {        
        uint32_t temp;             
        SysTick->LOAD =SystemCoreClock/8/1000000*nus;     //时间加载               
        SysTick->VAL  =0x00;                            //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;         //使能滴答定时器开始倒数      
        do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));            //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;         //关闭计数器
        SysTick->VAL =0X00;                               //清空计数器 
    }
    
    void delay_ms(uint16_t nms)
    {                     
        uint32_t temp;           
        SysTick->LOAD=SystemCoreClock/8/1000*nms;        //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                               //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //能滴答定时器开始倒数 
        do
        {
            temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));            //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                               //清空计数器              
    } 
    
    void LED_Init(void)
    {         
      
        //使能GPIOE,GPIOF时钟
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE);            
    
        //GPIOF9,F10初始化设置 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10;        //LED0和LED1对应IO口
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                    //普通输出模式,
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                    //推挽输出,驱动LED需要电流驱动
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;                //100MHz
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                    //上拉
        GPIO_Init(GPIOF, &GPIO_InitStructure);                            //初始化GPIOF,把配置的数据写入寄存器                        
    
    
        //GPIOE13,PE14初始化设置 
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;        //LED2和LED3对应IO口
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                    //普通输出模式
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                    //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;                //100MHz
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                    //上拉
        GPIO_Init(GPIOE, &GPIO_InitStructure);                            //初始化GPIOE,把配置的数据写入寄存器
    
        GPIO_SetBits(GPIOF,GPIO_Pin_9  | GPIO_Pin_10);                    //GPIOF9,PF10设置高,灯灭
        GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);        
    }
    
    
    void USART1_Init(uint32_t baud)
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);                             //使能GPIOA时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);                            //使能USART1时钟
     
        //串口1对应引脚复用映射
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);                         //GPIOA9复用为USART1
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);                         //GPIOA10复用为USART1
        
        //USART1端口配置
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;                         //GPIOA9与GPIOA10
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                    //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                //速度50MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                     //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                                     //上拉
        GPIO_Init(GPIOA,&GPIO_InitStructure);                                             //初始化PA9,PA10
    
        //USART1 初始化设置
        USART_InitStructure.USART_BaudRate = baud;                                        //波特率设置
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;                        //字长为8位数据格式
        USART_InitStructure.USART_StopBits = USART_StopBits_1;                            //一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;                                //无奇偶校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    //无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                    //收发模式
        USART_Init(USART1, &USART_InitStructure);                                         //初始化串口1
        
        USART_Cmd(USART1, ENABLE);                                                      //使能串口1 
        
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                                    //开启相关中断
    
        //Usart1 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                                //串口1中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;                            //抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;                                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                    //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);                                                    //根据指定的参数初始化VIC寄存器
    }
    
    
    
    
    int main(void)
    { 
        
        LED_Init();        
    
        //系统定时器初始化,时钟源来自HCLK,且进行8分频,
        //系统定时器时钟频率=168MHz/8=21MHz
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
        
        //设置中断优先级分组2
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        
        //串口1,波特率115200bps,开启接收中断
        USART1_Init(115200);
        
        /* Check if the system has resumed from WWDG reset ,检查是否窗口看门狗导致的复位,如果发现由窗口看门狗导致的复位,输出打印信息*/
        if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) != RESET)
        { 
            /* WWDGRST flag set */
            printf("wwdg reset cpu
    ");
    
            /* Clear reset flags */
            RCC_ClearFlag();
        }
        else
        {
            /* WWDGRST flag is not set */
            printf("normal reset cpu
    ");
        }
        
        delay_ms(500);delay_ms(500);
    
        /* WWDG configuration ,窗口看门狗的配置*/
        /* Enable WWDG clock ,使能看门狗的时钟*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
    
        /* 窗口看门狗的时钟 = (PCLK1 (42MHz)/4096)/8 = 1281 Hz (~780 us)  */
        WWDG_SetPrescaler(WWDG_Prescaler_8);
    
        /* Set Window value to 80; WWDG counter should be refreshed only when the counter
          is below 80 (and greater than 0x40) otherwise a reset will be generated 
        设置窗口的上限值为80
        */
        WWDG_SetWindowValue(80);
    
        /* 设置计数值的初值为127,则窗口看门狗的超时时间 = 780 us * 64 = 49.92 ms 
            这个时候窗口刷新时间如下
            ~780 * (127-80) = 36.6ms < refresh window < ~780 * 64 = 49.9ms
    
        
        */
        WWDG_Enable(127);
    
        //WWDG NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn;                            //窗口看门狗中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;                    //抢占优先级0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                        //子优先级0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                            //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);                                            //根据指定的参数初始化VIC寄存器    
        
        
        //清空提前唤醒中断标志位
        WWDG_ClearFlag();
        
        //使能提前唤醒中断
        WWDG_EnableIT();
        
        
        while(1)
        {
    #if 0
            //进行喂狗
            WWDG_SetCounter(127);
    
            //清空提前唤醒中断标志位
            WWDG_ClearFlag();
    #endif
    
        }
    }
    
    
    void WWDG_IRQHandler(void)
    {
        if(WWDG_GetFlagStatus()==SET)
        {
            //进行喂狗
            WWDG_SetCounter(127);
    
            //清空提前唤醒中断标志位
            WWDG_ClearFlag();    
        
        }
    }
    
    
    
    void USART1_IRQHandler(void)                                //串口1中断服务程序
    {
        uint8_t d;
        
    
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)      //接收中断
        {
    
        } 
    } 
    wwdg.c

     

  • 相关阅读:
    中国登山队员首次登上地球之巅珠穆朗玛峰的时间与意义及影响 (转)
    兰戈利尔人(斯蒂芬.金)
    冥界系列一:麝月 (作者:钱其强)
    席慕容独白
    【心理寓言】小偷在鸡舍偷了只鸡
    美国恐怖故事第一季事件时间表
    大学生逃课的暴笑理由
    原来他们四个也是有故事的男人
    爆笑:七八十年代各地最流行顺口溜 网友:太经典了
    中国的世界之最
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10964839.html
Copyright © 2011-2022 走看看