📄 measure.c
字号:
#include "measure.h"
#include "sys_time.h"
#include "storage.h"
#include "pub_func.h"
#include "i2c.h"
#include "string.h"
// 当前时段表表号
_sys_potinfo_s _SysPotInfo;
// 当前记量属性(正向尖,峰,平,谷;反向尖,峰,平,谷)
unsigned char PowerAttribute=0;
// 当前时段
unsigned char CurrentPotNum;
/******************************************
* 时区确认
* 说明:1.时区信息在E2prom中的存储一定要按照时间
* 由小到大排序
* 2.在一个月内可以有多个时区
******************************************/
void ZoneAttributeDetect(void)
{
unsigned char zoneinfo[2],zonecnt,zonenum,i;
// 读时区数
ReadBcdCountInfo(ADDR_OF_TIMEZONE_COUNT,&zonecnt,13,1);
// 时区号初始化为最后一个时区
zonenum=zonecnt-1;
for(i=0;i<zonecnt;i++)
{
// 读时区信息(月,日)
FramRead(BASE_ZTSTA+i*3+ZT_OFFSET_DAY,zoneinfo,2);
// 如果当前月大于时区信息的月,则继续寻找下一个时区信息
if(_sys_time.months>zoneinfo[1])
{
// 保存时区号
zonenum=i;
}
// 如果当前月等于时区信息的月,则判断日期
else if(_sys_time.months==zoneinfo[1])
{
// 如果当前日大于等于时区信息的日
if(_sys_time.days>=zoneinfo[0])
{
// 保存时段表号
zonenum=i;
}
}
}
//保存当前的时区号
_SysPotInfo.zonenum=zonenum;
}
/******************************************
* 费率属性确认
******************************************/
void ExesAttributeDetect(void)
{
unsigned char i,exes,potnum=_SysPotInfo.potcnt;
// 初始化当前费率(取当日时段表中最后一个日时段费率)
exes=_SysPotInfo.potinfo[(_SysPotInfo.potcnt-1)*3+POT_OFFSET_EXES];
for(i=0;i<_SysPotInfo.potcnt;i++)
{
// 如果系统时间的小时大于时段表中的小时,则更新费率属性
if(_sys_time.hours>_SysPotInfo.potinfo[i*3+POT_OFFSET_HOUR])
{
exes=_SysPotInfo.potinfo[i*3+POT_OFFSET_EXES];
potnum=i;
}
else if(_sys_time.hours==_SysPotInfo.potinfo[i*3+POT_OFFSET_HOUR])
{
// 如果系统时间的分钟大于时段表中的分钟,则更新费率属性
if(_sys_time.minutes>=_SysPotInfo.potinfo[i*3+POT_OFFSET_MINUTE])
{
exes=_SysPotInfo.potinfo[i*3+POT_OFFSET_EXES];
potnum=i;
}
}
}
exes--;
if(exes>7)
{
exes=0x02;
}
if(PowerAttribute!=exes)
{
// 如果切换了费率,则保存当天电量数据
//StorePowerData();
// 保存需量数据
//SaveRequirePowerData();
// 刷新当前费率属性
PowerAttribute=exes;
}
CurrentPotNum=potnum;
}
// 春节日期定义
const unsigned char _SpringFestivalDate[50]=
{
36,// {0x02,0x06},//2000年2月05日
24,// {0x01,0x24},//2001年1月24日
43,// {0x02,0x12},//2002年2月12日
32,// {0x02,0x01},//2003年2月01日
22,// {0x01,0x22},//2004年1月22日
40,// {0x02,0x09},//2005年2月09日
29,// {0x01,0x29},//2006年1月29日
49,// {0x02,0x18},//2007年2月18日
38,// {0x01,0x07},//2008年2月07日
26,// {0x01,0x26},//2009年1月26日
45,// {0x02,0x14},//2010年2月14日
34,// {0x02,0x03},//2011年2月03日
23,// {0x01,0x23},//2012年1月23日
41,// {0x02,0x10},//2013年2月10日
31,// {0x01,0x31},//2014年1月31日
50,// {0x02,0x19},//2015年2月19日
39,// {0x02,0x08},//2016年2月08日
28,// {0x01,0x28},//2017年1月28日
47,// {0x02,0x16},//2018年2月16日
36,// {0x02,0x05},//2019年2月05日
25,// {0x01,0x25},//2020年1月25日
43,// {0x02,0x12},//2021年2月12日
32,// {0x02,0x01},//2022年2月01日
22,// {0x01,0x22},//2023年1月22日
41,// {0x02,0x10},//2024年2月10日
29,// {0x01,0x29},//2025年1月29日
48,// {0x02,0x17},//2026年2月17日
37,// {0x02,0x06},//2027年2月06日
26,// {0x01,0x26},//2028年1月26日
44,// {0x02,0x13},//2029年2月13日
34,// {0x02,0x03},//2030年2月03日
23,// {0x01,0x23},//2031年1月23日
42,// {0x02,0x11},//2032年2月11日
31,// {0x01,0x31},//2033年1月31日
50,// {0x02,0x19},//2034年2月19日
39,// {0x02,0x08},//2035年2月08日
28,// {0x01,0x28},//2036年1月28日
46,// {0x02,0x15},//2037年2月15日
35,// {0x02,0x04},//2038年2月04日
24,// {0x01,0x24},//2039年1月24日
43,// {0x02,0x12},//2040年2月12日
32,// {0x02,0x01},//2041年2月01日
22,// {0x01,0x22},//2042年1月22日
41,// {0x02,0x10},//2043年2月10日
30,// {0x01,0x30},//2044年1月30日
48,// {0x02,0x17},//2045年2月17日
37,// {0x02,0x06},//2046年2月06日
26,// {0x01,0x26},//2047年1月26日
45,// {0x02,0x14},//2048年2月14日
33// {0x02,0x02},//2049年2月02日
};
/******************************************
* 公共假日确认
* 节假日优先级为:春节>公共假日>周休日
******************************************/
unsigned short PublicVacationDetect(void)
{
unsigned short addr,addr1;
unsigned char pvinfo[2],temp=0,pvcnt,i;
// 读周休日状态字
FramRead(ADDR_OF_WEEKEND_STATUS,&pvcnt,1);
if(!(pvcnt&(0x01<<_sys_time.week)))
{
temp|=0x01;
addr=ADDR_OF_SPRING_FEST;
}
// 读公共假日数
ReadBcdCountInfo(ADDR_OF_PUB_VACATION_COUNT,&pvcnt,13,1);
for(i=0;i<pvcnt;i++)
{
addr1=BASE_PUBV+i*3+PUBV_OFFSET_DAY;
// 读公共假日信息(月,日)
FramRead(addr1,pvinfo,3);
// 如果当前月和日等于公共假日信息的月和日
if((_sys_time.months==pvinfo[1])&&(_sys_time.days==pvinfo[0]))
{
// 保存当前公共假日状态为公共假日
temp|=0x10;
addr=addr1-1;
break;
}
}
// 判断是否为春节三天
if(_sys_time.months<2)
{
pvcnt=Bcd2HexChar(_sys_time.years);
if(pvcnt<50)
{
pvinfo[0]=_sys_time.months*31+Bcd2HexChar(_sys_time.days);
pvinfo[1]=_SpringFestivalDate[pvcnt]-1;
pvinfo[0]=(unsigned char)((unsigned char)pvinfo[0]-(unsigned char)pvinfo[1]);
if(pvinfo[0]<=2)
{
// 保存当前公共假日状态为春节
temp|=0x20;
addr=ADDR_OF_WEEKEND;
}
}
}
if(temp)
{
_SysPotInfo.pubvacstate=temp;
return(addr);
}
return(0);
}
/******************************************
* 确认日时段表号
******************************************/
void GetPeriodOfTimeTableNum(void)
{
unsigned short addr_pottbl;
unsigned char pottblcnt,temp;
// 读取本日公共假日号
addr_pottbl=PublicVacationDetect();
// 读取本日所在时区号
ZoneAttributeDetect();
if(_SysPotInfo.pubvacstate==0)
{
// 如果本日不是公共假日,则读相应时区的时段表号
addr_pottbl=BASE_ZTSTA+_SysPotInfo.zonenum*3+ZT_OFFSET_POTNUM;
}
// 读取日时段表数
ReadBcdCountInfo(ADDR_OF_POT_COUNT,&pottblcnt,13,1);
// 读取本日时段表号
FramRead(addr_pottbl,&temp,1);
temp=Bcd2HexChar(temp);
if((temp==0)||(temp>pottblcnt))
{
temp=1;
}
_SysPotInfo.pottblnum=temp;
//ReadBcdCountInfo(addr_pottbl,&_SysPotInfo.pottblnum,pottblcnt,1);
}
/******************************************
* 确认时段信息
******************************************/
void EnsurePeriodOfTime(void)
{
unsigned short addr;
unsigned char i,exescnt;
// 清数据结构
memset((unsigned char *)&_SysPotInfo.chksum,0x0,sizeof(_sys_potinfo_s));
// 读取日时段表信息
GetPeriodOfTimeTableNum();
// 读取时段数
ReadBcdCountInfo(ADDR_OF_POT_SWITCH_COUNT,&_SysPotInfo.potcnt,13,1);
// 读取费率数
ReadBcdCountInfo(ADDR_OF_FRATE_COUNT,&exescnt,5,1);
addr=BASE_POT_T+(_SysPotInfo.pottblnum-1)*BASE_POT_T_OFFSET;
for(i=0;i<_SysPotInfo.potcnt;i++)
{
// 读取时段表中的时间信息(时,分)
// 读取时段表中的费率信息
FramRead(addr,(unsigned char *)&_SysPotInfo.potinfo[i*3],3);
// 如果当前费率不在范围内,则强制置为"平电量"
if(_SysPotInfo.potinfo[i*3+POT_OFFSET_EXES]>exescnt)
{
_SysPotInfo.potinfo[i*3+POT_OFFSET_EXES]=2;
}
addr+=3;
}
// 更新本日日期和当前时间
_SysPotInfo.day=_sys_time.days;
_SysPotInfo.hour=_sys_time.hours;
_SysPotInfo.year=_sys_time.years;
// 读取结算日信息
FramRead(ADDR_OF_AUTO_RDDATA_DATE,(unsigned char *)&_SysPotInfo.balance_hour,2);
// 读取上次结算月信息
FramRead(ADDR_OF_SETTLEMENT_RECODE_MON,(unsigned char *)&_SysPotInfo.last_balance_mon,2);
// 读取需量周期时间(最大60分钟,默认15分钟)
ReadBcdCountInfo(ADDR_OF_REQ_CYCLE,&_SysPotInfo.reqtime,60,15);
//_SysPotInfo.reqtime=1;
// 读取滑差时间(最大60分钟,默认5分钟)
ReadBcdCountInfo(ADDR_OF_SLIP_TIME,&_SysPotInfo.reqtime_huacha,60,5);
_SysPotInfo.reqtime_huacha=1;
// 读取电表常数
FramRead(ADDR_OF_METER_CONSTANT_A+1,(unsigned char *)&exescnt,1);
exescnt=Bcd2HexChar(exescnt);
if((exescnt!=8)&&(exescnt!=16)&&(exescnt!=32))
{
_SysPotInfo.constant_a=8;
}
else
{
_SysPotInfo.constant_a=exescnt;
}
_SysPotInfo.watt=(0x2000/_SysPotInfo.constant_a)*10;
// 电压有效范围
//AptoticDataRead(ADDR_OF_REGV_MIN_VALUE,(unsigned char *)&_SysPotInfo.regv_min,4);
//_SysPotInfo.regv_min=Bcd2HexShort(_SysPotInfo.regv_min);
//_SysPotInfo.regv_max=Bcd2HexShort(_SysPotInfo.regv_max);
_SysPotInfo.regv_max=2640;
// 失压条件
FramRead(ADDR_OF_LV_CONDITION+2,(unsigned char *)&addr,2);
_SysPotInfo.lostv_con=Bcd2HexShort(addr);
// 失流条件
FramRead(ADDR_OF_LI_CONDITION+1,(unsigned char *)&addr,2);
_SysPotInfo.losti_con=Bcd2HexShort(addr);
// 额定电流
FramRead(ADDR_OF_RATED_IB,(unsigned char *)&addr,2);
_SysPotInfo.currentcoe=Bcd2HexShort(addr);
// 声光报警控制字
FramRead(ADDR_OF_ALARM_RAYCTL_WORD,(unsigned char *)&_SysPotInfo.alarm_light,2);
// 读ADE7753配置信息
exescnt=0;
for(i=0;i<50;i++)
{
//addr=ADDR_OF_ADE_BASE+i*3;
//FramRead(addr,(unsigned char *)&_SysPotInfo.ade7758_info[exescnt],_ade7758_wr_bytes[i]);
//exescnt+=_ade7758_wr_bytes[i];
}
// 计算校验和
_SysPotInfo.chksum=GetChkSumRvrs((unsigned char *)&_SysPotInfo.regv_min,sizeof(_sys_potinfo_s)-4);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -