//*****************************************************   
//Copyright (c) 2021, 苏州华芯微电子股份有限公司
//All rights reserved                                 
//
//文件名称: HS16F3211_WAKEUP_TC0
//摘    要: HS16F3211休眠，定时器唤醒功能演示
//  		程序进入睡眠，TC0溢出唤醒  500MS 唤醒一次 
//
//当前版本: 1.0                                      
//作    者: 华芯微MCU组
//完成日期: 2021.09.14
//*****************************************************   

#include 	<hs16f3211.h> 

//***********************宏定义*****************************
#define  unchar     unsigned char 
#define  unint      unsigned int
#define  unlong     unsigned long
#define  DemoPortOut	FPB0
#define  DemoPortOut1	FPB1

#define	NOP()		asm("NOP")    
#define	CLRWDT()	asm("clrwdt")    
#define	SLEEP()		asm("sleep")    



/*-------------------------------------------------
 *  函数名：GPIO_Init
 *	功能：  GPIO设置
 *  输入：  无
 *  输出：  无
 --------------------------------------------------*/	
void GPIO_Init(void) 
{ 
	OPTION = 0b00000010;//Bit7 INT1EDG, 外部中断1触发方式 0 INT1引脚下降沿触发
                        //Bit6 INTEDG, 外部中断 触发方式 0 INT引脚下降沿触发
                        //Bit5 T0CS, TMR0时钟源选择位 0 内部指令时钟
                        //Bit4 T0SE, TMR0时钟源边沿选择位 0 T0CKI引脚下降沿触发计数
                        //Bit1 PSA, 预分频分配位 0 预分频器分配给TMR0
                        //Bit2:0 PS[2:0], 预分频配置 010 '8分频
    PORTA = 0b00000000;	
    IOSTA = 0b00000000;	//PA输入输出 0-输出 1-输入
                        //PA口->全输出

    PORTB = 0b00000000;	
    IOSTB = 0b00000000;	//PB输入输出 0-输出 1-输入
                        //PB口->全输出
}


//**************中断处理**********************************
void interrupt ISR(void)  //空
{
   
}

/*-------------------------------------------------
 *  函数名：delay_ms
 *	功能：  写入参数 x,可以延时xMS
 *  输入参数：  x
 --------------------------------------------------*/	
void delay_ms(unint x)
{
	unint i,j;
	for(i=0;i<x;i++)
	{	
		for(j=0;j<140;j++);
	}
}

/*-------------------------------------------------
 *  函数名：TC0_WAKEUP_SET
 *	功能：  500MS唤醒一次睡眠。(睡眠后，TC0高速时钟停止，TC0低速时钟为16KHZ)
 *  TC0R重装载值计算方法 ：睡眠后系统时钟停止,TC0时钟变为 16KHZ ,  若选择32分频. TC0时钟为1/2KHZ  计时500MS      
             : 唤醒时间 = （TC0时钟/分频数）*（256-计数器初值 ）；
             ：所以  计数器初值 TC0R = 256-250 = 6; 
             ：500MS = (16KHZ/32)*(256-TC0L)；   
 --------------------------------------------------*/	
void TC0_WAKEUP_SET(void) //配置500MS 唤醒一次睡眠 ，睡眠后 TC0时钟为16K ，选择32分频 
{  		                
		TC0M = 0x30;//20;	//选择 8位计数器，32分频
						//0010 0000;//Fcpu 64'-8bit-   //定时器TC0时钟配置
		             	//Bit7 TC0TR, TC0启动控制位 0 禁止TC0定时器
                        //Bit6:4 TC0S[2:0], TC0分频选择位 011 32分频
                        //Bit3 TC0时钟信号选择位, 0 TC0时钟来自Fcpu
                        //BIT2 T16SEL,1  8/16位溢出位选择 0 低8位为溢出位
                        //BIT1 BUZ, BUZ输出使能位 0 关闭BUZ输出
                        //BIT0 PWM0, PWM0输出使能位 0 关闭PWM0输出
        TC0L=0X06;//06; //定时器TC0计数器初始值               
                                                       
		FTC0IF=0; 		//   TC0溢出中断标志位，TC0溢出时被置位，软件复位  
		FTC0IE=1; 		//   使能溢出中断   ;必须选择使能溢出，不置1无法唤醒睡眠
		FTC0TR=1; 		//   开启TC0定时器   
		FGIE=0;   		//   不开TC0中断,只进行TC0计时唤醒睡眠,不处理中断函数
		
		OSCM=0X10;     //-001 0000  OSCM.4=1   //TC0低速时钟控制   //打开TC0低速时钟
		               //必须要手动选择低速时钟,睡眠后高速时钟停止，如果不选择低速，TC0定时器不计数
		
		                //Bit7 空
		                //Bit6 1： 睡眠唤醒后选择高速 RC 作为系统时钟 0： 睡眠唤醒后选择内外低速作为系统时钟
		                //Bit5 1:绿色模式               0:普通模式
                        //Bit4 1:选择内外低速作为时钟   0： 选择高速 RC 作为时钟
                        //Bit3 1：关闭内外低速时钟      0：开启内外低速时钟
                        //BIT2 1：选择外部低速晶振      0：选择内部低速RC
                        //BIT1 1:停止内部高速振荡器     0：运行内部高速振荡器
                        //BIT0 1:低速模式     0:普通模式
                        			
}

/*-------------------------------------------------
 *  函数名：TC0_HIGH_CLK_RECOVER
 *	功能：  TC0时钟切换为高速时钟
 --------------------------------------------------*/	
void TC0_HIGH_CLK_RECOVER(void)//睡眠唤醒后，调用此函数TC0时钟切换为高速时钟
{
	FSLCON=0;//OSCM.4   //TC0低速时钟控制位
}


//****主函数****//
void main(void) 
{
    GPIO_Init();
    TC0_WAKEUP_SET(); //TC0睡眠唤醒设置  ;设置唤醒时间500MS唤醒一次
    while(1)
    {
    	SLEEP();        //睡眠指令
    	TC0L=0X06;      //保证下次睡眠唤醒时间为500MS,需要对 TC0L赋一次初值
	    //DemoPortOut = ~DemoPortOut;   //睡眠唤醒后PB0反转一次
    }
}
