yijingkun 发表于 2014-7-10 11:37:11

ATT7022E只接B相,电压电流读取正确,有功读取不正确,求助

本帖最后由 yijingkun 于 2014-7-11 11:11 编辑

问题已经解决,谢谢楼下各位帮助


三相只接了B相,电压直接接的交流220V,电流串接一个50欧的陶瓷功率电阻,应该是纯阻性的负载,目前读出电压值、电流值都比较接近(实测电压差几伏,电流差不到1A),但是有功功率至少应该是1000多W,可我读到的是34W还是负值,不知道哪里的问题,是不是校表程序有问题呢?求助。电压互感器是电流型的,2mA/2mA,电流互感器额定输入5A,输出2.5mA,电流实测接功率电阻后4.15A,互感器输出2.08mA。

功率校准和HFconst有关系吗,我写不同的HFCONST值,读到的有功都是-34W,有功功率是否只是和电压电流、相位角有关系?


/*校表函数*/
void ATT_Adjust(void)
{
        u32 read1=0x55;

        SPI_ATT_Write(0xC3, 0x000000);                //清校表数据
        SPI_ATT_Write(0xC9, 0x00005A);                //打开校准数据写

        SPI_ATT_Write(0x01, 0xB9FE);                //填写模式配置寄存器
        SPI_ATT_Write(0x03, 0xF804);                //填写EMU单元配置寄存器
        SPI_ATT_Write(0x31, 0x3437);                //填写模拟模块使能寄存器
        SPI_ATT_Write(0x02, 0x0000);                //各路ADC增益均为1

        SPI_ATT_Write(0x6D, 0xFF00);                //
        SPI_ATT_Write(0x6E, 0x0DB8);                //
        SPI_ATT_Write(0x6F, 0xD1DA);                //

        SPI_ATT_Write(UADC, 0x000000);                //电压通道增益为1
//        SPI_ATT_Write(HFconst, 0x00016D);        //高频输出参数为1511
///*----------------------------------------
//    分相电压电流校准参数
//-----------------------------------------*/
//        SPI_ATT_Write(UgainA, 0x000000);
//        SPI_ATT_Write(UgainB, 0x000000);
//        SPI_ATT_Write(UgainC, 0x8172F5);        //8483573

        SPI_ATT_Write(0xC9, 0x000001);                //关闭校准数据写

        SPI_ATT_Write(0xC6, 0x00005A);                //校表数据读出使能
        read1=SPI_ATT_Read(0x00);
        printf("\r\nIn 0xC6 with 0x5A: 0x00 is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x01);
        printf("\r\nModeCfg is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x03);
        printf("\r\nEMUCfg is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x31);
        printf("\r\nModuleCfg is %x !\r\n",read1);
        read1=0x55;

        SPI_ATT_Write(0xC6, 0x000001);                //计量数据读出使能
        read1=SPI_ATT_Read(0x00);
        printf("\r\nIn 0xC6 without 0x5A: 0x00 is %x !\r\n",read1);
}

/*试验函数(为了避免main中太多代码而设)*/
void ATT_Test(void)
{
        u32 read=0x55;

        read=SPI_ATT_Read(0x00);
        printf("\r\nDevice ID is %x !\r\n",read);
        read=0x55;

//         printf("\r\nReading A...\r\n");
//         Read_ATT_AData();

        printf("\r\nReading B...\r\n");
        Read_ATT_BData();

//         printf("\r\nReading C...\r\n");
//         Read_ATT_CData();

//         printf("\r\nReading T...\r\n");
//         Read_ATT_TData();
}



/*读B相结果函数*/
void Read_ATT_BData(void)
{
        BDataTypeDef.P=SPI_ATT_Read(r_Pb);
        BDataTypeDef.Q=SPI_ATT_Read(r_Qb);
        BDataTypeDef.S=SPI_ATT_Read(r_Sb);
        BDataTypeDef.URms=SPI_ATT_Read(r_UbRms);
        BDataTypeDef.IRms=SPI_ATT_Read(r_IbRms);
        BDataTypeDef.Pf=SPI_ATT_Read(r_Pfb);
        if(BDataTypeDef.P>0x800000){
                BDataTypeDef.Rp=0x1000000-BDataTypeDef.P;
                BDataTypeDef.Rp=-(BDataTypeDef.Rp/256.0);    //   2^15/2^23
        }
        else
                BDataTypeDef.Rp=BDataTypeDef.P/256.0;
        if(BDataTypeDef.Q>0x800000){
                BDataTypeDef.Rq=0x1000000-BDataTypeDef.Q;
                BDataTypeDef.Rq=-(BDataTypeDef.Rq/256.0);
        }
        else
                BDataTypeDef.Rq=BDataTypeDef.Q/256.0;
        BDataTypeDef.Rs=BDataTypeDef.S/256.0;
        BDataTypeDef.Rurms=BDataTypeDef.URms/8192.0;   //   2^10/2^23
        BDataTypeDef.Rirms=BDataTypeDef.IRms/8192.0;
        if(BDataTypeDef.Pf>0x800000){
                BDataTypeDef.Rpf=0x1000000-BDataTypeDef.Pf;
                BDataTypeDef.Rpf=-(BDataTypeDef.Rpf/8388608.0);
        }
        else
                BDataTypeDef.Rpf=BDataTypeDef.Pf/8388608.0;

        Lcd_Clr();
        sprintf(disp0,"B phase:");
        Lcd_Puts(7,0,disp0);
        Output_ATT(BDataTypeDef);
}

yijingkun 发表于 2014-7-10 12:40:50

自己顶一下,勿沉

abbott 发表于 2014-7-10 13:01:54

不知道什么原因,随便说一下!
会不会设置为三相三线模式了?

yijingkun 发表于 2014-7-10 13:03:39

abbott 发表于 2014-7-10 13:01
不知道什么原因,随便说一下!
会不会设置为三相三线模式了?

没有,SEL管脚我已经接高了。不过多谢回复。

abbott 发表于 2014-7-10 13:13:58

yijingkun 发表于 2014-7-10 13:03
没有,SEL管脚我已经接高了。不过多谢回复。

寄存器中是否也有相关设置?
功率因数也看一下,会不会功率因数导致不正确?

yijingkun 发表于 2014-7-10 13:27:52

abbott 发表于 2014-7-10 13:13
寄存器中是否也有相关设置?
功率因数也看一下,会不会功率因数导致不正确? ...

我再仔细看看手册,不过我校表程序中没有写功率因数相关的寄存器啊。

yijingkun 发表于 2014-7-10 13:31:48

有功功率读数是 ffddfa,手册上说是补码,怎么会是负值啊,读出数来到底怎么计算啊,我没用标准功率源和标准表,HFconst和EC到底怎么确定啊

yijingkun 发表于 2014-7-10 13:43:43

给上海焗泉打电话,让把电流反接,现在读到的数是0x2130,但是怎么计算出正确有功功率值啊

yijingkun 发表于 2014-7-10 14:28:45

顶,勿沉

xjmlfm1 发表于 2014-7-10 14:36:40

楼主是刚开始做电力行业产品吗?
功率为负,首先想到的就是电流接反了。

yijingkun 发表于 2014-7-10 15:09:53

本帖最后由 yijingkun 于 2014-7-10 15:12 编辑

对,以前没干电力行业,现在功率是正的了,读数是0x2130,我搞不懂怎么换算成实际的功率值,HFconst、EC怎么确定,我又没用到功率源、标准表,手册上说HFconst是高频脉冲常数,这个我理解和脉冲输出有关系的,和有功功率采集应该没关系啊,EC手册上有的地方说是脉冲常数,有的地方又说是电表常数,有点儿晕。

czdavid 发表于 2014-7-10 15:23:35

电表常数就是脉冲常数。
先定义好HFconst吧,不然出来的值不对。
要显示正确,必须进行校正。

binghe167 发表于 2014-7-10 15:28:15

ATT7022E/26E/28E功率寄存器采用补码形式给出,最高位是符号位,所以根据ATT7022E/26E/28E
功率寄存器给出的有功和无功功率的方向,可以直接得到当前所处的象限。视在功率总是大于或者等
于0,所以视在功率的符号位始终为0。
功率寄存器格式定义:
A/B/C分相功率参数:X
X:24位数据,补码形式
如果X>2^23,则XX=X-2^24
否则 XX=X
实际的A/B/C分相功率参数为:XXX=XX*K(其中K为功率参数系数,所有功率参数共用)。
A/B/C合相功率参数:T
T:24位数据,补码形式
如果T>2^23,则TT=T-2^24
否则 TT=T
实际的合相功率参数为:TTT=TT*2*K(其中K为功率参数系数,所有功率参数共用)。
单位:功率单位是瓦(W),功率系数K=2.592*10^10/(HFconst*EC*2^23)
其中HFconst为寄存器HFconst写入值,EC为电表常数


用户手册上写了啊

binghe167 发表于 2014-7-10 15:30:27

#define Meter_Ib        5.0                        //基本电流
#define Meter_Im        50.0                //最大电流
#define Meter_CT        5000.0                //互感器变比
#define Meter_Un        220.0                //参比电压
#define Meter_Ec        100                        //脉冲常数
#define Meter_Igain        2                        //电流通道ADC增益
//#define Meter_Vr
#define Meter_Ir        10.0                //电流取样电阻
#define        Meter_Vu        183.18                //电压取样输入mV       

//电流取样输入mV
#define Meter_Vi        (1000.0*Meter_Ir*Meter_Ib*Meter_Igain/Meter_CT)       
#define Meter_G                1.163                //ATT7022E常数
#define Meter_nI        6.0                        //电流比例常数

//高频脉冲常数
#define Meter_HFConst        ((2.592*Meter_G*Meter_G*Meter_Vi*Meter_Vu*10000.0)/(Meter_Ib*Meter_Un*Meter_Ec))
#define Meter_K                        (3089.9/(Meter_HFConst*Meter_Ec))

给你个我的定义,供你参考

yijingkun 发表于 2014-7-10 15:49:52

本帖最后由 yijingkun 于 2014-7-10 15:57 编辑

binghe167 发表于 2014-7-10 15:28
ATT7022E/26E/28E功率寄存器采用补码形式给出,最高位是符号位,所以根据ATT7022E/26E/28E
功率寄存器给出 ...

先谢谢你的答复,我就是这段看不明白:

如果X>2^23,则XX=X-2^24
否则 XX=X
实际的A/B/C分相功率参数为:XXX=XX*K(其中K为功率参数系数,所有功率参数共用)。XX=X,XX是什么意思啊?是X的平方吗?还有我没有用标准表,怎么确定电表常数啊?所以也没法确定HFconst的值。
我是三相电只接了B相,电压直接接的交流220V,电流串接一个50欧的陶瓷功率电阻,万用表测电流,通过负载电流是4.15A,电流互感器输出2.05毫安。

实际的A/B/C分相功率参数为:XXX=XX*K,XXX又是什么意思?

电流接线反接一下现在是正值了,读寄存器是0x2130,也就是十进制的:8,496,这个值肯定不是实际功率值,没法确定EC、就没法确定HFconst、就没法确定K。

我的理解:读到电压和电流值,只要误差不太大,7022E芯片就可以计算出B相的有功功率了,只是精度可能受HFconst等参数的影响,所以才需要校表,但是现在是读到的0x2130这个值,我不知道怎么换算成实际功率值,220V×4.15A,
功率应该是一千多W才对,也不知道读到的0x2130是否正确的。

yijingkun 发表于 2014-7-10 16:12:09

UP,求助ing

binghe167 发表于 2014-7-10 17:19:39

我在14楼都已经给出这些值得定义了啊
有功功率=0x2130*Meter_K

yijingkun 发表于 2014-7-10 17:22:09

本帖最后由 yijingkun 于 2014-7-10 17:24 编辑

binghe167 发表于 2014-7-10 17:19
我在14楼都已经给出这些值得定义了啊
有功功率=0x2130*Meter_K

可是我现在确定不了EC啊,EC确定不了,还是得不到K是多少啊?你的定义是:#define Meter_K                        (3089.9/(Meter_HFConst*Meter_Ec))

binghe167 发表于 2014-7-10 17:41:28

Ec自己随便定的啊

yijingkun 发表于 2014-7-11 09:09:13

binghe167 发表于 2014-7-10 17:41
Ec自己随便定的啊

算出来了,给上海的打电话,EC让按照3200定,现在算出来有功是1174W,谢楼上了。得到单相的电压,电流,确定了常数EC就可以算出功率了,只是如果需要提高精度,那么就必须认真校表了。至于手册中关于功率计算的描述,
什么XX=X,还是没搞明白什么意思。

zhangsai 发表于 2014-7-19 22:59:40

各位,呵呵,用7022E,有效值,不做平均处理的话,按1.76Hz的更新速率,U和I,跳变大吗?我不会又人品爆发了吧?目前情况比较惨。可没有以前的CS5460稳。正在处理中。

yijingkun 发表于 2014-7-28 16:30:22

zhangsai 发表于 2014-7-19 22:59
各位,呵呵,用7022E,有效值,不做平均处理的话,按1.76Hz的更新速率,U和I,跳变大吗?我不会又人品爆发 ...

我还没调到这一步,只是数据都读到了,误差不是太离谱,还要校表,所以没法确定跳变大不大

raosibin 发表于 2014-8-11 16:03:06

MARK,值得借鉴

125591656 发表于 2014-8-25 16:19:37

MARK,学习中

yijingkun 发表于 2014-8-25 16:33:29

目前进度汇报,三相电压、电流、有功、无功、PF、频率神马的都出来了,我没有三相标准功率源,ABC三相都是单相测试的,不校准情况下,先提高硬件精度,硬件主要是调PT、CT的采样电阻,然后不校准情况下,读出来的数据误差稍大,电压值比较准、电流值差了3~5%,功率值差的多一些,有功实测1.2k,标准表1.1k,无功1.2k,标准表1.5k。
有个问题不知道为什么,7022E的CT按照手册上应该接5.1R的,我是接0.88R才能比较准,没找的原因。校表不打算写7022E的寄存器,直接把电压、电流、功率的校正值写到板子的EEPROM里面,再计算出校准后的值就可以了。

yijingkun 发表于 2014-8-25 16:43:31

项目正在做,没法全部代码都公开,就把main、7022.c、7022.H放上来吧,事先说明,不是我原创的,核心的7022代码,是从PUDN下载下来然后修改的,程序模板用的原子的战舰版的例程。

7022.h
#ifndef _ATT7022_H_
#define _ATT7022_H_

#include "STM32F10X.h"
#include "math.h"

/*
   RST        PC3
   CS        PC6
   SCL        PC7
   DIN        PC8
   DOUT        PC9        (DATA)
*/

#define RST_Port        GPIOB
#define CS_Port                GPIOB
#define SCL_Port        GPIOB
#define DATA_Port        GPIOB
#define DIN_Port        GPIOB

#define RST_Pin                GPIO_Pin_0
#define CS_Pin                GPIO_Pin_12
#define SCL_Pin                GPIO_Pin_13
#define DATA_Pin        GPIO_Pin_15
#define DIN_Pin                GPIO_Pin_14

#define Set_CS                 GPIO_SetBits (CS_Port, CS_Pin)
#define Clr_CS                 GPIO_ResetBits (CS_Port, CS_Pin)
#define Rev_CS                GPIO_WriteBit(CS_Port, CS_Pin, (BitAction)(1 - GPIO_ReadOutputDataBit(CS_Port, CS_Pin)))

#define Set_SCL        GPIO_SetBits (SCL_Port, SCL_Pin)
#define Clr_SCL        GPIO_ResetBits (SCL_Port, SCL_Pin)
#define Rev_SCL                GPIO_WriteBit(SCL_Port, SCL_Pin, (BitAction)(1 - GPIO_ReadOutputDataBit(SCL_Port, SCL_Pin)))

#define Set_DATA        GPIO_SetBits (DATA_Port, DATA_Pin)
#define Clr_DATA        GPIO_ResetBits (DATA_Port, DATA_Pin)
#define Rev_DATA        GPIO_WriteBit(DATA_Port, DATA_Pin, (BitAction)(1 - GPIO_ReadOutputDataBit(DATA_Port, DATA_Pin)))

#define Set_RST         GPIO_SetBits (RST_Port, RST_Pin)
#define Clr_RST         GPIO_ResetBits (RST_Port, RST_Pin)
#define Rev_RST                GPIO_WriteBit(RST_Port, LED54_Pin, (BitAction)(1 - GPIO_ReadOutputDataBit(RST_Port, RST_Pin)))

#define Rd_MISO                GPIO_ReadInputDataBit(DIN_Port, DIN_Pin)==1

#define r_Pflag 0x3D//功率方向
#define R_Sflag 0x2C//状态寄存器

#define r_Pa 0x01
#define r_Pb 0x02
#define r_Pc 0x03
#define r_Pt 0x04    //有功功率

#define r_Qa 0x05
#define r_Qb 0x06
#define r_Qc 0x07
#define r_Qt 0x08    //无功功率

#define r_Sa 0x09
#define r_Sb 0x0A
#define r_Sc 0x0B
#define r_St 0x0C    //视在功率

#define r_UaRms 0x0D
#define r_UbRms 0x0E
#define r_UcRms 0x0F
#define r_UtRms 0x2B
#define r_IaRms 0x10
#define r_IbRms 0x11
#define r_IcRms 0x12
#define r_ItRms 0x13//电压电流有效值

#define r_Pfa 0x14
#define r_Pfb 0x15
#define r_Pfc 0x16
#define r_Pft 0x17   //功率因数

#define r_Freq 0x1C//线网频率

#define r_Epa 0x1E
#define r_Epb 0x1F
#define r_Epc 0x20
#define r_Ept 0x21    //累加型有功电能

#define r_Eqa 0x22
#define r_Eqb 0x23
#define r_Eqc 0x24
#define r_Eqt 0x25    //累加型无功电能

#define r_Epa2 0x31
#define r_Epb2 0x32
#define r_Epc2 0x33
#define r_Ept2 0x34    //清零型有功电能

#define r_Eqa2 0x35
#define r_Eqb2 0x36
#define r_Eqc2 0x37
#define r_Eqt2 0x38    //清零型无功电能

#define HFconst        0xA0   //高频输出参数
#define UADC        0xBF   //电压通道增益
#define UgainA        0x9B
#define UgainB        0x9C
#define UgainC        0x9D
#define IgainA        0x1A
#define IgainB        0x1B
#define IgainC        0x1C   //分相电压电流校准

#define PgainB        0x05       //B相有功功率增益

#define Vu0.190                //电压通道采样电压
#define Vi0.003                //电流通道采样电压
#define Un220                        //额定电压
#define In4.15                //额定电流
#define Meter_G                1.163                //ATT7022E常数
//#define Meter_HFConst      ((2.592*1E10*Meter_G*Meter_G*Vu*Vi)/(In*Un*Meter_Ec))
#define Meter_HFConst      ((2.592*pow(10,10)*Meter_G*Meter_G*Vu*Vi)/(In*Un*Meter_Ec))
#define Meter_K                        (2.592*pow(10,10)/(Meter_HFConst*Meter_Ec*pow(2,23)))

extern u16 Meter_Ec;                        //电表常数
// extern float I_Amp_Factor;                //电流放大倍数
// extern float V_Amp_Factor;                //电压放大倍数
// extern float Pa_Gain_compensation;                //A相有功功率补偿系数
// extern float Pha_compensation;                //A相相位补偿补偿系数


typedef struct
{
        u32 P;         //有功功率
        float Rp;
        u32 Q;         //无功功率
        float Rq;
        u32 S;         //视在功率
        float Rs;
        u32 URms;      //电压有效值
        float Rurms;
        u32 IRms;      //电流有效值
        float Rirms;
        u32 Pf;          //功率因数
        float Rpf;
        u32 Freq;      //线网频率
        float Rfreq;
}DataTypeDef;

extern DataTypeDef ADataTypeDef,BDataTypeDef,CDataTypeDef,TDataTypeDef;

typedef struct
{
// u16 Meter_Ec;                        //电表常数
float I_Amp_Factor;                //电流放大倍数
float V_Amp_Factor;                //电压放大倍数
float P_Gain_compensation;                //A相有功功率补偿系数
float Ph_compensation;                //A相相位补偿补偿系数
}Meter_Adj_Val_Stru_Def;

extern Meter_Adj_Val_Stru_Def PhaseA,PhaseB,PhaseC;


extern void delay_ms(u16 time);
extern void delay_us(u32 nus);
u32 SPI_ATT_Read(u8 data);             //SIG --> Sflag.7
void SPI_ATT_Write(u8 com_add,u32 data2);//0xD3,0x000000 可进行软件复位
void ATT7022_Init(void);
void ATT_Adjust(void);
void ATT_Test(void);
void Read_ATT_AData(void);
void Read_ATT_BData(void);
void Read_ATT_CData(void);
void Read_ATT_TData(void);

void Output_ATT(DataTypeDef output);
void Read_ATT_TestData(void);

#endif


7022.c
#include "ATT7022.h"
#include "stdio.h"
#include "Lcd1602.h"

extern int fputc(int ch, FILE *f);
extern char disp0;
extern char disp1;
extern char disp2;
extern char disp3;
extern DataTypeDef ADataTypeDef,BDataTypeDef,CDataTypeDef,TDataTypeDef;

DataTypeDef ADataTypeDef,BDataTypeDef,CDataTypeDef,TDataTypeDef;
Meter_Adj_Val_Stru_Def PhaseA={1.0,1.0,0.0,0.0},PhaseB={1.0,1.0,0.0,0.0},PhaseC={1.0,1.0,0.0,0.0};

u16 Meter_Ec = 3200;                        //电表常数

//7022初始化
void ATT7022_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PORTA,PORTE时钟
        GPIO_InitStructure.GPIO_Pin = RST_Pin|CS_Pin|SCL_Pin|DATA_Pin;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //复用推挽输出
        GPIO_Init(GPIOB,&GPIO_InitStructure);

        Clr_SCL;
       
    GPIO_InitStructure.GPIO_Pin = DIN_Pin;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
        GPIO_Init(DIN_Port,&GPIO_InitStructure);

        //硬件复位
        Clr_RST;
        delay_us(30);
        Set_RST;
        delay_us(600);
}

/*校表函数*/
void ATT_Adjust(void)
{
        u32 read1=0x55;

        SPI_ATT_Write(0xC3, 0x000000);                //清校表数据
        SPI_ATT_Write(0xC9, 0x00005A);                //打开校准数据写

        SPI_ATT_Write(0x01, 0xB9FE);                //填写模式配置寄存器
        SPI_ATT_Write(0x03, 0xF804);                //填写EMU单元配置寄存器
        SPI_ATT_Write(0x31, 0x3437);                //填写模拟模块使能寄存器
        SPI_ATT_Write(0x02, 0x0000);                //各路ADC增益均为1

        SPI_ATT_Write(0x6D, 0xFF00);                //
        SPI_ATT_Write(0x6E, 0x0DB8);                //
        SPI_ATT_Write(0x6F, 0xD1DA);                //

        SPI_ATT_Write(UADC, 0x000000);                //电压通道增益为1
       
//        SPI_ATT_Write(HFconst, 0x00016D);        //高频输出参数为1511
///*----------------------------------------
//    分相电压电流校准参数
//-----------------------------------------*/
//        SPI_ATT_Write(UgainA, 0x000000);
//        SPI_ATT_Write(UgainB, 0x000000);
//        SPI_ATT_Write(UgainC, 0x8172F5);        //8483573

        SPI_ATT_Write(0xC9, 0x000001);                //关闭校准数据写

        SPI_ATT_Write(0xC6, 0x00005A);                //校表数据读出使能
        read1=SPI_ATT_Read(0x00);
        printf("\r\nIn 0xC6 with 0x5A: 0x00 is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x01);
        printf("\r\nModeCfg is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x03);
        printf("\r\nEMUCfg is %x !\r\n",read1);
        read1=0x55;

        read1=SPI_ATT_Read(0x31);
        printf("\r\nModuleCfg is %x !\r\n",read1);
        read1=0x55;

        SPI_ATT_Write(0xC6, 0x000001);                //计量数据读出使能
        read1=SPI_ATT_Read(0x00);
        printf("\r\nIn 0xC6 without 0x5A: 0x00 is %x !\r\n",read1);
}

/*试验函数(为了避免main中太多代码而设)*/
void ATT_Test(void)
{
        u32 read=0x55;

        read=SPI_ATT_Read(0x00);
        printf("\r\nDevice ID is %x !\r\n",read);
        read=0x55;

        printf("\r\nReading A...\r\n");
        Read_ATT_AData();
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);

        printf("\r\nReading B...\r\n");
        Read_ATT_BData();
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);

        printf("\r\nReading C...\r\n");
        Read_ATT_CData();
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);

//         printf("\r\nReading T...\r\n");
//         Read_ATT_TData();
}

/*SPI读操作*/
u32 SPI_ATT_Read(u8 data)
{
        u8 i;
        u32 temp=0;
        Set_CS;
        Clr_SCL;
        Clr_CS;   //片选为低,开始操作
           for(i=0;i<8;i++)
        {
                Set_SCL;
                delay_us(50);
                   if(data&0x80)
                           Set_DATA;
                   else
                           Clr_DATA;
                delay_us(3);   //稳定数据
                   Clr_SCL;
                delay_us(50);
                data<<=1;//左移数据
        }
        delay_us(3);       //稳定数据       
        for(i=0;i<24;i++)
        {
                temp<<=1;
                   Set_SCL;
                delay_us(50);
                   if(Rd_MISO)
                           temp|=0x01;
                   Clr_SCL;
                delay_us(50);
        }
        Set_CS;
        return (temp);
}

/*SPI写操作*/
void SPI_ATT_Write(u8 com_add,u32 data2)
{
        u8 i,data1;
        data1=0x80|com_add;
        Set_CS;
        Clr_SCL;
        Clr_CS;   //片选为低,开始操作
           for(i=0;i<8;i++)
        {
                Set_SCL;
                delay_us(50);
                   if(data1&0x80)
                           Set_DATA;
                   else
                           Clr_DATA;
                delay_us(3);
                   Clr_SCL;
                delay_us(50);
                data1<<=1;//左移数据
        }
        for(i=0;i<24;i++)
        {
                   Set_SCL;
                delay_us(50);
                   if(data2&0x00800000)
                           Set_DATA;
                   else
                           Clr_DATA;
                delay_us(3);
                   Clr_SCL;
                delay_us(50);

                   data2<<=1;
        }
        Set_CS;
}

//以下为各相常用数据读取
void Read_ATT_AData(void)
{
        ADataTypeDef.P=SPI_ATT_Read(r_Pa);
        ADataTypeDef.Q=SPI_ATT_Read(r_Qa);
        ADataTypeDef.S=SPI_ATT_Read(r_Sa);
        ADataTypeDef.URms=SPI_ATT_Read(r_UaRms);
        ADataTypeDef.IRms=SPI_ATT_Read(r_IaRms);
        ADataTypeDef.Pf=SPI_ATT_Read(r_Pfa);
        ADataTypeDef.Freq=SPI_ATT_Read(r_Freq);
        if(ADataTypeDef.P>0x800000){
                ADataTypeDef.Rp=0x1000000-ADataTypeDef.P;
                ADataTypeDef.Rp=-((ADataTypeDef.Rp*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\
                -((ADataTypeDef.Rp*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation));    //   2^15/2^23
        }
        else
                ADataTypeDef.Rp=(ADataTypeDef.P*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\
                -((ADataTypeDef.P*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation);
        if(ADataTypeDef.Q>0x800000){
                ADataTypeDef.Rq=0x1000000-ADataTypeDef.Q;
                ADataTypeDef.Rq=-((ADataTypeDef.Rq*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\
                -((ADataTypeDef.Rq*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation));
        }
        else
                ADataTypeDef.Rq=(ADataTypeDef.Q*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\
                -((ADataTypeDef.Q*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation);
        ADataTypeDef.Rs=ADataTypeDef.S/256.0;
        ADataTypeDef.Rurms=ADataTypeDef.URms/8192.0*PhaseA.V_Amp_Factor;   //   2^10/2^23
        ADataTypeDef.Rirms=ADataTypeDef.IRms/8192.0*PhaseA.I_Amp_Factor;
        if(ADataTypeDef.Pf>0x800000){
                ADataTypeDef.Rpf=0x1000000-ADataTypeDef.Pf;
                ADataTypeDef.Rpf=-((ADataTypeDef.Rpf/8388608.0)-((ADataTypeDef.Rpf/8388608.0)*PhaseA.Ph_compensation));
        }
        else
                ADataTypeDef.Rpf=(ADataTypeDef.Pf/8388608.0)-((ADataTypeDef.Pf/8388608.0)*PhaseA.Ph_compensation);
        ADataTypeDef.Rfreq=ADataTypeDef.Freq/8192.0;

//         Lcd_Clr();
//         sprintf(disp0,"A phase:");
//         Lcd_Puts(7,0,disp0);
//        Output_ATT(ADataTypeDef);
}

void Read_ATT_BData(void)
{
        BDataTypeDef.P=SPI_ATT_Read(r_Pb);
        BDataTypeDef.Q=SPI_ATT_Read(r_Qb);
        BDataTypeDef.S=SPI_ATT_Read(r_Sb);
        BDataTypeDef.URms=SPI_ATT_Read(r_UbRms);
        BDataTypeDef.IRms=SPI_ATT_Read(r_IbRms);
        BDataTypeDef.Pf=SPI_ATT_Read(r_Pfb);
        BDataTypeDef.Freq=SPI_ATT_Read(r_Freq);
        if(BDataTypeDef.P>0x800000){
                BDataTypeDef.Rp=0x1000000-BDataTypeDef.P;
                BDataTypeDef.Rp=-((BDataTypeDef.Rp*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))\
                -((BDataTypeDef.Rp*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))*PhaseB.P_Gain_compensation));    //   2^15/2^23
        }
        else
                BDataTypeDef.Rp=(BDataTypeDef.P*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))\
                -((BDataTypeDef.P*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))*PhaseB.P_Gain_compensation);
        if(BDataTypeDef.Q>0x800000){
                BDataTypeDef.Rq=0x1000000-BDataTypeDef.Q;
                BDataTypeDef.Rq=-((BDataTypeDef.Rq*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))\
                -((BDataTypeDef.Rq*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))*PhaseB.P_Gain_compensation));
        }
        else
                BDataTypeDef.Rq=(BDataTypeDef.Q*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))\
                -((BDataTypeDef.Q*Meter_K*fabs(PhaseB.I_Amp_Factor)*fabs(PhaseB.V_Amp_Factor))*PhaseB.P_Gain_compensation);
        BDataTypeDef.Rs=BDataTypeDef.S/256.0;
        BDataTypeDef.Rurms=BDataTypeDef.URms/8192.0*PhaseB.V_Amp_Factor;   //   2^10/2^23
        BDataTypeDef.Rirms=BDataTypeDef.IRms/8192.0*PhaseB.I_Amp_Factor;
        if(BDataTypeDef.Pf>0x800000){
                BDataTypeDef.Rpf=0x1000000-BDataTypeDef.Pf;
                BDataTypeDef.Rpf=-((BDataTypeDef.Rpf/8388608.0)-((BDataTypeDef.Rpf/8388608.0)*PhaseB.Ph_compensation));
        }
        else
                BDataTypeDef.Rpf=(BDataTypeDef.Pf/8388608.0)-((BDataTypeDef.Pf/8388608.0)*PhaseB.Ph_compensation);
        BDataTypeDef.Rfreq=BDataTypeDef.Freq/8192.0;

//         Lcd_Clr();
//         sprintf(disp0,"B phase:");
//         Lcd_Puts(7,0,disp0);
//         Output_ATT(BDataTypeDef);
}

void Read_ATT_CData(void)
{
        CDataTypeDef.P=SPI_ATT_Read(r_Pc);
        CDataTypeDef.Q=SPI_ATT_Read(r_Qc);
        CDataTypeDef.S=SPI_ATT_Read(r_Sc);
        CDataTypeDef.URms=SPI_ATT_Read(r_UcRms);
        CDataTypeDef.IRms=SPI_ATT_Read(r_IcRms);
        CDataTypeDef.Pf=SPI_ATT_Read(r_Pfc);
        CDataTypeDef.Freq=SPI_ATT_Read(r_Freq);
        if(CDataTypeDef.P>0x800000){
                CDataTypeDef.Rp=0x1000000-CDataTypeDef.P;
                CDataTypeDef.Rp=-((CDataTypeDef.Rp*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))\
                -((CDataTypeDef.Rp*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))*PhaseC.P_Gain_compensation));    //   2^15/2^23
        }
        else
                CDataTypeDef.Rp=(CDataTypeDef.P*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))\
                -((CDataTypeDef.P*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))*PhaseC.P_Gain_compensation);
        if(CDataTypeDef.Q>0x800000){
                CDataTypeDef.Rq=0x1000000-CDataTypeDef.Q;
                CDataTypeDef.Rq=-((CDataTypeDef.Rq*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))\
                -((CDataTypeDef.Rq*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))*PhaseC.P_Gain_compensation));
        }
        else
                CDataTypeDef.Rq=(CDataTypeDef.Q*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))\
                -((CDataTypeDef.Q*Meter_K*fabs(PhaseC.I_Amp_Factor)*fabs(PhaseC.V_Amp_Factor))*PhaseC.P_Gain_compensation);
        CDataTypeDef.Rs=CDataTypeDef.S/256.0;
        CDataTypeDef.Rurms=CDataTypeDef.URms/8192.0*PhaseC.V_Amp_Factor;   //   2^10/2^23
        CDataTypeDef.Rirms=CDataTypeDef.IRms/8192.0*PhaseC.I_Amp_Factor;
        if(CDataTypeDef.Pf>0x800000){
                CDataTypeDef.Rpf=0x1000000-CDataTypeDef.Pf;
                CDataTypeDef.Rpf=-((CDataTypeDef.Rpf/8388608.0)-((CDataTypeDef.Rpf/8388608.0)*PhaseC.Ph_compensation));
        }
        else
                CDataTypeDef.Rpf=(CDataTypeDef.Pf/8388608.0)-((CDataTypeDef.Pf/8388608.0)*PhaseC.Ph_compensation);
        CDataTypeDef.Rfreq=CDataTypeDef.Freq/8192.0;

//         Lcd_Clr();
//         sprintf(disp0,"C phase:");
//         Lcd_Puts(7,0,disp0);
//         Output_ATT(CDataTypeDef);
}

void Read_ATT_TData(void)
{
        TDataTypeDef.P=SPI_ATT_Read(r_Pt);
        TDataTypeDef.Q=SPI_ATT_Read(r_Qt);
        TDataTypeDef.S=SPI_ATT_Read(r_St);
        TDataTypeDef.URms=SPI_ATT_Read(r_UtRms);
        TDataTypeDef.IRms=SPI_ATT_Read(r_ItRms);
        TDataTypeDef.Pf=SPI_ATT_Read(r_Pft);
        TDataTypeDef.Freq=SPI_ATT_Read(r_Freq);
        if(TDataTypeDef.P>0x800000){
                TDataTypeDef.Rp=0x1000000-TDataTypeDef.P;
                TDataTypeDef.Rp=-(TDataTypeDef.Rp/64.0);    //   2^17/2^23
        }
        else
                TDataTypeDef.Rp=TDataTypeDef.P/64.0;
        if(TDataTypeDef.Q>0x800000){
                TDataTypeDef.Rq=0x1000000-TDataTypeDef.Q;
                TDataTypeDef.Rq=-(TDataTypeDef.Rq/64.0);
        }
        else
                TDataTypeDef.Rq=TDataTypeDef.Q/64.0;
        TDataTypeDef.Rs=TDataTypeDef.S/64.0;
        TDataTypeDef.Rurms=TDataTypeDef.URms/8192.0;   //   2^10/2^23
        TDataTypeDef.Rirms=TDataTypeDef.IRms/8192.0;
        if(TDataTypeDef.Pf>0x800000){
                TDataTypeDef.Rpf=0x1000000-TDataTypeDef.Pf;
                TDataTypeDef.Rpf=-(TDataTypeDef.Rpf/8388608.0);
        }
        else
                TDataTypeDef.Rpf=TDataTypeDef.Pf/8388608.0;
        TDataTypeDef.Rfreq=TDataTypeDef.Freq/8192.0;

        Output_ATT(TDataTypeDef);
}

void Output_ATT(DataTypeDef output)
{
        sprintf(disp1,"U:%.2fV,I:%.2fA",output.Rurms,output.Rirms);
        if(output.Rp<=999.9)
                sprintf(disp2,"P:%.2fW,Q:%.2fVar",output.Rp,output.Rq);
        if(output.Rp>999.9)
                sprintf(disp2,"P:%.1fkW,Q:%.1fkVar",(output.Rp/1000.0),(output.Rq/1000.0));
        sprintf(disp3,"Pf:%.3f,F:%.3fHz",output.Rpf,output.Rfreq);
        Lcd_Puts(0,1,disp1);
        Lcd_Puts(0,2,disp2);
        Lcd_Puts(0,3,disp3);
        printf("\r\n********************\r\n");
        printf("\r\nP = %x !\r\n",output.P);
        printf("\r\n    %f !\r\n",output.Rp);
        printf("\r\nQ = %x !\r\n",output.Q);
        printf("\r\n    %f !\r\n",output.Rq);       
        printf("\r\nS = %x !\r\n",output.S);
        printf("\r\n    %f !\r\n",output.Rs);
        printf("\r\nURms = %x !\r\n",output.URms);
        printf("\r\n       %f !\r\n",output.Rurms);
        printf("\r\nIRms = %x !\r\n",output.IRms);
        printf("\r\n       %f !\r\n",output.Rirms);
        printf("\r\nPf = %x !\r\n",output.Pf);
        printf("\r\n   %f !\r\n",output.Rpf);
        printf("\r\nFreq = %x !\r\n",output.Freq);
        printf("\r\n       %f !\r\n",output.Rfreq);
        printf("\r\n********************\r\n");
}


main.c
//                           _ooOoo_
//                        o8888888o
//                        88" . "88
//                        (| -_- |)
//                        O\=/O
//                     ____/`---'\____
//                     .'\\|   |//`.
//                  /\\|||:|||//\
//                   /_||||| -:- |||||-\
//                   |   | \\\-/// |   |
//                   | \_|''\---/''|   |
//                   \.-\__`-`___/-. /
//               ___`. .'/--.--\`. . __
//            ."" '<`.___\_<|>_/___.'>'"".
//             | | :`- \`.;`\ _ /`;.`/ - ` : | |
//             \\ `-.   \_ __\ /__ _/   .-` //
//      ======`-.____`-.___\_____/___.-`____.-'======
//                           `=---='
//
//
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                   佛祖保佑       永不死机
//                   心外无法       法外无心

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "Lcd1602.h"
#include "24C02.h"
#include "..\RTC\rtc.h"
#include "ATT7022.h"
#include "string.h"
//ALIENTEK战舰STM32开发板实验4
//串口实验
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司
extern void ATT7022_Init(void);
extern void ATT_Adjust(void);
extern void ATT_Test(void);
extern void Read_ATT_AData(void);
extern void Read_ATT_BData(void);
extern void Read_ATT_CData(void);

char disp0={0};
char disp1={0};
char disp2={0};
char disp3={0};

char ABC_Phase_val='C';
uint8_t test={'0','I','V','U','4','5','6'};
uint8_t test2={0};

void C_Phase_Cal(void)                //C相校表程序
{
        u8 tmp = 0,tmp1=0;                                       //临时变量
        float tmp2=0.0;                       //临时变量,作为校表时控制当前位数用

        Lcd_Puts(0,0,"C phase Adjust");
        delay_ms(1000);
//进入校表显示界面,先输入电表常数
        Lcd_Puts(0,1,"Enter Meter EC");
        memset(disp0,'0',25);
        sprintf(disp0,"%d",Meter_Ec);
        Lcd_Puts(0,2,"                   ");
        tmp1=0;
        tmp=3;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电表常数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec+(1*pow(10,tmp));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec-(1*pow(10,tmp));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp--;
                        tmp1++;
                        if(tmp1>3)
                        {
                                tmp1=0;                //防止设置参数溢出千位
                                tmp=3;
                        }
                }
                if((Meter_Ec>9999)||(Meter_Ec<1))                 //防止常数设置错误,恢复默认值3200
                {
                        Meter_Ec=3200;
                        tmp=3;
                        tmp1=0;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,disp0);
                }
                sprintf(disp0,"%04d",Meter_Ec);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入电流放大倍数设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter I Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseC.I_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电流放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseC.I_Amp_Factor>=0)
                                PhaseC.I_Amp_Factor=PhaseC.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseC.I_Amp_Factor=PhaseC.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseC.I_Amp_Factor>=0)
                                PhaseC.I_Amp_Factor=PhaseC.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseC.I_Amp_Factor=PhaseC.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseC.I_Amp_Factor>9999.9)||(PhaseC.I_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电流最大放大999倍
                {
                        PhaseC.I_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseC.I_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入设置电压放大倍数界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter V Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseC.V_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电压放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseC.V_Amp_Factor>=0)
                                PhaseC.V_Amp_Factor=PhaseC.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseC.V_Amp_Factor=PhaseC.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseC.V_Amp_Factor>=0)
                                PhaseC.V_Amp_Factor=PhaseC.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递减 key3按下递减
                        else
                                PhaseC.V_Amp_Factor=PhaseC.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseC.V_Amp_Factor>9999.0)||(PhaseC.V_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电压最大放大9999.9倍
                {
                        PhaseC.V_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseC.V_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入功率增益补偿设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter PgC");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseC.P_Gain_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出功率增益设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseC.P_Gain_compensation>=0)
                                PhaseC.P_Gain_compensation=PhaseC.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseC.P_Gain_compensation=PhaseC.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseC.P_Gain_compensation>=0)
                                PhaseC.P_Gain_compensation=PhaseC.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseC.P_Gain_compensation=PhaseC.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseC.P_Gain_compensation>+9.9)||(PhaseC.P_Gain_compensation<-9.9))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseC.P_Gain_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseC.P_Gain_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//相位校正界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter PhA");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseC.Ph_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出相位设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseC.Ph_compensation>=0)
                                PhaseC.Ph_compensation=PhaseC.Ph_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseC.Ph_compensation=PhaseC.Ph_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseC.Ph_compensation>=0)
                                PhaseC.Ph_compensation=PhaseC.Ph_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseC.Ph_compensation=PhaseC.Ph_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseC.Ph_compensation>+2.0)||(PhaseC.Ph_compensation<-2.0))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseC.Ph_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseC.Ph_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
}

void A_Phase_Cal(void)                //A相校表程序
{
        u8 tmp = 0,tmp1=0;                                       //临时变量
        float tmp2=0.0;                       //临时变量,作为校表时控制当前位数用

        Lcd_Puts(0,0,"A phase Adjust");
        delay_ms(1000);
//进入校表显示界面,先输入电表常数
        Lcd_Puts(0,1,"Enter Meter EC");
        memset(disp0,'0',25);
        sprintf(disp0,"%d",Meter_Ec);
        Lcd_Puts(0,2,"                   ");
        tmp1=0;
        tmp=3;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电表常数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec+(1*pow(10,tmp));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec-(1*pow(10,tmp));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp--;
                        tmp1++;
                        if(tmp1>3)
                        {
                                tmp1=0;                //防止设置参数溢出千位
                                tmp=3;
                        }
                }
                if((Meter_Ec>9999)||(Meter_Ec<1))                 //防止常数设置错误,恢复默认值3200
                {
                        Meter_Ec=3200;
                        tmp=3;
                        tmp1=0;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,disp0);
                }
                sprintf(disp0,"%04d",Meter_Ec);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入电流放大倍数设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter I Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseA.I_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电流放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseA.I_Amp_Factor>=0)
                                PhaseA.I_Amp_Factor=PhaseA.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseA.I_Amp_Factor=PhaseA.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseA.I_Amp_Factor>=0)
                                PhaseA.I_Amp_Factor=PhaseA.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseA.I_Amp_Factor=PhaseA.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseA.I_Amp_Factor>9999.9)||(PhaseA.I_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电流最大放大999倍
                {
                        PhaseA.I_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseA.I_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入设置电压放大倍数界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter V Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseA.V_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电压放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseA.V_Amp_Factor>=0)
                                PhaseA.V_Amp_Factor=PhaseA.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseA.V_Amp_Factor=PhaseA.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseA.V_Amp_Factor>=0)
                                PhaseA.V_Amp_Factor=PhaseA.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递减 key3按下递减
                        else
                                PhaseA.V_Amp_Factor=PhaseA.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseA.V_Amp_Factor>9999.0)||(PhaseA.V_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电压最大放大9999.9倍
                {
                        PhaseA.V_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseA.V_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入A相功率增益补偿设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter Pga");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseA.P_Gain_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出功率增益设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseA.P_Gain_compensation>=0)
                                PhaseA.P_Gain_compensation=PhaseA.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseA.P_Gain_compensation=PhaseA.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseA.P_Gain_compensation>=0)
                                PhaseA.P_Gain_compensation=PhaseA.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseA.P_Gain_compensation=PhaseA.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseA.P_Gain_compensation>+9.9)||(PhaseA.P_Gain_compensation<-9.9))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseA.P_Gain_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseA.P_Gain_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//A相相位校正界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter Pha");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseA.Ph_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出相位设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseA.Ph_compensation>=0)
                                PhaseA.Ph_compensation=PhaseA.Ph_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseA.Ph_compensation=PhaseA.Ph_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseA.Ph_compensation>=0)
                                PhaseA.Ph_compensation=PhaseA.Ph_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseA.Ph_compensation=PhaseA.Ph_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseA.Ph_compensation>+2.0)||(PhaseA.Ph_compensation<-2.0))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseA.Ph_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseA.Ph_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
}


void B_Phase_Cal(void)                //B相校表程序
{
        u8 tmp = 0,tmp1=0;                                       //临时变量
        float tmp2=0.0;                       //临时变量,作为校表时控制当前位数用

        Lcd_Puts(0,0,"B phase Adjust");
        delay_ms(1000);
//进入校表显示界面,先输入电表常数
        Lcd_Puts(0,1,"Enter Meter EC");
        memset(disp0,'0',25);
        sprintf(disp0,"%d",Meter_Ec);
        Lcd_Puts(0,2,"                   ");
        tmp1=0;
        tmp=3;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电表常数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec+(1*pow(10,tmp));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        Meter_Ec=Meter_Ec-(1*pow(10,tmp));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp--;
                        tmp1++;
                        if(tmp1>3)
                        {
                                tmp1=0;                //防止设置参数溢出千位
                                tmp=3;
                        }
                }
                if((Meter_Ec>9999)||(Meter_Ec<1))                 //防止常数设置错误,恢复默认值3200
                {
                        Meter_Ec=3200;
                        tmp=3;
                        tmp1=0;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,disp0);
                }
                sprintf(disp0,"%04d",Meter_Ec);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入电流放大倍数设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter I Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseB.I_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电流放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseB.I_Amp_Factor>=0)
                                PhaseB.I_Amp_Factor=PhaseB.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseB.I_Amp_Factor=PhaseB.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseB.I_Amp_Factor>=0)
                                PhaseB.I_Amp_Factor=PhaseB.I_Amp_Factor-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseB.I_Amp_Factor=PhaseB.I_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseB.I_Amp_Factor>9999.9)||(PhaseB.I_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电流最大放大999倍
                {
                        PhaseB.I_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseB.I_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入设置电压放大倍数界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"Enter V Amp Factor");
        memset(disp0,0x00,25);
        sprintf(disp0,"%+07.1f",PhaseB.V_Amp_Factor);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=3.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出电压放大倍数设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseB.V_Amp_Factor>=0)
                                PhaseB.V_Amp_Factor=PhaseB.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseB.V_Amp_Factor=PhaseB.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseB.V_Amp_Factor>=0)
                                PhaseB.V_Amp_Factor=PhaseB.V_Amp_Factor-(1*pow(10,tmp2));                //设置值递减 key3按下递减
                        else
                                PhaseB.V_Amp_Factor=PhaseB.V_Amp_Factor+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==5)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>6)
                        {
                                tmp1=1;                //防止设置参数溢出千位
                                tmp2=3.0;
                        }
                }
                if((PhaseB.V_Amp_Factor>9999.0)||(PhaseB.V_Amp_Factor<-9999.9))                 //防止常数设置错误,恢复默认值1,电压最大放大9999.9倍
                {
                        PhaseB.V_Amp_Factor=1.0;
                        tmp2=3.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+07.1f",PhaseB.V_Amp_Factor);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//进入B相功率增益补偿设置界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter Pga");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseB.P_Gain_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出功率增益设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseB.P_Gain_compensation>=0)
                                PhaseB.P_Gain_compensation=PhaseB.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseB.P_Gain_compensation=PhaseB.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseB.P_Gain_compensation>=0)
                                PhaseB.P_Gain_compensation=PhaseB.P_Gain_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseB.P_Gain_compensation=PhaseB.P_Gain_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseB.P_Gain_compensation>+9.9)||(PhaseB.P_Gain_compensation<-9.9))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseB.P_Gain_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseB.P_Gain_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
//B相相位校正界面
        while(PAin(3)==0);
        Lcd_Puts(0,1,"                   ");
        Lcd_Puts(0,1,"Enter Pha");
        memset(disp0,'0',25);
        sprintf(disp0,"%+04.2f",PhaseB.Ph_compensation);
        Lcd_Puts(0,2,"                   ");
        tmp1=1;
        tmp2=0.0;
        Lcd_FlickerChar(tmp1,2);
        while(PAin(3)!=0)                //key4按下表示退出相位设置界面
        {
                if(PAin(0)==0)
                {
                        delay_ms(300);
                        if(PhaseB.Ph_compensation>=0)
                                PhaseB.Ph_compensation=PhaseB.Ph_compensation+(1*pow(10,tmp2));                //设置值递增 key1按下递增
                        else
                                PhaseB.Ph_compensation=PhaseB.Ph_compensation-(1*pow(10,tmp2));                //设置值递增 key1按下递增
                }
                if(PAin(2)==0)
                {
                        delay_ms(300);
                        if(PhaseB.Ph_compensation>=0)
                                PhaseB.Ph_compensation=PhaseB.Ph_compensation-(1*pow(10,tmp2));                //设置值递减
                        else
                                PhaseB.Ph_compensation=PhaseB.Ph_compensation+(1*pow(10,tmp2));                //设置值递减
                }
                if(PAin(1)==0)                //个十百千位调整和显示光标调整 key2按下递减
                {
                        delay_ms(300);
                        tmp2--;
                        tmp1++;
                        if(tmp1==2)
                                tmp1++;                //如果光标在小数位,移位到下一位
                        if(tmp1>4)
                        {
                                tmp1=1;                //防止设置参数溢出
                                tmp2=0.0;
                        }
                }
                if((PhaseB.Ph_compensation>+2.0)||(PhaseB.Ph_compensation<-2.0))                 //防止常数设置错误,恢复默认值0.0
                {
                        PhaseB.Ph_compensation=0.0;
                        tmp2=0.0;
                        tmp1=1;
                        memset(disp0,0x00,25);
                        Lcd_Puts(0,2,"                   ");
                }
                sprintf(disp0,"%+04.2f",PhaseB.Ph_compensation);
                Lcd_Puts(0,2,disp0);
                Lcd_FlickerChar(tmp1,2);
                delay_ms(300);
        }
}

int main(void)
{
//        u8 t;
//         u8 len;
        delay_init();                 //延时函数初始化
        NVIC_Configuration();        //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(9600);       //串口初始化为9600
//         RTC_Init();                                  //RTC初始化
        KEY_Init();          //初始化与按键连接的硬件接口
        Lcd_Init();/*LCD初始化*/
        I2C_Configuration();    //初始化at24c256的scl、sda管脚


        Lcd_Clr();

I2C_PageWrite(test,8,2,ADDR_24LC02);                //EEPROM存储功能测试
        I2C_ReadByte(test2,8,2,ADDR_24LC02);
        /* 初始化ATT7022 */
        printf("\r\nInitializing ATT7022E...\r\n");
        ATT7022_Init();
        printf("\r\nFinish!\r\n");

        printf("\r\nAdjusting ATT7022E...\r\n");
        ATT_Adjust();
        printf("\r\nFinish!\r\n");

//         ATT_Test();


       while(1)
        {
                Read_ATT_AData();
                Read_ATT_BData();
                Read_ATT_CData();
                switch (ABC_Phase_val)        //根据key1设置显示某一相参数
                {
                        case 'A':
                                Lcd_Clr();
                                sprintf(disp0,"A phase:");
                                Lcd_Puts(7,0,disp0);
                                Output_ATT(ADataTypeDef);
                                delay_ms(300);
                                break;
                        case 'B':
                                Lcd_Clr();
                                sprintf(disp0,"B phase:");
                                Lcd_Puts(7,0,disp0);
                                Output_ATT(BDataTypeDef);
                                delay_ms(300);
                                break;
                        case 'C':
                                Lcd_Clr();
                                sprintf(disp0,"C phase:");
                                Lcd_Puts(7,0,disp0);
                                Output_ATT(CDataTypeDef);
                                delay_ms(300);
                                break;
                        default:
                                break;
                }
                if(PAin(0)==0)                                //切换相参数显示
                {
                        ABC_Phase_val++;
                }
                if(ABC_Phase_val>'C')        //确保显示变量在ABC三相之间
                        ABC_Phase_val='A';
//进入设置校表参数界面
                if(PAin(3)==0)                                //key4按下,表示执行输入校表参数
                {
                        while(PAin(3)==0);
                        Lcd_Clr();
                        Lcd_Puts(0,0,"7022E Adjust");
                        delay_ms(1000);
                        A_Phase_Cal();                //设置A相校表参数
                        B_Phase_Cal();                //设置B相校表参数
                        C_Phase_Cal();                //设置C相校表参数
                }

                Lcd_CloseFlicker();
        }
}

embeddev_1 发表于 2014-8-25 16:54:55

yijingkun 发表于 2014-8-25 16:43
项目正在做,没法全部代码都公开,就把main、7022.c、7022.H放上来吧,事先说明,不是我原创的,核心的7022 ...

   楼主有对应的原理图吗? 老夫刚做完cs5463, 单相测的马马虎虎!来学习学习3相的~{:biggrin:}

yijingkun 发表于 2014-8-25 17:07:39

抱歉,项目还没完呢,不方便太公开了

Z_Jian 发表于 2014-11-17 10:03:57

楼主大神,能指导一下吗?我现在也要做这个项目,刚毕业出来不久,什么都不会啊就直接叫我做这个项目,没人带苦逼啊!看了7022的用户手册也不知如何下手,先谢谢啊!{:cry:}

