//*********************************************************************** 
//Copyright (c) 2024   HuaXin Micro-electronics Co.,Ltd 
//
//HS16P2811 
//T3PWM
//configuration introduction
//芯片T3定时器周期溢出功能，时钟源选Fosc
//designer:华芯微MCU组
//updata：20241105
//***********************************************************************  
//RAM: 176*8bytes
//ROM: 2K
//STACK: 8-level
//*********************************************************************** 
#include 	"main.h"		


//--------------------------------------------------------------------------------------------------
/*
	     ╔══════╗　 ╔══════╗
	VDD  ╬1 ●   ╚═══╝    16╬   GND
	PA7  ╬2              15╬   PA0
	PA6  ╬3              14╬   PA1
	PA5  ╬4              13╬   PA2
	PA4  ╬5              12╬   PA3
	PC5  ╬6              11╬   PC0
	PC4  ╬7              10╬   PC1
	PC3  ╬8              9 ╬   PC2
         ╚═════════════════╝
*/
//--------------------------------------------------------------------------------------------------
#define	DEBUG_PA0PA1	0



#define  uint64_t     	unsigned long long
#define  uint32_t     	unsigned long
#define  uint16_t      	unsigned int
#define  uint8_t     	unsigned char 

//============Define  Flag=================
typedef union {
   	unsigned char byte;
   	struct
   	{
   	   	uint8_t bit0 : 1;
   	   	uint8_t bit1 : 1;
   	   	uint8_t bit2 : 1;
   	   	uint8_t bit3 : 1;
   	   	uint8_t bit4 : 1;
   	   	uint8_t bit5 : 1;
   	   	uint8_t bit6 : 1;
   	   	uint8_t bit7 : 1;
   	} bits;
}bit_flag;




#define 	SEG1_O	   	  FPC1
#define 	SEG2_O	   	  FPC3
#define 	SEG3_O	   	  FPC4
#define 	SEG4_O	   	  FPC5
#define 	SEG5_O	   	  FPA6


#define 	SEG1_M   	  FTRISC1
#define 	SEG2_M   	  FTRISC3
#define 	SEG3_M   	  FTRISC4
#define 	SEG4_M   	  FTRISC5
#define 	SEG5_M   	  FTRISA6

////////////////
bit_flag	dsp_dat1;
	#define	b_a1_dsp	dsp_dat1.bits.bit0
	#define	b_b1_dsp	dsp_dat1.bits.bit1
	#define	b_c1_dsp	dsp_dat1.bits.bit2
	#define	b_d1_dsp	dsp_dat1.bits.bit3
	#define	b_e1_dsp	dsp_dat1.bits.bit4
	#define	b_f1_dsp	dsp_dat1.bits.bit5
	#define	b_g1_dsp	dsp_dat1.bits.bit6
	// #define	b_18dp_dsp	dsp_dat1.bt.b7

bit_flag	dsp_dat2;
	#define	b_a2_dsp	dsp_dat2.bits.bit0
	#define	b_b2_dsp	dsp_dat2.bits.bit1
	#define	b_c2_dsp	dsp_dat2.bits.bit2
	#define	b_d2_dsp	dsp_dat2.bits.bit3
	#define	b_e2_dsp	dsp_dat2.bits.bit4
	#define	b_f2_dsp	dsp_dat2.bits.bit5
	#define	b_g2_dsp	dsp_dat2.bits.bit6
	
bit_flag	dsp_dat3;
	#define	b_a3_dsp	dsp_dat3.bits.bit0
	#define	b_b3_dsp	dsp_dat3.bits.bit1
	#define	b_c3_dsp	dsp_dat3.bits.bit2
	#define	b_d3_dsp	dsp_dat3.bits.bit3
	#define	b_e3_dsp	dsp_dat3.bits.bit4
	#define	b_f3_dsp	dsp_dat3.bits.bit5
	#define	b_g3_dsp	dsp_dat3.bits.bit6


// bit_flag	dsp_dpv;
	// #define	b_dp1	dsp_dpv.bits.bit0
	// #define	b_dp2	dsp_dpv.bits.bit1
	// #define	b_k1	dsp_dpv.bits.bit2
	// #define	b_k2	dsp_dpv.bits.bit3



