📄 measure.c
字号:
Write24C64(RevErySavePtr,0x06,0x7E,2);
//保存整数电量
Write24C64(&CommVariant[32],0x06,0x00+RevErySavePtr[0]*0x20,17);
}
}
//***********************************************************************
//名称: ReadRevSaveEry()
//功能: 读取反向(峰、平、谷)整数电量
//说明:
//***********************************************************************
void ReadRevSaveEry(void)
{
uchar i,Sum;
//读取整数电量保存指针
if(RevErySavePtr[1]!=~RevErySavePtr[0]) //内存指针出错
{
Read24C64(RevErySavePtr,0x06,0x7E,2);
if(RevErySavePtr[1]!=~RevErySavePtr[0]) //Eeprom指针出错
{
RevErySavePtr[0] = 0x00;
}
}
//读取整数电量
for(i=0;i<4;i++)
{
RevErySavePtr[0] &= 0x03; //总共4个备份
Read24C64(&CommVariant[32],0x06,0x00+RevErySavePtr[0]*0x20,17);
Sum = ~SumCHK(&CommVariant[32],16);
if(Sum!=CommVariant[48])
{
RevErySavePtr[0]++;
}
////////////////////////////////////////////////////////////////
else if(!BCDCHK(&CommVariant[32+4],16-4)) //保证BCD码加法正确
{
RevErySavePtr[0]++;
}
////////////////////////////////////////////////////////////////
else break;
}
//恢复整数电量保存指针
RevErySavePtr[0] &= 0x03;
RevErySavePtr[1] = ~RevErySavePtr[0];
}
//***********************************************************************
//名称: CreateRealTimeEry()
//功能: 产生实时电量
//说明: 形成(总/正/反)(总、峰、平、谷)电量
// CommVariant[00]~CommVariant[15]:总(总、峰、平、谷)电量
// CommVariant[16]~CommVariant[31]:正(总、峰、平、谷)电量
// CommVariant[32]~CommVariant[47]:反(总、峰、平、谷)电量
//***********************************************************************
void CreateRealTimeEry(void)
{
uchar j;
ArrayInit(CommVariant,16); //清总有功(总、峰、平、谷)电量
//读取整数电量
ReadPosSaveEry();
ArrayInit(&CommVariant[16],4); //清正向总有功电量
ReadRevSaveEry();
ArrayInit(&CommVariant[32],4); //清反向总有功电量
//读取小数电量
CommVariant[16+4] = HEX2BCD(Energy.EryTmp1[0]);
CommVariant[16+8] = HEX2BCD(Energy.EryTmp1[1]);
CommVariant[16+12] = HEX2BCD(Energy.EryTmp1[2]);
CommVariant[32+4] = HEX2BCD(Energy.EryTmp2[0]);
CommVariant[32+8] = HEX2BCD(Energy.EryTmp2[1]);
CommVariant[32+12] = HEX2BCD(Energy.EryTmp2[2]);
//计算正向总电量
BCDAdd(&CommVariant[16],&CommVariant[20],4); //峰
BCDAdd(&CommVariant[16],&CommVariant[24],4); //峰+平
BCDAdd(&CommVariant[16],&CommVariant[28],4); //峰+平+谷
//计算反向总电量
BCDAdd(&CommVariant[32],&CommVariant[36],4); //峰
BCDAdd(&CommVariant[32],&CommVariant[40],4); //峰+平
BCDAdd(&CommVariant[32],&CommVariant[44],4); //峰+平+谷
//计算总电量
for(j=0;j<4;j++)
{
BCDAdd(&CommVariant[j*4],&CommVariant[16+j*4],4); //+正
BCDAdd(&CommVariant[j*4],&CommVariant[32+j*4],4); //+反
}
//电量翻转处理(5+1)
for(j=0;j<12;j++)
{
CommVariant[j*4+3] &= 0x0F;
}
}
//**********************************************************
//名称:Write24C64()
//功能:向eeprom写入数据
//说明:ptr--->指向待写数据区首址; Addr1--->片内高地址
// Addr1--->片内低地址 ; DataLen--->数据长度
// 读数据成功时,返回1;否则返回0.
//**********************************************************
bit Write24C64(uchar idata *ptr,uchar Addr1,uchar Addr2,uchar DataLen)
{
uchar i = 0;
uchar idata *DataPtr;
uchar idata Addr[3]; //地址数据
uchar idata Len[2]; //地址空间、数据空间长度
Addr[0] = 0xA0;
Addr[1] = Addr1;
Addr[2] = Addr2;
Len[0] = 0x03;
Len[1] = DataLen;
DataPtr = ptr;
while(ISendStr(Addr,DataPtr,Len)==0)
{
DataPtr = ptr;
i++;
if(i>=32) //最多写32次
{
return(0);
}
}
DelayNms(6); //延时6ms
PowerDownProcess(); //掉电检测处理程序
return(1);
}
//**********************************************************
//名称:Read24C64()
//功能:读取eeprom中的数据
//说明:ptr--->指向保存数据区首址; Addr1--->片内高地址
// Addr1--->片内低地址 ; DataLen--->数据长度
// 读数据成功时,返回1;否则返回0.
//**********************************************************
bit Read24C64(uchar idata *ptr,uchar Addr1,uchar Addr2,uchar DataLen)
{
uchar i;
uchar idata *DataPtr;
uchar idata Addr[3]; //地址数据
uchar idata Len[2]; //地址空间、数据空间长度
Addr[0] = 0xA0;
Addr[1] = Addr1;
Addr[2] = Addr2;
Len[0] = 0x03;
Len[1] = DataLen;
DataPtr = ptr;
i = 0x00;
while(IRcvStr(Addr,DataPtr,Len)==0)
{
DataPtr = ptr;
i++;
if(i>=32) //读取EEPROM的数据,最多读32次
{
////////////////////////////////////////
SystemCheckFlag |= 0x04; //EEPROM出错
////////////////////////////////////////
return(0);
}
}
////////////////////////////////////////
SystemCheckFlag &= ~0x04; //EEPROM正常
////////////////////////////////////////
return(1);
}
//***********************************************************************
//名称: PowerDownProcess()
//功能:
//说明: 掉电检测处理程序
//***********************************************************************
void PowerDownProcess(void)
{
uchar i,*ptr;
if(ePowerDownCheckFlag==DISABLE) return; //关闭掉电检测
if((CMP1&0x02)==0x00) //前端电压变低
{
i = 0xFF;
while(--i); //延时140uS
if((CMP1&0x02)==0x00)
{
EA = 0;
LED_F = 1; //峰
LED_P = 1; //平
LED_G = 1; //谷
//保存掉电时间
Energy.PowerDownTime[0] = Min;
Energy.PowerDownTime[1] = Hour;
Energy.PowerDownTime[2] = Day;
Energy.PowerDownTime[3] = Month;
Energy.PowerDownTime[4] = Year;
Energy.TimeCheck = ~SumCHK(&Energy.PowerDownTime[0],5);
//本次断电时电能是否反向
if(REVP==0) Energy.isRev = 0xAA;
//RTC备份指针、总反向累计时间备份指针
Energy.RtcPtr = RTCBackPtr;
//请在这里添加下电处理事件...
ptr = &Energy.PulseTmp1[0];
//if(I2EN == 1) //I2C总线忙
//{
I2CON = 0x54; //STO=1&AA=1 发送停止标志,结束其他I2C操作
while(STO == 1);
//}
I2SCLH = 0x14; //设置SCL高电平的PCLK周期数
I2SCLL = 0x14; //设置SCL低电平的PCLK周期数
I2CON = 0x64; //申请成为主机,起动总线。使用内部SCL发生器,I2EN和AA置位
while( SI==0 ); //等待起始信号的发送,申请总线
I2DAT = 0xA0; //发送器件地址
I2CON = 0x44; //清除SI位等等
while( SI==0 ); //等待数据的发送
I2DAT = 0x00; //发送从地址1
I2CON = 0x44; //清除SI位等等
while( SI==0 ); //等待数据的发送
I2DAT = 0x00; //发送从地址2
I2CON = 0x44; //清除SI位等等
while( SI==0 ); //等待数据的发送
for(i=0;i<24;i++) //发送数据
{
I2DAT = *ptr;
I2CON = 0x44; //清除SI位等等
while( SI==0 );
ptr++;
}
I2CON = 0x54; //结束总线
//////////////////////////////////////////////////////////////
//电源慢上问题
while((CMP1&0x02)==0x00); //检测上电
i = 250; //250*40mS=10S
while(i)
{
EA = 0;
WFEED1 = 0xA5;
WFEED2 = 0x5A;
MainMonitor = 0; //主循环监控变量
T0Monitor = 0x0000; //Timer0监控变量
RTCMonitor = 0x0000;//RTC监控变量
DelayNms(40); //延时40mS
if((CMP1&0x02)==0x02) --i;
else AUXR1 |= 0x08;//软件复位
}
//////////////////////////////////////////////////////////////
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -