📄 caculate.c
字号:
/*******************************************************************************************
** procedures for IDIN200E
**
** (c) Copyright 2004-2010, GZZG
** All Rights Reserved
**
** V0.1
** 文件信息---------------------------------------------------------------------------------
** 文 件 名: Caculate.c
** 作 者: 姜静
** 历史版本:
** 描 述: 本模块实现对电量的读取及相应的计算。
** 环 境:
** 注 意:
*******************************************************************************************/
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#include <Include.h>
#include <ExternDef.h>
#include <SPIDrive.h>
#include <math.h>
/*
*********************************************************************************************************
* EXTERN VARIABLES
*********************************************************************************************************
*/
extern bit permit_caculate;
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void Caculate_UI(void);
void Caculate_Power(void);
long Change_code(unsigned long *sdata);
/*$PAGE*/
/*******************************************************************************************
** 函数原型:void Calculate(void)
** 功能描述:电量计算函数。
** 参数说明:无。
** 返 回 值:无。
** 说 明:
** 注 意:
*******************************************************************************************/
void Calculate(void)
{
if(permit_caculate==0) return;
Caculate_UI();
Caculate_Power();
permit_caculate=0;
}
/*******************************************************************************************
** 函数原型:void Caculate_LineU(void)
** 功能描述:线电压计算函数。
** 参数说明:无。
** 返 回 值:无。
** 说 明:
** 注 意:
*******************************************************************************************/
void Caculate_LineU(void)
{
if(bMeter3==0) {//两表法
PhaseValue.LCDValueUU[0]=PhaseValue.LCDValueU[0];
PhaseValue.LCDValueUU[2]=PhaseValue.LCDValueU[2];
PhaseValue.LCDValueUU[3]=(PhaseValue.LCDValueUU[0]+PhaseValue.LCDValueUU[2])/2;
}
else {
PhaseValue.LCDValueUU[0]=sqrt(PhaseValue.LCDValueU[0]*PhaseValue.LCDValueU[0] +
PhaseValue.LCDValueU[1]*PhaseValue.LCDValueU[1] +
PhaseValue.LCDValueU[0]*PhaseValue.LCDValueU[1]);
PhaseValue.LCDValueUU[1]=sqrt(PhaseValue.LCDValueU[2]*PhaseValue.LCDValueU[2] +
PhaseValue.LCDValueU[0]*PhaseValue.LCDValueU[0] +
PhaseValue.LCDValueU[2]*PhaseValue.LCDValueU[0]);
PhaseValue.LCDValueUU[2]=sqrt(PhaseValue.LCDValueU[2]*PhaseValue.LCDValueU[2] +
PhaseValue.LCDValueU[1]*PhaseValue.LCDValueU[1] +
PhaseValue.LCDValueU[2]*PhaseValue.LCDValueU[1]);
PhaseValue.LCDValueUU[3]=(PhaseValue.LCDValueUU[0]+PhaseValue.LCDValueUU[1]+PhaseValue.LCDValueUU[2])/3;
}
}
/*******************************************************************************************
** 函数原型:void Caculate_UI(void)
** 功能描述:电压电流计算函数。
** 参数说明:无。
** 返 回 值:无。
** 说 明:
** 注 意:
*******************************************************************************************/
void Caculate_UI(void)
{
unsigned char i;
//电量计算
PhaseValue.LCDValueI[3]=0;
PhaseValue.LCDValueU[3]=0;
for(i=0;i<3;i++)
{
if(xdata_att7022a[0x0d+i]==0x00ffffff||xdata_att7022a[0x10+i]==0x00ffffff) return; //如果电流或电压溢出,则返回。--姜静加2007-9-18
PhaseValue.COS_value[i]=Change_code(&(xdata_att7022a+0x14+i))/(float)8388608; //三相功率因数
PhaseValue.LCDValueU[i]=xdata_att7022a[0x0d+i]/(float)(8192)*pt_num.IntData/10; //三相电压
PhaseValue.LCDValueI[i]=xdata_att7022a[0x10+i]/(float)(8192)*ct_num.IntData; //三相电流
if(PhaseValue.LCDValueI[i]<(0.001*ct_num.IntData)) PhaseValue.LCDValueI[i]=0;
PhaseValue.LCDValueI[3]+=PhaseValue.LCDValueI[i];
PhaseValue.LCDValueU[3]+=PhaseValue.LCDValueU[i];
}
PhaseValue.COS_value[3]=Change_code(&(xdata_att7022a+0x17))/(float)8388608; //合相功率因数
PhaseValue.LCDValueFreq=xdata_att7022a[0x1c]/(float)8192; //频率
//功率方向标志位的读取
Flag_power=xdata_att7022a[29];
Caculate_LineU(); //计算线电压
PhaseValue.LCDValueI[3]/=3;
PhaseValue.LCDValueU[3]/=3;
}
/*******************************************************************************************
** 函数原型:void Caculate_Power(void)
** 功能描述:功率计算函数。
** 参数说明:无。
** 返 回 值:无。
** 说 明:
** 注 意:
*******************************************************************************************/
void Caculate_Power(void)
{
unsigned char i;
static xdata unsigned char CalCount_num=0;
static xdata float TmpCalP[4]={0,0,0,0}; //有功功率的累积值
static xdata float TmpCalQ[4]={0,0,0,0}; //无功功率的累积值
static xdata float TmpCalS[4]={0,0,0,0};
xdata float temp_float;
//功率、线电压变化频繁,取10次求平均值
if(CalCount_num>=10){
CalCount_num=0;
temp_float=((float)pt_num.IntData)/10;
temp_float=(float)(ct_num.IntData*temp_float); //功率变比计算
for(i=0;i<4;i++) {
PhaseValue.LCDValueP[i]=TmpCalP[i]/CalCount_num*temp_float;
PhaseValue.LCDValueQ[i]=TmpCalQ[i]/CalCount_num*temp_float;
PhaseValue.LCDValueS[i]=TmpCalS[i]/CalCount_num*temp_float;
if(i==3&&(PhaseValue.LCDValueP[0]+PhaseValue.LCDValueP[1]+PhaseValue.LCDValueP[2])==0)
PhaseValue.LCDValueP[3]=0; //消除无电压电流情况下出现随机值的情况
if(i==3&&(PhaseValue.LCDValueQ[0]+PhaseValue.LCDValueQ[1]+PhaseValue.LCDValueQ[2])==0)
PhaseValue.LCDValueQ[3]=0;
TmpCalP[i]=0;
TmpCalQ[i]=0;
TmpCalS[i]=0;
}
}
else{
for(i=0;i<3;i++) { //计算有功、无功功率
TmpCalP[i] += Change_code(&(xdata_att7022a+0x01+i))/(float)256;
TmpCalQ[i] += Change_code(&(xdata_att7022a+0x05+i))/(float)256;
TmpCalS[i] += Change_code(&(xdata_att7022a+0x09+i))/(float)256;
}
TmpCalP[i] +=Change_code(&(xdata_att7022a+0x04))/(float)64; //合相有功功率
TmpCalP[i] +=Change_code(&(xdata_att7022a+0x08))/(float)64; //合相无功功率
TmpCalP[i] +=Change_code(&(xdata_att7022a+0x0c))/(float)64; //合相视在功率
CalCount_num++;
}
}
/*******************************************************************************************
** 函数原型:void Calculate_energy(void)
** 功能描述:电度计算函数。
** 参数说明:无。
** 返 回 值:无。
** 说 明:
** 注 意:
*******************************************************************************************/
void Calculate_energy(void)
{
unsigned int multiple;
unsigned long temp_const;
temp_const=pt_num.IntData*ct_num.IntData;
//有功电能累加
if(xdata_att7022a_energy[0]>=320){
multiple=(int)(xdata_att7022a_energy[0]/320);
xdata_att7022a_energy[0]-=multiple*320;
if(xdata_att7022a_energy[0]>320||xdata_att7022a_energy[0]<0)
xdata_att7022a_energy[0]=0;
else{
Ram_PK_Init+=(int)(multiple*temp_const/10);
if(Ram_PK_Init>9999){
Ram_PG_Init++;
Ram_PK_Init-=9999;
if(Ram_PK_Init>9999)
Ram_PK_Init=0;
}
}
}
//无功电能累加
if(xdata_att7022a_energy[1]>=320){
multiple=(int)(xdata_att7022a_energy[0]/320);
xdata_att7022a_energy[1]-=multiple*320;
if(xdata_att7022a_energy[1]>320||xdata_att7022a_energy[1]<0)
xdata_att7022a_energy[1]=0;
else{
Ram_QK_Init+=(int)(multiple*temp_const/10);
if(Ram_QK_Init>9999){
Ram_QG_Init++;
Ram_QK_Init-=9999;
if(Ram_QK_Init>9999)
Ram_QK_Init=0;
}
}
}
//正向有功电能累加
if(xdata_att7022a_energy[2]>=320){
multiple=(int)(xdata_att7022a_energy[2]/320);
xdata_att7022a_energy[2]-=multiple*320;
if(xdata_att7022a_energy[2]>320||xdata_att7022a_energy[2]<0)
xdata_att7022a_energy[2]=0;
else{
Ram_PK0_Init+=(int)(multiple*temp_const/10);
if(Ram_PK0_Init>9999){
Ram_PG0_Init++;
Ram_PK0_Init-=9999;
if(Ram_PK0_Init>9999)
Ram_PK0_Init=0;
}
}
}
//反向有功电能累加
if(xdata_att7022a_energy[3]>=320){
multiple=(int)(xdata_att7022a_energy[3]/320);
xdata_att7022a_energy[0]-=multiple*320;
if(xdata_att7022a_energy[3]>320||xdata_att7022a_energy[3]<0)
xdata_att7022a_energy[3]=0;
else{
Ram_PK1_Init+=(int)(multiple*temp_const/10);
if(Ram_PK1_Init>9999){
Ram_PG1_Init++;
Ram_PK1_Init-=9999;
if(Ram_PK1_Init>9999)
Ram_PK1_Init=0;
}
}
}
//正向无功电能累加
if(xdata_att7022a_energy[4]>=320){
multiple=(int)(xdata_att7022a_energy[4]/320);
xdata_att7022a_energy[4]-=multiple*320;
if(xdata_att7022a_energy[4]>320||xdata_att7022a_energy[4]<0)
xdata_att7022a_energy[4]=0;
else{
Ram_QK0_Init+=(int)(multiple*temp_const/10);
if(Ram_QK0_Init>9999){
Ram_QG0_Init++;
Ram_QK0_Init-=9999;
if(Ram_QK0_Init>9999)
Ram_QK0_Init=0;
}
}
}
//反向无功电能累加
if(xdata_att7022a_energy[5]>=320){
multiple=(int)(xdata_att7022a_energy[5]/320);
xdata_att7022a_energy[5]-=multiple*320;
if(xdata_att7022a_energy[5]>320||xdata_att7022a_energy[5]<0)
xdata_att7022a_energy[5]=0;
else{
Ram_QK1_Init+=(int)(multiple*temp_const/10);
if(Ram_QK1_Init>9999){
Ram_QG1_Init++;
Ram_QK1_Init-=9999;
if(Ram_QK1_Init>9999)
Ram_QK1_Init=0;
}
}
}
}
/*******************************************************************************************
** 函数原型:long Change_code(unsigned long *sdata)
** 功能描述:补码转原码函数。
** 参数说明:补码。
** 返 回 值:原码。
** 说 明:
** 注 意:
*******************************************************************************************/
long Change_code(unsigned long *sdata)
{
long temp1;
temp1=*sdata;
if(temp1>8388608)
{
temp1=temp1-16777216;
}
return(temp1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -