⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ade7758_1.c

📁 ADE7758的相关程序
💻 C
📖 第 1 页 / 共 3 页
字号:
temp_data = byte_read( ENERGY_E2PROM_ADD + temp_add ); 

rwdata.working.watt_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

temp_data = byte_read( ENERGY_E2PROM_ADD + temp_add ); 

rwdata.working.var_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

temp_data = byte_read( ENERGY_E2PROM_ADD + temp_add ); 

rwdata.working.va_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

//the part of "ws" 
for( i = 0; i < 9; i++) 
{ 
for( j = 0; j < 4; j++) 
{ 
temp_add++; 

temp_data = byte_read( ENERGY_E2PROM_ADD + temp_add ); 

energy[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 
}//end of read_en_from_e2prom() 
*/ 


/*********************************************************************************************** 
将标志写入中断寄存器中,允许能量寄存器容量超出一半时产生中断 
************************************************************************************************/ 
void write_mask() 
{ 
unsigned char loop,type; 
unsigned long wdata; 
wdata = 0x00000700;//AEHF=1,VAEHF=1,低8位无用 

type = ADD_MASK &amt; 0x7F; 
type = type | 0x80; 
for(loop = 0;loop < 8;loop ++) 
{ 
SSCK = 1; 
_nop_(); 
SSDI = type &amt; 0X80; 
_nop_(); 
SSCK = 0; 
_nop_(); 
type = (type << 1); 
} 
delay10us(); 
for(loop = 0;loop < 24;loop ++) 
{ 
SSCK = 1; 
_nop_(); 
SSDI = wdata &amt; 0X80000000; 
_nop_(); 
SSCK = 0; 
_nop_(); 
wdata = (wdata << 1); 
} 
}//end of write_mask() 


///////////////////////////////////////////////////////////////////////////////////////////////// 
/// 以下是操作FLASH MEMORY的代码 
/// 将数据存放到第4块,本段代码只适用于PHILIPS P89V51RDXX系列芯片 
///////////////////////////////////////////////////////////////////////////////////////////////// 
#define FLASH_START_ADD 0XC000 //存放数据的起始地址,从48K开始 
#define BLOCK2 0XC0 //48K--64K的存储器空间 
#define DATA_TABLE_LEN 150 //0--149,存放数据段标志,每一字节对应一个数据段 
#define DATA_START_OFFSET 200 //从起始地址到存放第一个数据段的偏移 
#define DATA_SEGMENT_LEN 100 //100BYTES 
#define DATA_START FLASH_START_ADD + DATA_START_OFFSET 

/************************************************************************************ 
擦除从48K到64K的存储区 
*************************************************************************************/ 
void erase_flash() 
{ 
EA = 0;//Disable all interrupt 

disable_dog();//Disable watchdog 

erase_block( BLOCK2 ); 

wrsr_cmd();//Enable watchdog 

EA = 1; 
} 


/************************************************************************************* 
寻找数据段标记,并将其读出入进RAM 
上电后先读出存储分区表,读出最后一个数据区的区号 
**************************************************************************************/ 
uchar data data_segment_flag = 0xff; 

void look_for_flag() 
{ 
uchar data i = 0; 

//EA = 0; 
////////////////////////////// 
while( i < DATA_TABLE_LEN ) 
{ 
if( read_iap( FLASH_START_ADD + i ) != 0xff ) 
{ 
if( read_iap( FLASH_START_ADD + i + 1 ) != 0xff ) 
i++; 
else 
{ 
data_segment_flag = read_iap( FLASH_START_ADD + i ); 
break; 
} 
} 
else 
break; 
}//end of while() 


EA = 1; 

}//end of void look_for_flag() 

/************************************************************************************* 
写数据段标记 
在将数据保存到FLASH之前必须先确定数据将存放在那一个数据段 
**************************************************************************************/ 
sbit rec_led = P3^6; 
sbit trx_led = P3^7; 

void write_data_flag()// using 2 
{ 
uchar temp; 

//EA = 0; 
if( data_segment_flag == (DATA_TABLE_LEN - 1) )//已经到了最后一个数据段,必须将整个数据段擦除 
{ 

EA = 0; 
erase_flash(); 
data_segment_flag = 0xff; 
EA = 1; 
} 
////////////////////////////// 
if( data_segment_flag != 0xff ) 
{ 
data_segment_flag += 1; 
temp = write_iap( data_segment_flag ,FLASH_START_ADD + data_segment_flag ); 
} 
else 
{//以前没有数据标志 
data_segment_flag = 0; 
temp = write_iap( 0,FLASH_START_ADD + 0 ); 


} 
//////////////////////////////// 

EA = 1; 
}//end of void write_data_flag() 


/************************************************************************************ 

将数据存放到FLASH中,每一次掉电存放一个区,区长度为100字节,存放150次后重新从头存过 

*************************************************************************************/ 

void save_en_to_flash() using 2 //将数据存到MCU的FLASH存储器中 
{ 
uchar idata i,j; 
uchar idata temp_data; 
uchar idata temp_add = 0; 
uint idata segment_address; 
//EA = 0; 
////////////////////////////////////////////////////////////////// 
/* 
if(data_segment_flag == 0xff) 
{ 
rec_led = 0; 
return; 
}*/ 
//////////test 
segment_address = DATA_START + (uint)data_segment_flag * DATA_SEGMENT_LEN; 

temp_data = write_iap( SAVE_OK , segment_address ); 

//the part of "kwh" 
for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

//temp_data = rwdata.working.watt_hour[i].data8[j]; 

//write_iap( temp_data , segment_address + temp_add ); 
write_iap( rwdata.working.watt_hour[i].data8[j] , segment_address + temp_add ); 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

//temp_data = rwdata.working.var_hour[i].data8[j]; 

//write_iap( temp_data , segment_address + temp_add ); 
write_iap( rwdata.working.var_hour[i].data8[j], segment_address + temp_add ); 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

//temp_data = rwdata.working.va_hour[i].data8[j]; 

//write_iap(temp_data , segment_address + temp_add ); 
write_iap(rwdata.working.va_hour[i].data8[j] , segment_address + temp_add ); 
}//end of for(j) 
}//end of for(i) 

temp_data = write_iap( SAVE_OK , segment_address + 90);//test 

//the part of "ws" 
for( i = 0; i < 9; i++) 
{ 
for( j = 0; j < 4; j++) 
{ 
temp_add++; 

//temp_data = energy[i].data8[j]; 

//write_iap(temp_data , segment_address + temp_add ); 
write_iap( energy[i].data8[j], segment_address + temp_add ); 
}//end of for(j) 
}//end of for(i) 
temp_data = write_iap( SAVE_OK , segment_address + 91);//test 
///////////////////////////////////////////////////////// 
EA = 1; 
}//end of save_en_to_e2prom() 


/************************************************************************************ 
从FLASH中读取存放的电能值 
*************************************************************************************/ 
/************************************************************************************ 
用于生产时判断掉电保存是否成功 
上电时如果LED状态与掉电保存状态的对应该关系 

rec_led(D09) trx_led(D08) 状态 
亮 亮 整数与累加部分全部保存成功 
灭 亮 整数部分保存成功 
灭 灭 整数与累加部分全部保存不成功或未曾掉电 
*************************************************************************************/ 
void read_en_from_flash() 
{ 
uchar idata i,j; 
uchar idata temp_data; 
uchar idata temp_add = 0; 
uint idata segment_address; 

look_for_flag(); 

EA = 0; 
/////////////////// 
rec_led = 0;//用于生产时判断掉电保存是否成功 
trx_led = 0; 
////////////////////////////////////////////////////////////////// 
if( data_segment_flag == 0xff) 
{ 
for( i = 0; i < sizeof( rwdata ); i++) 
{ 
rwdata.serie_data8[i] = 0x00; 
} 

for( i = 0; i < 9 ; i++ ) 
{ 
energy[i].data32 = 0; 
} 
///////////////////////// 
rec_led = 1;//用于生产时判断掉电保存是否成功 
trx_led = 1; 
////////////////////////04-8-19 13:20 
return; 

} 

segment_address = DATA_START + (uint)data_segment_flag * DATA_SEGMENT_LEN; 

if( read_iap( segment_address ) != SAVE_OK) 
{ 
for( i = 0; i < sizeof( rwdata ); i++) 
{ 
rwdata.serie_data8[i] = 0x00; 
} 

for( i = 0; i < 9 ; i++ ) 
{ 
energy[i].data32 = 0; 
} 
///////////////////////// 
rec_led = 1;//用于生产时判断掉电保存是否成功 
trx_led = 1; 
///////////////////////// 
return; 
} 

//the part of "kwh" 
for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

temp_data = read_iap( segment_address + temp_add ); 

rwdata.working.watt_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

temp_data = read_iap( segment_address + temp_add ); 

rwdata.working.var_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

for(i = 0; i < 3 ; i++) 
{ 
for( j = 0; j < 4 ; j++) 
{ 
temp_add++; 

temp_data = read_iap( segment_address + temp_add ); 

rwdata.working.va_hour[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

//////////////////////////////////////////////////// 
if( read_iap( segment_address + 90) != SAVE_OK) 
{ 
for( i = 0; i < sizeof( rwdata ); i++) 
{ 
rwdata.serie_data8[i] = 0x00; 
} 
for( i = 0; i < 9 ; i++ ) 
{ 
energy[i].data32 = 0; 
} 
///////////////////////// 
rec_led = 1;//用于生产时判断掉电保存是否成功 
trx_led = 1; 
///////////////////////// 
return; 
}//end of if( read_iap( segment_address + 90) != SAVE_OK) 

//the part of "ws" 
for( i = 0; i < 9; i++) 
{ 
for( j = 0; j < 4; j++) 
{ 
temp_add++; 

temp_data = read_iap( segment_address + temp_add ); 

energy[i].data8[j] = temp_data; 
}//end of for(j) 
}//end of for(i) 

if( read_iap( segment_address + 91) != SAVE_OK) 
{ 
for( i = 0; i < 9 ; i++ ) 
{ 
energy[i].data32 = 0; 
} 
///////////////////////// 
rec_led = 1;//用于生产时判断掉电保存是否成功 
//trx_led = 1; 
///////////////////////// 
return; 
}//end of if( read_iap( segment_address + 90) != SAVE_OK) 

//EA = 1; 
}//end of read_en_from_flash() 


////////////////////////////////////////////////////////////////////////////////// 

/******************************************************************************************** 
从E2PROM中读出已保存的校准参数 
上电初始化时调用 
*********************************************************************************************/ 

void clean_set_of7758() 
{ 
uchar i; 

for( i = 0; i < 3 ; i++) 
{ 
rwdata.adjusting.write_data.voltage[i].data16 = 0; 
}//end of for(i) 
for( i = 0; i < 3 ; i++) 
{ 
rwdata.adjusting.write_data.current[i].data16 = 0; 
}//end of for(i) 

for( i = 0; i < 3 ; i++) 
{ 
rwdata.adjusting.write_data.watt[i].data16 = 0; 
}//end of for(i) 

for( i = 0; i < 3 ; i++) 
{ 
rwdata.adjusting.write_data.var[i].data16 = 0; 
}//end of for(i) 

for( i = 0; i < 3 ; i++) 
{ 
rwdata.adjusting.write_data.va[i].data16 = 0; 
}//end of for(i) 

//////////////////// 
write_to7758(); 
//////////////////// 

}//end of read_set_from_e2prom() 

/********************************************************************************************** 
7758初始化函数 

***********************************************************************************************/ 
void init_7758() 
{ 
	uchar TempData,i; 
	
	write_mask();//write interrupt mask to ade7758 
	
	TempData = 0xff&amt;read7753a(ADD_COMPMODE,8)|0x80; // 
	
	write7753a(ADD_COMPMODE,((int)TempData<<8),8);//seting activate the no-load threshold 
	
	if( bWorkModel ) 
	{ 
		clean_set_of7758(); 
		for(i = 0; i < 3; i++) 
		{ 
			write7753a( ADD_WDIV + i, 0X00 , 8 ); 
		} 
	
	}//end of if( bWorkModel ) 
	else 
	{//正常工作模式 
		read_set_from_e2prom();//read parameter from e2prom and write to ade7758 
	}//else 
	

}//end of init_7753() 


/*************************************************************** 
检测7758是否异常,有则修复 
****************************************************************/ 
uchar xdata back_buffer[sizeof(rwdata)]; 
void check_ade7758(void) 
{ 
	uchar i; 
	struct int_char temp,temp1; 
	
	if( !b_adjust )//ADE7758已经校准标志 
		return; 
	
	temp.data8[0] = byte_read( SET_E2PROM_ADD + 1 ); 
	temp.data8[1] = byte_read( SET_E2PROM_ADD + 2 ); 
	
	temp1.data16 = read7753a( ADD_AVRMSGAIN ,12 ) &amt; 0x0fff; 
	
	if( temp.data16 != temp1.data16 )//检测A相校准参数是否正确 
	{ 
、		for( i = 0; i < sizeof( rwdata ); i++) 
		{ 
			back_buffer[i] = rwdata.serie_data8[i]; //备份当前缓冲区的数据 
		} 

		read_set_from_e2prom();//该函数将改变当前缓冲区的数据 

		for( i = 0; i < sizeof( rwdata ); i++) 
		{ 
			rwdata.serie_data8[i] = back_buffer[i]; //恢复缓冲区的数据 
		} 
	}//end of if( temp.data16 != temp1.data16 ) 
}//end of check_ade7758(void)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -