//*****************************************************   
//Copyright (c) 2024, 苏州华芯微电子股份有限公司
//All rights reserved                                 
//
//文件名称: HS16F1886-TP0
//摘    要: HS16F1886-TP0功能演示
//  	    TP0周期定时溢出中断演示
//
//当前版本: 1.0                                      
//作    者: 华芯微MCU组
//完成日期: 2025.08.22
//*****************************************************   
//Files include 
#include 	"hs16p1886.h" 
#include 	"main.h"		


//***********************宏定义*****************************
#define  unchar     unsigned char 
#define  unint      unsigned int
#define  unlong     unsigned long

#define  u8     	unsigned char 
#define  u16      	unsigned int
#define  u32     	unsigned long


//**所有中断统一入口，没有优先级区分，只能靠软件查询顺序排优先级***//
void interrupt myIsr(void)
{
	if(TP0IF)//检查TP0溢出中断
	{
		TP0IF=0;
		PB1 = ~PB1;//PB1翻转
		//100us中断一次，取决于PWM0PL
	}
	
	if(PBIF)//检查PORTB变化中断
	{
		PBIF = 0; 
		
		
	}
}


void main(void) 
{
	sys_gpio_init(); //系统寄存器和GPIO配置
	clr_all_ram();   //清所有ram
	
	WDT_Init();		//看门狗初始化
	tp0_tim_init();	//tc0初始化
	
	GIE = 1;		//开总中断
	while(1)
	{
		CLRWDT;	//清看门狗
	}
}




/**
  * @brief  tp0定时器初始化函数,
  *
  * @note   tp0如果选Fosc,Fosc是固定的16Mhz
  * @note   - 本示例使用Fpcu的4分频作为tp0时钟，也就是tp0时钟为1Mhz，则TP0溢出周期为256-PWM0PL
  * @note   - 注意TP0只支持上溢出，所以重装载值向上增加到256溢出
  *           
  * @retval None
  */
void tp0_tim_init(void)
{	
	//;Timer register 周期:100us
	PWM0TL = 156;    //定时器TP0计数值
	PWM0PL = 156;	 //重装载值,TP0只支持上溢出,则100个tp0时钟则溢出，所以本例程100us中断一次
					 //TP0溢出周期为256-PWM0PL
					 //若填156则100个tp0时钟溢出，若填0则256个tp0时钟溢出
	
	PWMPSCON = 0X00;//---- -000
	//Bit2~Bit0：PWMPS[2:0]：PWM0 输出端口选择； 000=PB0,001=PB1,010=PB2,011=PB3,100=PB4,101=PB5
	
	//control register
	PWM0C  = 0x4a;	//01-- 1-10//Fcpu/4=4MHz/4=1MHz
					//Bit3：PWM0S1：PWM0 输出取反位; 	0=DIS,1=EN
					
					//Bit7: CK0[3]：tp0时钟源选择位 0:Fcpu作为时钟; 1:Fosc/16M作为时钟
					//Bit6:Bit1-0  => CK0[2:0]:TC0 时钟分频选择位
					//CK0[2:0]		Fcpu作为时钟(CK0[3]=0)		Fosc/16M作为时钟(CK0[3]=1)
					// 000				Fcpu/256					Fosc/128
					// 001				Fcpu/128                	Fosc/64
					// 010				Fcpu/64                 	Fosc/32
					// 011				Fcpu/32                 	Fosc/16
					// 100				Fcpu/16                 	Fosc/8
					// 101				Fcpu/8                  	Fosc/4
					// 110				Fcpu/4                  	Fosc/2
					// 111				Fcpu/2						Fosc/1
	
	//;enable register	 
	PWM0EN = 0x81;	//1--- --01
					//;Bit7：TP0EN:TP0定时器总使能;				0=DIS,1=EN
					//;Bit1：PWM0EN:PWM0输出控制位; 			0=DIS,1=EN
					//;Bit0：LOADEN:PWM重装使能(重装周期寄存器);0=DIS,1=EN
					
	TP0IE	=	1;	//开启TP0溢出中断
}



//*********************************************************************** 
/****WDT overflow reset，have no wakeup funtions****；
	则看门狗复位时间仅由烧录配置：288ms；512ms；766ms；1024ms；
*/
void WDT_Init(void)
{
	CLRWDT;
	 
//;option attentions 
	OPTION= 0b00000000; //-000 0000
			//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
			//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;0-falling edge, 1-rising edge
		
	
//;PCON 
	PCON  = 0b10100000;	//100- ----	
			//;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			//;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN			
}
 
//****GPIO configuration****//
void sys_gpio_init(void)
{
	OPTION= 0b00000000;//0000 0000	
			//;Bit7：INT1EDG：外部中断1触发方式选择位（PB1）;0-falling edge, 1-rising edge
			//;Bit6：INTEDG：外部中断触发方式选择位（PB0）	;0-falling edge, 1-rising edge
			
	
	PCON  = 0b10100000;	//101- ----		
			//;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			//;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN
	
	//PORTB //----------------------------------------------------------------------
	PORTB = 0b00000000;	//0000 0000 :PORTB数据寄存器
	TRISB = 0b00000000;	//--00 0000 :PORTB输入输出配置寄存器 (0-OUT;1-IN)
	WUCON = 0b00000000;	//--00 0000	:PORTB变化中断唤醒寄存器 (1-EN;0=DIS)
	ODCON = 0b00000000;	//--00 0000 :PORTB开漏寄存器 (1-EN;0-DIS)
	PHCON = 0b11111111;	//--11 1111 :PORTB上拉寄存器 (1-DIS;0-EN)
	
	PDCON = 0b11111111;	//0000 ---- :bit7:4 PORTB3:0下拉寄存器;1-DIS;0-EN
	PDCON1= 0b11111111;	//---- --11 :bit1:0 PORTB5:4下拉寄存器;1-DIS;0-EN
	//----------------------------------------------------------------------
}


//****************************************************  
//清除所有ram 
//C中嵌入ASM，指令操作特殊寄存器前面需要加下划线“_”;
//****************************************************    
void clr_all_ram(void)
{
	STATUS &= 0x1F;
#asm  
	MOVLW	0X3F
	MOVWF	040H
	MOVLW	0X7F
	MOVWF	_FSR
	
BANK0_RAM_CLR_LOOP:	
	CLRF	_INDF
	DECF	_FSR,F
	DECFSZ	040H,F
	GOTO	BANK0_RAM_CLR_LOOP
#endasm
}

/*-------------------------------------------------
 *  函数名：DelayMs
 *	功能：  软件延时函数
 *  输入：  延时时间 单位 MS 存在一定的误差 8M2分频情况下，未开优化
 *  输出：  无
 --------------------------------------------------*/	
void DelayMs(unsigned char delayMs)
{
	unsigned int delay_us;
	while(delayMs--)
	{
		delay_us=285;
		while(delay_us--);
	}
}


//****delay function****// 
//;Fcpu=1MHz;DelayUs = 11+7x     
void DelayUs(unsigned char delayUs)
{      
	while(delayUs--);    
} 