📄 ade7758_1.c
字号:
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 + -