yijingkun 发表于 2014-11-17 10:50:45

Z_Jian 发表于 2014-11-17 10:03
楼主大神,能指导一下吗?我现在也要做这个项目,刚毕业出来不久,什么都不会啊就直接叫我做这个项目,没人 ...

有什么问题吗,具体点

Z_Jian 发表于 2014-11-17 13:28:44

yijingkun 发表于 2014-11-17 10:50
有什么问题吗,具体点

就是看了用户手册不知如何去编程,仪器规格要求有各项指标什么精度、范围、量程等,看得晕晕的,不知如何根据手册去转化为项目的那些要求,我是完全菜鸟一个,刚出来又没人指导!{:sad:}

yijingkun 发表于 2014-11-17 15:31:31

Z_Jian 发表于 2014-11-17 13:28
就是看了用户手册不知如何去编程,仪器规格要求有各项指标什么精度、范围、量程等,看得晕晕的,不知如何 ...

那你还是先了解背景知识吧,网上搜搜,这不是一两句话说得清楚的

Z_Jian 发表于 2014-11-17 15:48:03

yijingkun 发表于 2014-11-17 15:31
那你还是先了解背景知识吧,网上搜搜,这不是一两句话说得清楚的

您好,那能加你q请教请教吗?{:smile:}

yijingkun 发表于 2014-11-17 15:52:52

抱歉,工作比较忙。有个7022的QQ群,是代理建的,你可以在里面提问。

Z_Jian 发表于 2014-11-17 20:23:18

yijingkun 发表于 2014-11-17 15:52
抱歉,工作比较忙。有个7022的QQ群,是代理建的,你可以在里面提问。

好的,谢谢!

Z_Jian 发表于 2014-11-18 23:41:00

yijingkun 发表于 2014-11-17 15:52
抱歉,工作比较忙。有个7022的QQ群,是代理建的,你可以在里面提问。

楼主您好,请教你一下程序问题,在7022.h中,结构体中    float Rp;   float Rq; float Rs;float Rurms;   float Rirms; float Rpf;float Rfreq;这几个变量是什么意思呢?
7022.c中各相常用数据读取函数如void Read_ATT_AData(void)中if(ADataTypeDef.P>0x800000){

208.                ADataTypeDef.Rp=0x1000000-ADataTypeDef.P;

209.                ADataTypeDef.Rp=-((ADataTypeDef.Rp*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\

210.                -((ADataTypeDef.Rp*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation));    //   2^15/2^23

211.      }

212.      else

213.                ADataTypeDef.Rp=(ADataTypeDef.P*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\

214.                -((ADataTypeDef.P*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation);

215.      if(ADataTypeDef.Q>0x800000){

216.                ADataTypeDef.Rq=0x1000000-ADataTypeDef.Q;

217.                ADataTypeDef.Rq=-((ADataTypeDef.Rq*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\

218.                -((ADataTypeDef.Rq*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation));

219.      }

220.      else

221.                ADataTypeDef.Rq=(ADataTypeDef.Q*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))\

222.                -((ADataTypeDef.Q*Meter_K*fabs(PhaseA.I_Amp_Factor)*fabs(PhaseA.V_Amp_Factor))*PhaseA.P_Gain_compensation);

223.      ADataTypeDef.Rs=ADataTypeDef.S/256.0;

224.      ADataTypeDef.Rurms=ADataTypeDef.URms/8192.0*PhaseA.V_Amp_Factor;   //   2^10/2^23

225.      ADataTypeDef.Rirms=ADataTypeDef.IRms/8192.0*PhaseA.I_Amp_Factor;

226.      if(ADataTypeDef.Pf>0x800000){

227.                ADataTypeDef.Rpf=0x1000000-ADataTypeDef.Pf;

228.                ADataTypeDef.Rpf=-((ADataTypeDef.Rpf/8388608.0)-((ADataTypeDef.Rpf/8388608.0)*PhaseA.Ph_compensation));

229.      }

230.      else

231.                ADataTypeDef.Rpf=(ADataTypeDef.Pf/8388608.0)-((ADataTypeDef.Pf/8388608.0)*PhaseA.Ph_compensation);

232.      ADataTypeDef.Rfreq=ADataTypeDef.Freq/8192.0;

233.

234.//         Lcd_Clr();

235.//         sprintf(disp0,"A phase:");

236.//         Lcd_Puts(7,0,disp0);

237.//      Output_ATT(ADataTypeDef);
这些什么得来的呢?是根据什么哪里运算的呢?麻烦指导一下,谢谢!!

yijingkun 发表于 2014-11-19 14:59:36

本帖最后由 yijingkun 于 2014-11-19 15:12 编辑

Z_Jian 发表于 2014-11-18 23:41
楼主您好,请教你一下程序问题,在7022.h中,结构体中    float Rp;   float Rq; float Rs;float Rur ...

RP、RQ是有功和无功,RS是视在功率,其它的你需要仔细看7022的文档,到钜泉的官网去下载吧。

另外也可以到pudn这个网站找找7022的代码

Z_Jian 发表于 2014-11-19 15:23:50

yijingkun 发表于 2014-11-19 14:59
RP、RQ是有功和无功,RS是视在功率,其它的你需要仔细看7022的文档,到钜泉的官网去下载吧。

另外也可以 ...

那么P、Q、S又是什么变量呢?还有那个u32 URms;float Rurms;和u32 IRms;float Rirms;为什么有两个呢?是电压电流有效值和真有效值?
void Read_ATT_AData(void)函数是根据手册里来的吗?我看的是ATT7022E,不知跟ATT7022是不是差不多的,两者的计算方法一样吗?

yijingkun 发表于 2014-11-19 17:17:14

Z_Jian 发表于 2014-11-19 15:23
那么P、Q、S又是什么变量呢?还有那个u32 URms;float Rurms;和u32 IRms;float Rirms;为什么有两个呢 ...

建议你仔细看7022E的手册,至于程序上的问题,你先通读三遍7022e的手册,带着问题去看之后,应该会明白的

Z_Jian 发表于 2014-11-19 17:37:39

yijingkun 发表于 2014-11-19 17:17
建议你仔细看7022E的手册,至于程序上的问题,你先通读三遍7022e的手册,带着问题去看之后,应该会明白的 ...

好的,其实我都读至少有3遍手册啦,不过只要是那份手册上就能解决的那就行了,谢谢啦!

Z_Jian 发表于 2014-11-21 16:05:02

yijingkun 发表于 2014-7-10 15:49
先谢谢你的答复,我就是这段看不明白:

如果X>2^23,则XX=X-2^24


楼主大神你好,关于X,XX,和xxx这里我也不懂,请问是什么意思呢?为什么跟程序中不一样的?{:smile:}

liangshanguang 发表于 2018-1-9 18:14:41

binghe167 发表于 2014-7-10 15:30
#define Meter_Ib        5.0                        //基本电流
#define Meter_Im        50.0                //最大电流
#define Meter_CT        5000.0                //互感 ...

大咖能加qq吗,我现在正在做att7022e的毕业设计

justdomyself 发表于 2018-6-30 11:04:02

我的读出三相电流ID都有读数 ,其他的都是0什么鬼

justdomyself 发表于 2018-6-30 15:59:34

binghe167 发表于 2014-7-10 15:28
ATT7022E/26E/28E功率寄存器采用补码形式给出,最高位是符号位,所以根据ATT7022E/26E/28E
功率寄存器给出 ...

这个芯片的文档看起来真费劲

首先要算x,算x需要k

计算需要k

算 k需要 HF和EC

HF从哪来的

EC是什么鬼, 应该是多少

lonny_chen 发表于 2024-9-19 10:26:30

binghe167 发表于 2014-7-10 15:30
#define Meter_Ib        5.0                        //基本电流
#define Meter_Im        50.0                //最大电流
#define Meter_CT        5000.0                //互感 ...
(引用自14楼)

受益匪浅
页: [1]
查看完整版本: ATT7022E只接B相,电压电流读取正确,有功读取不正确,求助