//seg 输出高
#define 	SEG1		do{SEG1_M=0;SEG1_O=1;}while(0)//SEG1_O=1;
#define 	SEG2		do{SEG2_M=0;SEG2_O=1;}while(0)//SEG2_O=1;
#define 	SEG3		do{SEG3_M=0;SEG3_O=1;}while(0)//SEG3_O=1;
#define 	SEG4		do{SEG4_M=0;SEG4_O=1;}while(0)//SEG4_O=1;
#define 	SEG5		do{SEG5_M=0;SEG5_O=1;}while(0)//SEG5_O=1;
#define 	SEG6		do{SEG6_M=0;SEG6_O=1;}while(0)//SEG6_O=1;

//com输出低
#define 	COM1		do{SEG1_M=0;SEG1_O=0;}while(0)
#define 	COM2		do{SEG2_M=0;SEG2_O=0;}while(0)
#define 	COM3		do{SEG3_M=0;SEG3_O=0;}while(0)
#define 	COM4		do{SEG4_M=0;SEG4_O=0;}while(0)
#define 	COM5		do{SEG5_M=0;SEG5_O=0;}while(0)
#define 	COM6		do{SEG6_M=0;SEG6_O=0;}while(0)
    
uint8_t led_wei;






//--------------------------------------------------------------------------------------------------
//Timer3-define
#define  iT3_1_rate		7
#define  iT3_2_rate		6
#define  iT3_4_rate		5
#define  iT3_8_rate		4
#define  iT3_16_rate	3
#define  iT3_32_rate	2
#define  iT3_64_rate	1
#define  iT3_128_rate	0

#define  iT3_val		(170)
#define  iT3_val2		(30-15)

/**
 * @ brief:	T3_Timer_Fosc_Init-T3-定时器模式-Fosc
 * @ note: 定时器模式，时钟源选-Fosc；
 * @ param:	rate-分频系数,timer_val-初值
 * @ retval:null
 */
void T3_Timer_Fosc_Init(unsigned char rate, unsigned int timer_val)
{
	T3C2 = 0x00;	//00** *111
		//bit7:PDTM2
			//0 = T3PWM3 & T3PWM2 工作与独立输出模式
			//1 = T3PWM3 & T3PWM2 工作与互补输出模式
		//bit6:PDTM0
			//0 = T3PWM1 & T3PWM0 工作与独立输出模式
			//1 = T3PWM1 & T3PWM0 工作与互补输出模式
		//bit5:T3PWM4INV 	//0 = 不取反;			1 = 取反
		//bit4:T3PWM3INV  	//0 = 不取反;			1 = 取反
		//bit3:T3PWM2INV  	//0 = 不取反;			1 = 取反
		//bit2:T3PWM4EN		//0 = 禁止 T3PWM4 输出;	1 = 允许 T3PWM4 输出 
		//bit1:T3PWM3EN		//0 = 禁止 T3PWM3 输出;	1 = 允许 T3PWM3 输出 
		//bit0:T3PWM2EN		//0 = 禁止 T3PWM2 输出;	1 = 允许 T3PWM2 输出 
		
	T3C1 = 0x00;	//-0-0 -111
	T3C1|=(1<<4);	//Fosc
	T3C1|=(rate & 0x07);	//分频系数（不能大于7）
		//bit6:T3OUT0   	//0 = T3PWM 输出不受影响;	1 = T3PWM 输出全低电平 
		//bit4:T3CKS0 		//0 = Fcpu/2;				1 = Fosc-√
		//bit2~0:T3CK<2:0>
			//111 = 1分频;		110 = 2分频;		101 = 4分频;	100 = 8分频
			//011 = 16分频;		010 = 32分频;		001 = 64分频;	000 = 128分频
		
	T3C0 = 0x80;	//1-** -11-
		//bit7:T3REN  定时器总使能;			//0 = 禁止;		1 = 使能-√
		//bit5:T3PWM1INV  T3PWM1输出极性;	//0 = 不取反;	1 = 取反
		//bit4:T3PWM0INV  T3PWM0输出极性;	//0 = 不取反;	1 = 取反
		//bit2:T3PWM1EN 输出使能;			//0 = 禁止;		1 = 启动
		//bit1:T3PWM0EN 输出使能;			//0 = 禁止;		1 = 启动
	
	//timer
	T3TH = (0xfff - timer_val)/256;
	T3TL = (0xfff - timer_val)%256;		
	
	T3IF = 0;
	T3IE = 1;
	PEIE = 1;
	GIE = 1;
}

