STM32F4 看门的使用

IWDG (独立看门狗):用于那些需要一个看门狗在主程序之外能够独立工作并且对时间精度要求较低的场合
 1.时钟由独立RC振荡器提供(可工作在停止和待机模式下)
 2.看门狗被激活后,则在计数器计到0x000是产生复位 3.在寄存器(IWDG_KR)中写入0xCCCC,开始启用独立看门狗;此时计数器开始从其复位值0xFFF递减计数。当计数器寄到末尾0x000时会产生一个复位信号(IWDG_RESET)。无论何时,只要在寄存器IWDG中写入IWDG_KR中写入0xAAAA,IWDG_RLR中的值就会被重新加载到计数器,从而避免产生看门狗复位。
 4.如果用户在选择字节中启用了“硬件看门狗”,在系统上电复位后,看门狗会自动开始运行;如果在计数器结束前,若软件没有向寄存器写入相应的值,则系统会产生复位。
 5.寄存器访问保护
  IWDG_PR和IWDG_RLR寄存器具有写保护功能。要修改这两个寄存器的值,必须先向IWDG_KR寄存器中写入0x5555.以不同的值写入这个寄存器将会打乱操作顺序,寄存器将重新被保护。重装在操作(写入0xAAAA)也会启动写保护功能。状态寄存器指示预分配寄存器跟递减计数器是否正在被更新。
 6.IWDG 库
  IWDG_ReloadCounter()       防止系统复位
  
  分频器和计数器配置函数
  void IWDG_WriteAccessCmd(unit16_t IWDG_WriteAccess) 使能写寄存器IWDG_PR和IWDG_RLR
  void IWDG_SetPrescaler(unit8_t IWDG_Prescaler)   设置 IWDG 预分频值
  void IWDG_SetReload(uint16_t Relaod)     设置 IWDG 重装载值
  void IWDG_ReloadCounter(void)
  
  看门狗激活函数
  void IWDG_Enable(void)使能看门狗
  
  标志管理函数
  FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG) 用于检测看门狗标志
  
 7.程序设计步骤
  a.取消寄存器写保护 向 IWDG_KR 写入 0X5555 
   IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  b.设置独立看门狗的预分频系数和重装载值  Tout=((4×2^prer) × rlr) /40 (prer 预分频值,rlr 重装载值)
   IWDG_SetPrescaler(4);   // 设置 IWDG 预分频值
   IWDG_SetPrescaler(625);   // 设置 IWDG 重装载值 Tout = 1000ms
  c.重载计数值喂狗
   IWDG_ReloadCounter();   // 按照 IWDG 重装载寄存器的值重装载 IWDG 计数器
  d.启动看门狗(向 IWDG_KR 写入 0XCCCC)
   IWDG_Enable();      //使能 IWDG
注意:看门狗的时钟不是准确的 40Khz,所以在喂狗的时候,最好不要太晚了,否则,有可能发生看门狗复位。
   
 //初始化独立看门狗
 //prer:分频数:0~7(只有低 3 位有效!) rlr:自动重装载值,0~0XFFF.
 //分频因子=4*2^prer.但最大值只能是 256!
 //rlr:重装载寄存器值:低 11 位有效.
 //时间计算(大概):Tout=((4*2^prer)*rlr)/32 (ms).
 void IWDGInit(uint8_t prer,uint16_t rlr)
 {
  IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //取消寄存器写保护
  IWDG_SetPrescaler(prer); //设置 IWDG 分频系数
  IWDG_SetReload(rlr); //设置 IWDG 装载值
  IWDG_ReloadCounter(); //reload
  IWDG_Enable(); //使能看门狗
 }
 
 //喂独立看门狗
 void IWDG_Feed(void)
 {
  IWDG_ReloadCounter();//reload
 }
 
