//*****************************************************   
//Copyright (c) 2022, 苏州华芯微电子股份有限公司
//All rights reserved                                 
//文件名称: main.c
//摘    要: EEPROM读写数据实验:对EE的0X01地址写入数据0XAA;然后读取EE的0X01地址内的数据，如果数据为0XAA,则PA0的电平反转一次
//当前版本: 1.0                                      
//作    者: 华芯微MCU组
//完成日期: 2022.02.10
//*****************************************************  
#include 	<hs16f3612.h>  	
#include 	<main.h>		
//*********************************************************************** 
unsigned char BSREG_Buf;	//System Use
/*-------------------------------------------------
 *  函数名称：Interrupt
 *  功能：   中断处理函数
 *  输入参数：无
 * 	返回参数：无 
 -------------------------------------------------*/
void interrupt myIsr(void)    
{
	//BSREG_SAVE
	BSREG_Buf = BSREG;

//--------------------------------------------	
	GOTO_BANK0;
	
	
	
	
	//----------------------------------------------------
	//空
	//----------------------------------------------------
	
	
	
	
	//BANK_RECOVER
	BSREG = BSREG_Buf;
} 

/*-------------------------------------------------
 *  函数名称：EEPROM_CLR_ALL
 *  功能：    EEPROM数据全擦
 *  输入参数：无
 * 	返回参数：无 
 -------------------------------------------------*/
void EEPROM_CLR_ALL(void)
{
	EECON1 = 0x00;	
	 				  //Bit7 空	
					  //Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
					  //Bit4 空	
					  //Bit3 ERSALLEE 全擦操作使能	1-使能全擦操作    0-禁止全擦操作
					  //Bit2 ERASEEE  位擦操作使能  1-使能位擦		  0-禁止位擦
					  //Bit1 PROGEE	  写操作使能    1-使能写操作      0-禁止写操作
					  //Bit0 READEE   读操作使能    1-使能读          0-禁止读		
	NOP(); 
	FERSALLEE = 1;	  //使能全擦
	FERASEEE = 1;	  //使能位擦
	NOP();
	while(FERASEEE);  //等待擦写完毕
}

/*-------------------------------------------------
 *  函数名称：EEPROM_Write_1Byte
 *  功能：    EEPROM写一个字节数据
 *  输入参数：EEPROM_Addr:要写入EE数据的地址；   EEPROM_Data:要写入EE的数据；
 * 	返回参数：无 
 -------------------------------------------------*/
void EEPROM_Write_1Byte(unsigned char EEPROM_Addr,unsigned char EEPROM_Data) 
{
	EECON1 = 0b01000000;	
					        //Bit7 空	
						    //Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
						    //Bit4 空	
						    //Bit3 ERSALLEE 全擦操作使能  1-使能全擦操作    0-禁止全擦操作
						    //Bit2 ERASEEE  位擦操作使能  1-使能位擦		0-禁止位擦
						    //Bit1 PROGEE	写操作使能    1-使能写操作      0-禁止写操作
						    //Bit0 READEE   读操作使能    1-使能读          0-禁止读		
	
	EEADRL = EEPROM_Addr;	//对要写入数据的地址进行赋值, 
	//OSCM = 0x01;            //对EE写数据时,系统时钟改为低速时钟;等数据写完毕时,在把系统时钟改为高速时钟.
					  		//Bit7 空	
					  		//Bit6 WAKEMODE 低速模式下睡眠唤醒后系统时钟选择位 1-选择高速时钟作为系统时钟     0-选择低速时钟作为系统时钟
					  		//Bit5 GREENEN 绿色模式使能位     1-开启绿色模式     0-普通模式
					  		//Bit4 RTCEN RTC模式使能位        1-模式软件关闭     0-模式软件使能	
					  		//Bit3 SLCON 内外低速时钟控制位   1-关闭内外低速时钟     0-开启内外低速时钟	
					  		//Bit2 XTSEL 内外低速选择位       1-选择外部低速晶振     0-选择内部低速RC   
					  		//Bit1 STPHX 内部高速震荡器控制位 1-停止，内部低速RC仍然运行。  0-运行
					  		//Bit0 CLKMD 系统时钟模式控制位   1-低速模式，低速时钟作为系统时钟	0-普通模式，高速时钟作为系统时钟  

	FERASEEE = 1;			//ERASEEE  位擦操作使能  1-使能位擦		0-禁止位擦 
	while(FERASEEE);		//等待数据擦除结束 
	EEDATL = EEPROM_Data;	//对要写入EE的数据进行赋值
	FPROGEE = 1;			//写操作使能    1-使能写操作      0-禁止写操作
	while(FPROGEE);	 	    //等待数据写操作结束
	//OSCM = 0x00;            //数据写入完毕，系统时钟改为高速时钟。
} 
/*-------------------------------------------------
 *  函数名称：EEPROM_Read_1Byte
 *  功能：    读一个字节数据
 *  输入参数：EEPROM_Addr:读取数据的地址
 * 	返回参数：ReadEeprom_Date:读取到的EE数据
 -------------------------------------------------*/
unsigned char EEPROM_Read_1Byte(unsigned char EEPROM_Addr) 
{
	unsigned char ReadEeprom_Data;	//函数返回值 
	EECON1 = 0x00;	
							//Bit7 空	
						    //Bit6 TIMEE[1:0] EE操作时长选择 00：默认 01：默认一半  10：默认两倍  11：默认4倍 
						    //Bit4 空	
						    //Bit3 ERSALLEE 全擦操作使能  1-使能全擦操作    0-禁止全擦操作
						    //Bit2 ERASEEE  位擦操作使能  1-使能位擦		0-禁止位擦
						    //Bit1 PROGEE	写操作使能    1-使能写操作      0-禁止写操作
						    //Bit0 READEE   读操作使能    1-使能读          0-禁止读	
	EEADRL = EEPROM_Addr;	//对要读取EE数据的地址进行赋值
	FREADEE = 1;			//读数据使能
	NOP(); 
	ReadEeprom_Data = EEDATL;//把读取的数据赋给ReadEeprom_Data寄存器
	return ReadEeprom_Data;	//返回读取到的EE数据 
} 

/*-------------------------------------------------
 *  函数名称：main
 *  功能：   main函数
 *  输入参数：无
 * 	返回参数：无 
 -------------------------------------------------*/
//****main function****//
void main(void) 
{
	unsigned char data=0;
	System_Init();//系统初始化
	GPIO_Init();  //IO初始化
	EEPROM_Write_1Byte(0x01,0xAA); //在0X01地址写入0XAA
	//EEPROM_CLR_ALL();EE数据全擦除
	while(1) 
	{ 
		CLRWDT(); //清看门狗
		data=EEPROM_Read_1Byte(0x01);//读取0X01地址的数据
		if(data==0xAA)              //判断0X01地址的数据是否是0XAA,如果是0XAA则PA0的电平反转一次。
		{
			PORTA = PORTA^0x01;	    // 读取的EE数据是0XAA, PA0的电平反转一次。
		}
		DelayMs(200);//延时200MS		
		DelayMs(200);//延时200MS	
	} 
} 
/*-------------------------------------------------
 *  函数名称：IO_Init
 *  功能：   io 初始化函数
 *  输入参数：无
 * 	返回参数：无
 -------------------------------------------------*/
