上午搞定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条评论)
登录后参与讨论