M0驱动历程里面的wdt_wakeup,调试时发现,WDT_SetInterval(4)函数,设置为4、5、6、7时,看门狗唤醒正常,设置为1、2、3时,系统上电,可以进入睡眠和唤醒2次,然后就没有反应了。。。
下面是程序:
/*---------------------------------------------------------------------------------------------------------*/
/* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
/*---------------------------------------------------------------------------------------------------------*/
/***************************************************************************************
WDT唤醒MCU。烧录完代码后,给芯片掉电,再上电,开始执行代码,执行情况可在超级终端上显示
****************************************************************************************/
#include "Common.h"
#include "led.h"
void WDT_Init(void);
void WDT_SetInterval(uint32_t interval);
void delay(void);
unsigned int sys_index=0;
unsigned int led_标志寄存器=0;
int main(void)
{
Un_Lock_Reg(); //解锁被保护的寄存器位,以便用户访问
PWRCON |= XTL12M_EN; //使能外晶振
while((CLKSTATUS & XTL12M_STB) == 0); //等12M时钟稳定
PWRCON |= OSC10K_EN; //使能10K时钟
while((CLKSTATUS & OSC10K_STB) == 0); //等10K时钟稳定
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //选12M为系统时钟
Lock_Reg(); //重新锁被保护的寄存器位
//UART_Init(); //初始化串口
//printf("Press Enter key to start...\n");
//getchar();
WDT_Init(); //初始化WDT
Un_Lock_Reg();
WDT_SetInterval(4); //设定WDT超时间
WTCR |= CLRWTR; //清零WDT
Lock_Reg();
LED_Init();
while(1)
{
//printf("Enter power down mode...\n");
if(!led_标志寄存器)
{
LED_BLUE_ON();//开发光管
led_标志寄存器=1;
}
else
{
LED_BLUE_OFF();//关发光管
led_标志寄存器=0;
}
//delay();
Un_Lock_Reg();
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_10K; //选12M为系统时钟
SCR |= SLEEPDEEP; //通知M0内核MCU要进入深度休眠模式
PWRCON &= ~PD_WU_IE; //休眠醒来时不产生中断
PWRCON &= ~PD_WAIT_CPU; //不需等待WFI指令即可进入掉电模式
PWRCON |= PWR_DOWN_EN; //允许MCU进入掉电模式
Lock_Reg();
delay();
Un_Lock_Reg();
CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M;
Lock_Reg();
}
}
/***************************************************************************************
描述 : WDT中断代码
****************************************************************************************/
void WDT_IRQHandler(void)
{
Un_Lock_Reg();
WTCR |= WTWKF; //清除WDT复位标志
WTCR |= WTIF; //清除WDT超时中断标志
Lock_Reg();
//printf("WDT interrupt!\n");
}
/***************************************************************************************
描述 : WDT初始化,时钟源选10KHz
****************************************************************************************/
void WDT_Init(void)
{
Un_Lock_Reg();
APBCLK |= WDT_CLKEN; //使能WDT时钟
CLKSEL1 = (CLKSEL1 & (~WDT_CLK)) | WDT_10K; //WDT时钟源选10KHz
WTCR &= ~WTRE; //禁止WDT复位芯片
WDT_SetInterval(0); //设定WDT超时间隔
WTCR |= WTIE; //使能WDT超时中断
NVIC_ISER = WDT_INT;
WTCR |= WTWKE; //使能WDT唤醒功能
WTCR |= WTE; //使能WDT
Lock_Reg();
}
/***************************************************************************************
描述 : 选WDT周期
****************************************************************************************/
void WDT_SetInterval(uint32_t interval)
{
WTCR = (WTCR&(~WTIS)) | (interval<<8); //设置WDT超时间隔
//WTCR=WTCR|(interval<<8);
}
void delay(void)
{
volatile uint32_t i;
for (i=0; i<100; i++);
}
|