const uint8_t seg_tab[]={0x3F,0x6,0x5B,0x4F,0x66,0x6D,0x7D,0x7,0x7F,0x6F};

/**
 * @ brief:	main
 * @ param:	null
 * @ retval:null
 */
void main(void) 
{
	System_Init();
	GPIO_Init();
	CLR_RAM_EveryBank();
	
	dsp_dat1.byte = seg_tab[1];
	dsp_dat2.byte = seg_tab[8];
	dsp_dat3.byte = seg_tab[8];
	// dsp_dpv.byte = 0x0F;
	
//	VREF = 0x02;
//	ADPCON  = 0x80;
//	ADPCON1 = 0x01;
//	ADM= 0b10011000;
	T3_Timer_Fosc_Init(iT3_16_rate, iT3_val);

	while(1) 
	{ 
		CLRWDT();  	
	} 
} 


/**
 * @ brief:	GPIO Init
 * @ param:	null
 * @ retval:null
 */
void GPIO_Init(void) 
{
//;PORTA
	PORTA = 0b00000000;		//0000 0000	//端口输出赋值
	TRISA = 0b00000000;		//0000 0000	:0-OUT;1-IN 	//输入输出配置
	PAODCON = 0b00000000;	//0000 0000 :1-EN;0-DIS 	//开漏配置
	PAHCON = 0b11111111;	//1111 1111 :1-DIS;0-EN 	//内部上拉配置
	PADCON = 0b11111111;	//1111 1111 :1-DIS;0-EN 	//内部下拉配置
	WUACON = 0b00000000;	//0000 0000	:1-EN;0=DIS 	//端口唤醒配置
		
//;PORTC
	PORTC = 0b00000000;		//--00 0000	//端口输出赋值
	TRISC = 0b00111000;		//--00 0000	:0-OUT;1-IN 	//输入输出配置
	PCDCON = 0b11111111;	//--11 1111 :1-DIS;0-EN		//内部下拉配置
	PCHCON = 0b11111111;	//--11 1111 :1-DIS;0-EN 	//内部上拉配置
} 


/**
 * @ brief:	System_Init
 * @ param:	null
 * @ retval:null
 */ 
void System_Init(void)
{
	OPTION = 0b000000000;	 //-0-- ----
			//bit6:INTEDG：外部中断触发方式选择位（PC1）	;0-falling edge, 1-rising edge
			
	INTCON = 0b00000000;	//00-0 0-00
			//bit7:GIE 全局中断使能位
			//bit6:PEIE 外设总中断使能位
			//bit4:INTIE 外部中断使能位(PC1)
			//bit3:PAIE PORTA输入变化中断使能位
			//bit1:INTIF 外部中断标志位
			//bit0:PAIF PORTA输入变化中断标志位			
	
	PCON  = 0b10110000;		//1-1- ----	
			//Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			//Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN
				
	PIE1 = 0B00000000;		//-0-- ---0 
			//Bit6:ADCIE ADC中断使能位
			//Bit0:T1IE 定时器T1中断使能位 
			
	PIR1 = 0B00000000;		//-0-- ---0 
			//Bit6:ADCIE ADC转换完成标志位
			//Bit0:T1IE 定时器T1溢出标志位 
			
	PIE2 = 0B00000000;	//---- -0-0
			//Bit1:T3IE 定时器T3中断使能位
			//Bit2:T4IE 定时器T4中断使能位
			//Bit5:C1IE 比较器C1中断使能位
			
	PIR2 = 0B00000000;	//---- -0-0
			//Bit1:T3IE 定时器T3溢出标志位,软件清0
			//Bit2:T4IE 定时器T4溢出标志位,软件清0
			//Bit5:C1IE 比较器C1输出变化时被置位,软件清0
}