WWDG(窗口看门狗):通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障
 1.可编程的自由运行递减计数器
 2.条件复位
  当递减计数器值小于0x40,若看门狗被启动则产生复位;
  当递减计数器在窗口外被重新装载,若看门狗被启动则产生复位
 3.若果启动了看门狗并允许中断,当递减计数器等于0x40是产生早起唤醒中断(EWI),他可以被用于重装载计数器避免WWD复位。
 4.应用程序在正常运行过程中必须定期的写入WWDG_CR寄存器以防止MCU发生复位。只有当计数器值小于窗口寄存器时,才能进行写操作。存储在WWDG_CR寄存器中的数值必须在0xff和0xc0之间。
 5.实际的复位产生前,如果需要执行专门的安全操作或者记录数据,则EWI中断就派上了用场。EWI终端有WWDG_CFR的EWI使能位。当计数器计到0x40的时候,EWI中断将产生,在设备复位前,我们可以在中断服务程序里面执行或者数据记录。
 6.WWDG库
  分频器,窗口刷新,计数器配置函数
  void WWDG_DeInit(void)
  void WWDG_SetPrescaler(uint32_t WWDG_Prescaler)
  void WWDG_SetWindowValue(uint8_t WindowValue)
  void WWDG_EnableIT(void)
  void WWDG_SetCoounter(uint8_t Counter)
  独立看门狗激活函数
  void WWDG_Enable(uint8_t Counter)
  中断标志管理
  FlagStatus WWDG_GetFlagStatue(void)
  void WWDG_CLearFlag(void)
 7.程序设计步骤
  a.使能 WWDG 时钟
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);  // WWDG 时钟使能
  b.设置窗口值和分频数
   void WWDG_SetWindowValue(uint8_t WindowValue);   // 设置窗口值
   void WWDG_SetPrescaler(uint32_t WWDG_Prescaler);  // 设置分频数
   Twwdg=(4096×2^WDGTB×(T[5:0]+1)) /Fpclk1; Twwdg: WWDG 超时时间(ms),Fpclk1: APB1 的时钟频率(Khz) WDGTB: WWDG 的预分频系数 T[5:0]:窗口看门狗的计数器低 6 位
  c.开启 WWDG 中断并分组
   WWDG_EnableIT(); //开启窗口看门狗中断
  d.设置计数器初始值并使能看门狗
   void WWDG_Enable(uint8_t Counter);      // 该函数既设置了计数器初始值,同时使能了窗口看门狗
   void WWDG_SetCounter(uint8_t Counter);     // 独立的设置计数器值
  e.编写中断服务函数
  

注意:当写入WWDG_CR 寄存器时,始终置 T6 为‘1’,以避免立即产生以复位
   窗口值必须大于0x40 ,否则窗口就不存在了
  
 u8 WWDG_CNT=0X7F;
 //初始化窗口看门狗
 //tr :T[6:0],计数器值 wr :W[6:0],窗口值
 //fprer:分频系数(WDGTB) ,仅最低 2 位有效
 //Fwwdg=PCLK1/(4096*2^fprer). 一般 PCLK1=42Mhz
 void WWDG_Init(u8 tr,u8 wr,u32 fprer)
 {
  NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
  //使能窗口看门狗时钟
  WWDG_CNT=tr&WWDG_CNT; //初始化 WWDG_CNT.
  WWDG_SetPrescaler(fprer); //设置分频值
  WWDG_SetWindowValue(wr); //设置窗口值
  WWDG_SetCounter(WWDG_CNT);//设置计数值
  WWDG_Enable(WWDG_CNT); //开启看门狗
  NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为 2
  NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //响应优先级为 3
  NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
  NVIC_Init(&NVIC_InitStructure);
  WWDG_ClearFlag();//清除提前唤醒中断标志位
  WWDG_EnableIT();//开启提前唤醒中断
 }
 //窗口看门狗中断服务程序
 void WWDG_IRQHandler(void)
 {
  WWDG_SetCounter (WWDG_CNT); //重设窗口看门狗值
  WWDG_ClearFlag();//清除提前唤醒中断标志位
  LED1=!LED1;      // LED等翻转一次
 } 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

posted @ 2017-06-22 09:20  躬技手昏  阅读(300)  评论(0)    收藏  举报