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

     

  • 相关阅读:
    RecyclerView 数据刷新的几种方式 局部刷新 notify MD
    【图片】批量获取几万张图片
    RV BaseRecyclerViewAdapterHelper 总结 MD
    RecyclerView.ItemDecoration 间隔线
    Kotlin【简介】Android开发 配置 扩展
    Kotlin 特性 语法糖 优势 扩展 高阶 MD
    一个十分简洁实用的MD风格的UI主框架
    折叠伸缩工具栏 CollapsingToolbarLayout
    FloatingActionButton FAB 悬浮按钮
    Glide Picasso Fresco UIL 图片框架 缓存 MD
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/10964839.html
Copyright © 2011-2022 走看看