上一节我们讨论了cs5464的测量过程及操作方法。这一节我们来看看测量过程的代码实现。下面我给出cs5464的测量代码实现。
/************************************
功能:测量FTU信号
测量顺序:
0---A相参数 Ua、Iap、Pa、Qa、PFa
1---B相参数 Ub、Ibp、Pb、Qb、PFb
2---C相参数 Uc、Icp、Pc、Qc、PFc (更新PSum、PFSum)
3---零序 U0、I0p、P0、Q0、PF0
4---A相负荷 Ia
5---B相负荷 Ib
6---C相负荷 Ic
7---零序
8---线电压 Uca
9---线电压 Ucb
10---线电压 Uab
11---电池电压
************************************/
void ftuMeasure( )
{
//12月27日
#ifdef TEST
char buf[50];
#endif
static unsigned char Mstate=0;
//检查CS5464是否空闲
if(CS5464_MEA.busy==CS5464_IDLE)
{
if(Mstate==0)
{
//选择通道
switch(CS5464_MEA.channel)
{
case M_A_PHASE:
SEL_A_PHASE;
break;
case M_B_PHASE:
SEL_B_PHASE;
break;
case M_C_PHASE:
SEL_C_PHASE;
break;
case M_LX_PHASE:
SEL_LX_PHASE;
break;
case M_A_LOADER:
SEL_A_LOADER;
break;
case M_B_LOADER:
SEL_B_LOADER;
break;
case M_C_LOADER:
SEL_C_LOADER;
break;
case M_LX_LOADER:
SEL_LX_LOADER;
break;
case M_CA_LOADER:
SEL_AC_V;
break;
case M_CB_LOADER:
SEL_CB_V;
break;
case M_AB_LOADER:
SEL_AB_V;
break;
case M_BAT_VOL:
SEL_BAT_VOL;
break;
default:
return;
break;
}
Mstate=1;
//#ifdef TEST
// sprintf(buf,"0,rn");
// uartSendArray(buf,strlen(buf));
// #endif
return;
}
if(Mstate==1)
{
startMeasure( );
CS5464_MEA.busy=CS5464_BUSY;
Mstate=2;
// #ifdef TEST
// sprintf(buf,"1,rn");
// uartSendArray(buf,strlen(buf));
// #endif
return;
}
}
if(Mstate==2)
{
if(meaComplete( )==MEA_COMPLETE)
{
//读取数据
// #ifdef TEST
// sprintf(buf,"3,rn");
// uartSendArray(buf,strlen(buf));
// #endif
Mstate=0;
readMea(CS5464_MEA.channel);
CS5464_MEA.busy=CS5464_IDLE;
CS5464_MEA.channel++;
CS5464_MEA.channel= CS5464_MEA.channel%12;
}
}
}
CS5464_MEA是一个结构体,记录了cs5464关于侧量的信息。结构体定义如下:
#define MEA_COMPLETE 1 //测量完成
#define MEA_NO_COMPLETE 0 //侧量未完成
#define CS5464_BUSY 1 //cs5464忙
#define CS5464_IDLE 0 //cs5464闲
typedef struct CS_MEA_STATE_TYPE
{
unsigned char meaCpFlag; //测量是否完成标志
unsigned char channel; //通道选择
unsigned char busy; //忙标志
unsigned char meaPeriod; //测量周期
}CS5464_MEA_TY;
通道选择采用了宏定义。这样只是为了方便代码编写。
sbit CONA = P3^5;
sbit CONB = P3^7;
sbit CONC = P4^1;
//#define TEST
//#define BAT_TEST
#define SEL_A_LOADER CONC=1; CONB=0; CONA=1//U3的第5路
#define SEL_B_LOADER CONC=1; CONB=0; CONA=0//U3的第4路
#define SEL_C_LOADER CONC=0; CONB=1; CONA=1//U3的第3路
#define SEL_LX_LOADER CONC=1; CONB=1; CONA=1//U3的第7路
#define SEL_A_PHASE CONC=0; CONB=1; CONA=0//U2、U3的第2路
#define SEL_B_PHASE CONC=0; CONB=0; CONA=1//U2、U3的第1路
#define SEL_C_PHASE CONC=0; CONB=0; CONA=0//U2、U3的第0路
#define SEL_LX_PHASE CONC=1; CONB=1; CONA=0//U2、U3的第6路
#define SEL_BAT_VOL CONC=1; CONB=1; CONA=1//U2的第7路
#define SEL_AC_V CONB=0; CONA=0 //U24 X0 Y0
#define SEL_AB_V CONB=0; CONA=1 //U24 X1 Y1
#define SEL_CB_V CONB=1; CONA=0 //U24 X2 Y2
ftuMeasure( ) 每10毫秒会执行执行一次。
测量过程如下:
CS5464是否空闲?如果空闲并且Mstate==0?如果 Mstate的值为0切换测量通道, Mstate的值置1。否侧退出。CS5464空闲吗?开始测量,CS5464_MEA.busy置忙,Mstate的值置2,退出。Mstate的的值是否为2?为2则检查CS5464是否测量结束?如果测量没有结束则退出。如果结束则读取测量结果,并且 CS5464_MEA.busy置空闲,Mstate清零,更新测量通道。
meaComplete( )用于检测测量是否结束。读取STATUS_REG状态寄存器。
/****************************************
功能:检测FTU测量是否完成
MEA_COMPLETE---------------完成
MEA_NO_COMPLETE---------------未完成
*****************************************/
bit meaComplete( )
{
char dat[4];
static unsigned flag=0;
if(flag==0)
{
//页寄存器置0
dat[0] = (PAGE_REG<<1)|0x40;
dat[1] = 0x00;
dat[2] = 0x00;
dat[3] = 0x00;
Write_CS5464(dat,4);
//清除状态寄存器
dat[0] = (STATUS_REG<<1)|0x40;
dat[1] = 0x80;
dat[2] = 0x00;
dat[3] = 0x00;
Write_CS5464(dat,4); //页寄存器置1
flag=1;
}
//读取state寄存器
Read_5464(STATUS_REG<<1,dat);
if(dat[0]&0x80)
{
flag=0;
return MEA_COMPLETE;
}
else
{
return MEA_NO_COMPLETE;
}
//return dat[0]&0x80;
}
下一节我们浏览读取测量结果的函数-----readMea(CS5464_MEA.channel)。