原创 STM32窗口看门狗使用?(WWDG)

2008-12-14 19:18 9592 15 15 分类: MCU/ 嵌入式

    上午搞定RTC之后,开始弄IWDG和WWDG,IWDG比较容易,配置也很简单,参考ST的代码就能很快搞定.但是WWDG就不行了,搞了很久都不行,按ST的库做,在keil上仿真也不行,主要原因就是WWDG->CR寄存器中的计数值不会减少!


      其他配置也都正确了,WWDG->CR就是不减少,我不知道是不是PCLK1的时钟没有,但是从keil的仿真可以看到PCLK1的时钟是36M,没道理没有,很是郁闷,不知道哪位朋友用过STM32的WWDG没有?请指教!


多谢先.


我用的是STM32F103RBT6.


主函数:


#include "stm32f10x_lib.h"
#include "sys.h"  
#include "led.h"
#include "delay.h" 
#include "wwdg.h"          
int main(void)//GPIO
{  
 //u32 temp;     
 Stm32_Clock_Init();//系统时钟设置      
    led_init();
 //DBGMCU->CR=0X00000000;
 delay_init(72);//72M系统时钟
    //delay_ms(300);
 wwdg_init();   //配置并使能IWDG   
 //temp=DBGMCU->CR;
 while (1)
    {       
     LED0_SET(0);
  //WWDG->CR&=~(1<<6);
  delay_us(500000);//在这里系统重启          
    }     
}
 


wwdg.h代码:


#ifndef __WWDG_H
#define __WWDG_H
//看门狗定时器中断配置
void NVIC_WWDGConfiguration(void)
{
 NVIC_InitTypeDef NVIC_InitStructure; 
 #ifdef  VECT_TAB_RAM           
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
 #else  /* VECT_TAB_FLASH  */        
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
 #endif     
 NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQChannel;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 NVIC_Init(&NVIC_InitStructure);
}
void wwdg_init(void)

 NVIC_WWDGConfiguration();
        
 RCC->APB1ENR|=1<<11; //窗口看门狗时钟使能.       
   WWDG->CFR|=1<<8;     //CLKww=PCLK1/4096/8=244Hz
   WWDG->CFR|=1<<7;  


 WWDG->CFR&=0X380; 
 WWDG->CFR|=65;   //窗口值设置为65
 
 WWDG->CR=0X7F;   //计数值设定为0X7F
 WWDG->CR|=1<<7;      //开启看门狗   
 
 WWDG->SR&=0XFFFFFFFE;//清除EWIF位
 
 WWDG->CFR|=1<<9;     //提前唤醒中断
}
//串口看门狗中断
void WWDG_IRQHandler(void)
{        
   WWDG_SetCounter(0x7F);   
   WWDG_ClearFlag(); 
}
#endif  


sys.h中的代码:


#ifndef __SYS_H
#define __SYS_H    
#include "stm32f10x_lib.h"
//系统时钟初始化
//使用外部8M晶振,PLL到72M频率     
//正点原子@SCUT
//2008/12/04
#define uint unsigned int
#define uchar unsigned char
/*
#define CLOCK 72/8 //时钟=72M


//us延时函数
void delay_us(unsigned int us)
{
 u8 n;     
 while(us--)for(n=0;n<CLOCK;n++);  
}
//ms延时函数
void delay_ms(unsigned int ms)
{
 while(ms--)delay_us(1000); 
} */


//把所有时钟寄存器复位
void RCC_RESETInit(void)
{
 RCC->APB2RSTR = 0XFFFFFFFF;//外设复位   
 RCC->APB1RSTR = 0XFFFFFFFF;            
 RCC->APB2RSTR = 0X00000000;//复位恢复   
 RCC->APB1RSTR = 0X00000000; 
    
   RCC->AHBENR = 0x00000014;  //flash时钟,闪存时钟使能.DMA时钟关闭  
   RCC->APB2ENR = 0x00000000; //外设时钟关闭.     
   RCC->APB1ENR = 0x00000000;  
 RCC->CR |= 0x00000001;     //使能内部高速时钟HSION                 
 RCC->CFGR &= 0xF8FF0000;   //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]     
 RCC->CR &= 0xFEF6FFFF;     //复位HSEON,CSSON,PLLON
 RCC->CR &= 0xFFFBFFFF;     //复位HSEBYP      
 RCC->CFGR &= 0xFF80FFFF;   //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
 RCC->CIR = 0x00000000;     //关闭所有中断
}


//外部8M,则得到72M的系统时钟 
void Stm32_Clock_Init(void)
{
 unsigned char temp="0";
 u8 timeout="0";
 RCC_RESETInit();
 RCC->CR|=0x00010000;  //外部高速时钟使能HSEON


 timeout=0;
 while(!(RCC->CR>>17)&&timeout<200)timeout++;//等待外部时钟就绪 


 //0-24M 等待0;24-48M 等待1;48-72M等待2;(非常重要!)   
 FLASH->ACR|=0x32;//FLASH 2个延时周期


 RCC->CFGR|=0X001D2400;//APB1/2=DIV2;AHB=DIV1;PLL=9*CLK;HSE作为PLL时钟源
 RCC->CR|=0x01000000;  //PLLON


 timeout=0;
 while(!(RCC->CR>>25)&&timeout<200)timeout++;//等待PLL锁定


 RCC->CFGR|=0x00000002;//PLL作为系统时钟
 while(temp!=0x02&&timeout<200)     //等待PLL作为系统时钟设置成功
 {  
  temp=RCC->CFGR>>2;
  timeout++;
  temp&=0x03;
 } 
}
#endif


delay.h中的代码:


#ifndef __DELAY_H
#define __DELAY_H      
//使用SysTick的普通计数模式对延迟进行管理
//包括delay_us,delay_ms 
//正点原子@SCUT
//2008/12/13 
static u8  fac_us=0;//us延时倍乘数
static u16 fac_ms=0;//ms延时倍乘数
//初始化延迟函数
void delay_init(u8 SYSCLK)
{
 SysTick->CTRL&=0xfffffffb;//选择内部时钟 HCLK/8
 fac_us=SYSCLK/8;     
 fac_ms=(u16)fac_us*1000;
}           
//延时Nms
//注意Nms的范围
//Nms<=0xffffff*8/SYSCLK
//对72M条件下,Nms<=1864
void delay_ms(u16 nms)
{   
 SysTick->LOAD=(u32)nms*fac_ms; //时间加载 
 SysTick->CTRL|=0x01;               //开始倒数   
 while(!(SysTick->CTRL&(1<<16)));   //等待时间到达
 SysTick->CTRL&=0XFFFFFFFE;         //关闭计数器
 SysTick->VAL=0X00000000;           //清空计数器    
}  
//延时us          
void delay_us(u32 Nus)

 SysTick->LOAD=Nus*fac_us;       //时间加载     
 SysTick->CTRL|=0x01;            //开始倒数   
 while(!(SysTick->CTRL&(1<<16)));//等待时间到达
 SysTick->CTRL=0X00000000;       //关闭计数器
 SysTick->VAL=0X00000000;        //清空计数器    

#endif


led.h中没什么其他配置,应该不影响WWDG的,希望高手指教阿!


 

文章评论0条评论)

登录后参与讨论
我要评论
0
15
关闭 站长推荐上一条 /2 下一条