void GPIO_Init(void) 
{
	PORTA = 0b00000000;	    //PA输出赋值
	TRISA = 0b00000000;	    //PA输入输出配置 :0-输出  ;1=输入  
	PAODCON = 0b00000000;	//PA漏极开路配置 :1-使能  ;0-禁止 
	PAHCON = 0b11111111;	//PA内部上拉配置 :1-禁止  ;0-使能 
	PADCON = 0b11111111;	//PA内部下拉配置 :1-禁止  ;0-使能 
	WUACON = 0b00000000;	//PA端口唤醒配置 :1-使能  ;0-禁止 
	PAIC0 = 0b00000000;	    //启动加强驱动   :1-加强驱动;0-默认驱动 
	PORTA = 0b00000000;	    //PA输出赋值
//----------------------------------------------------------------------
	PORTB = 0b00000000;	    //PB输出赋值
	TRISB = 0b00000110;	    //PA输入输出配置 :0-输出  ;1=输入 	
	PBODCON = 0b00000000;	//PA漏极开路配置 :1-使能  ;0-禁止 
	PBHCON = 0b11111111;	//PA内部上拉配置 :1-禁止  ;0-使能 	
	PBDCON = 0b11111111;	//PA内部下拉配置 :1-禁止  ;0-使能 
	WUBCON = 0b00000000;	//PA端口唤醒配置 :1-使能  ;0-禁止 
	PBIC0 = 0b00000000;	    //启动加强       :1-加强驱动;0-默认驱动 
	PORTB = 0b00000000;	    //PA输出赋值
//----------------------------------------------------------------------
	PORTC = 0b00000000;	    //PA输出赋值
	TRISC = 0b00000000;	    //PA输入输出配置 :0-输出  ;1=输入 
	PCDCON = 0b11111111;	//PA内部下拉配置 :1-禁止  ;0-使能 
	PCHCON = 0b11111111;	//PA内部上拉配置 :1-禁止  ;0-使能 	
} 

/*-------------------------------------------------
 *  函数名称：System_Init
 *  功能：   中断初始化配置
 *  输入参数：无
 * 	返回参数：无 
 -------------------------------------------------*/
void System_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分频
	PCON  = 0b10110000;	
	                  //Bit7 WDTE,看门狗定时器控制  1-使能WDT   0-禁止WDT
					  //Bit6 EIS,PB0管脚复用控制位  1-使能为外部中断输入脚  0-屏蔽中断功能	
					  //Bit5 LVDTE,LVDT低压复位使能,电压点由配置字决定  	
	                  //Bit4 SMTS,施密特使能位 1-施密特有效，0-施密特禁止
					  //Bit3 空	
					  //Bit2 空
					  //Bit1 空
					  //Bit0 空				
	INTEN = 0B00000000;	
					  //Bit7 GIE 使能全局中断     1-使能 0-禁止	
					  //Bit6 T3IE 使能T3溢出中断  1-使能 0-禁止
					  //Bit5 INT1IE 使能外部中断1 1-使能 0-禁止
					  //Bit4 T2IE 使能T2溢出中断  1-使能 0-禁止
					  //Bit3 TC1IE 使能T1溢出中断 1-使能 0-禁止
					  //Bit2 INTIE 使能外部中断0  1-使能 0-禁止
					  //Bit1 PBIE 使能端口变化中断1-使能 0-禁止 
					  //Bit0 T0IE TIME0溢出中断   1-使能 0-禁止
	INTFLAG=0B00000000;	
					  //Bit7 空	
					  //Bit6 T3IF T3溢出中断标志位
					  //Bit5 INT1IF 外部中断1标志位
					  //Bit4 T2IF T2溢出中断标志位	
					  //Bit3 TC1IF TC1溢出中断标志位		
					  //Bit2 INTIF 外部中断0标志位		
					  //Bit1 PBIF PA/PB输入状态变化中断标志位	
					  //Bit0 T0IF TIME0溢出中断标志位		
	INTEN1 = 0B00000000;	
			          //Bit7 空	
					  //Bit6 空
					  //Bit5 空
					  //Bit4 空	
					  //Bit3 空	
					  //Bit2 ADCIE ADC中断使能位 1-使能 0-禁止
					  //Bit1 空
					  //Bit0 TKIE 触摸中断使能位 1-使能 0-禁止		
	INTFLAG1=0B00000000;	
					  //Bit7 空	
					  //Bit6 空
					  //Bit5 空
					  //Bit4 空	
					  //Bit3 空	
					  //Bit2 ADCIF ADC中断标志位
					  //Bit1 空
					  //Bit0 TKIF 触摸中断标志位	
}

/*-------------------------------------------------
 *  函数名称：DelayMs
 *  功能：   短延时函数 --8M-4T
 *  输入参数：x 延时时间长度 延时只是粗略计算;延时X毫秒；
 * 	返回参数：无 
 -------------------------------------------------*/
//;Fcpu=8MHz/4T;   
void DelayMs(unsigned char x)     
{
	unsigned int i,j;
	for(i=0;i<x;i++)
	for(j=0;j<141;j++)
	{
		CLRWDT();
	}
} 