/**
 * @ brief:	CLR_RAM_EveryBank
 * @ note
 *  @对用户寄存器进行清0操作 
 *  @分BANK区清楚 
 *  @嵌入汇编操作 
 *  @IRP:FSR7:	间接寻址寻址空间（充分理解 间接寻址操作原理）
 *  @	0 0		BANK0
 *  @	0 1		BANK1
 *  @	1 0		BANK2
 *  @	1 1		BANK3
 * @ param:	null
 * @ retval:null
 */     
void CLR_RAM_EveryBank(void)
{
	#asm   
		MOVLW	0x5F  //个数
		MOVWF	0x20  //个数存放地址 
		MOVLW 	0x7F  //REG从后往前 清理 
		MOVWF	_FSR,F 
	CLR_RAM_LOOP:   
		CALL	CLR_RAM_Demo
		
		DECF	_FSR,F   
		DECFSZ	0X20,F   
		GOTO	CLR_RAM_LOOP
		
		CALL	CLR_RAM_Demo
		RETURN
		
	CLR_RAM_Demo:	
	//	0 1		BANK1
		//BCF	_STATUS,7	//IRP
		BSF		_FSR,7		//01:BANK1
		CLRF	_INDF  
		
	//	0 0		BANK0
		//BCF	_STATUS,7	//IRP
		BCF		_FSR,7		//00:BANK0
		CLRF	_INDF
		
		RETURN
	#endasm	
}   

/**
 * @ brief:	Delay
 * @ note
 *  @ Fcpu=1MHz;DelayUs = 11+7x
 *  @ 不同时钟Fcpu，注意时间差异
 * @ param:	null
 * @ retval:null
 */
//****delay function****// 
void DelayUs(unsigned char delayUs)
{
	while(delayUs--);
} 



//==============================================
//1.>中断函数
//;Bank0~3 编译系统会自动切换,用户不需要手动切换; 
//==============================================
void interrupt myIsr(void)    
{
	//----User Code ----/
	#if 1
	if(T3IF)	//T3
	{
		T3IF = 0;
		//timer
		
		{
			T3TH = (0xfff-iT3_val)/256;
			T3TL = (0xfff-iT3_val)%256;
			
			SEG1_M=1;
			SEG2_M=1;
			SEG3_M=1;
			SEG4_M=1;
			SEG5_M=1;
			
			
			if(++led_wei>=16)
				led_wei=0;
			switch(led_wei)
			{
				case  0:if(b_b1_dsp){SEG3;COM4;}break;//第一个数码管的B段，根据数码管资料点亮
				case  1:if(b_c1_dsp){SEG2;COM4;}break;//第一个数码管的C段，根据数码管资料点亮
				
				case  2:if(b_a2_dsp){SEG2;COM3;}break;//第二个数码管的A段，根据数码管资料点亮
				case  3:if(b_b2_dsp){SEG3;COM2;}break;
				case  4:if(b_c2_dsp){SEG4;COM3;}break;
				case  5:if(b_d2_dsp){SEG4;COM2;}break;
				case  6:if(b_e2_dsp){SEG5;COM2;}break;
				case  7:if(b_f2_dsp){SEG5;COM3;}break;
				case  8:if(b_g2_dsp){SEG5;COM4;}break;
				
				case  9:if(b_a3_dsp){SEG1;COM2;}break;//第三个数码管的A段，根据数码管资料点亮
				case 10:if(b_b3_dsp){SEG2;COM1;}break;
				case 11:if(b_c3_dsp){SEG1;COM3;}break;
				case 12:if(b_d3_dsp){SEG3;COM1;}break;
				case 13:if(b_e3_dsp){SEG1;COM4;}break;
				case 14:if(b_f3_dsp){SEG4;COM1;}break;
				case 15:if(b_g3_dsp){SEG5;COM1;}break;
				
				default:break;
			}
		
		}
	}
	#endif
}