⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_7026a_data_spi.c

📁 这是电能芯片ATT7026的读写函数
💻 C
字号:
#include <18F452.h>
#include <read_7026a_data_spi.h>
UDWORD spi_read_parameter(UCHAR addr)                   //读电能芯片1个参数//
{
	UDWORD tempdata=0;
	UCHAR i;
	output_high(PIN_E2);		//CS置高
	;
	;
	output_low(PIN_E2);			//CS置低
   	;
    spi_write(addr);
	do
	{
		;
	}while(!spi_data_is_in());
	i=spi_read();
    delay_us(4);
		
	tempdata+=((UDWORD)spi_read(0)<<16);
		
	tempdata+=((UDWORD)spi_read(0)<<8);
		
	tempdata+=(UDWORD)spi_read(0);  
	output_high(PIN_E2);		//CS置高
    return tempdata;
}


void spi_write_parameter(UCHAR addr,UDWORD data)        //写一个参数到电能芯片中//
{
    signed 	char 	i=0;
    UCHAR   j=0;
    UDWORD tempdata=0;
	output_high(PIN_E2);		//CS置高
	;
	;
	output_low(PIN_E2);			//CS置低
	;
    spi_write(addr+0x80);
	while(!spi_data_is_in())
	{
		;
	}
	j=spi_read();
    for(i=2;i>=0;i--)
    {
		tempdata=data;
		if(i==2)	
		{tempdata=tempdata>>16;}
		else if(i==1)
		{tempdata=tempdata>>8;}
		j=(UCHAR)tempdata;
		spi_write(j);
		do
		{
			;
		}while(!spi_data_is_in());
		j=spi_read();
	}
	output_high(PIN_E2);
}




void ReadPwr(void)
{
    UCHAR i;
	float	iii;
    for(i=0; i<4; i++) 
	{
		AMPara.ActPwr[i]=spi_read_parameter(i+0x01);//读有功功率
		if(i!=3)
		{
			if(AMPara.ActPwr[i]<=_23_bit)
				iii=(float)AMPara.ActPwr[i]*_15_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.ActPwr[i])*_15_bit/_23_bit;
			MP.AMReal.ActP[i]=iii;
		}
		else
		{
			if(AMPara.ActPwr[i]<=_23_bit)
				iii=(float)AMPara.ActPwr[i]*_17_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.ActPwr[i])*_17_bit/_23_bit;
			MP.AMReal.ActP[i]=iii;
		}

	}	
    for(i=0; i<4; i++) 
	{	
		AMPara.ReaPwr[i]=spi_read_parameter(i+0x05);//读无功功率
		if(i!=3)
		{
			if(AMPara.ReaPwr[i]<=_23_bit)
				iii=(float)AMPara.ReaPwr[i]*_15_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.ReaPwr[i])*_15_bit/_23_bit;
			MP.AMReal.ReaP[i]=iii;
		}
		else
		{
			if(AMPara.ReaPwr[i]<=_23_bit)
				iii=(float)AMPara.ReaPwr[i]*_17_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.ReaPwr[i])*_17_bit/_23_bit;
			MP.AMReal.ReaP[i]=iii;
		}
	}


    for(i=0; i<4; i++) 
	{	
		AMPara.AppPwr[i]=spi_read_parameter(i+0x09);//读视在功率
		if(i!=3)
		{
			if(AMPara.AppPwr[i]<=_23_bit)
				iii=(float)AMPara.AppPwr[i]*_15_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.AppPwr[i])*_15_bit/_23_bit;
			MP.AMReal.AppP[i]=iii;
		}
		else
		{
			if(AMPara.AppPwr[i]<=_23_bit)
				iii=(float)AMPara.AppPwr[i]*_17_bit/_23_bit;
			else
				iii=(float)(_24_bit-AMPara.AppPwr[i])*_17_bit/_23_bit;
			MP.AMReal.AppP[i]=iii;
		}
	}
}

void ReadU( UCHAR ch )                      //读电压
{
    float iii;

    AMPara.UU[ch]=spi_read_parameter(ch+0x0D);

    if(AMPara.UU[ch]<=_23_bit)
        iii=(((float)AMPara.UU[ch]*_10_bit)/_23_bit)*KU;
    else
    	iii=((float)(_24_bit-AMPara.UU[ch])*_10_bit)/_23_bit*KU;
	MP.AMReal.U[ch]=iii;
}

void ReadI( UCHAR ch )                  //读电流
{
    float iii;

    AMPara.II[ch]=spi_read_parameter(ch+0x10);

    if(AMPara.II[ch]<=_23_bit)
        {	iii=(float)AMPara.II[ch]*_10_bit/_23_bit*KI;}
    else
        {	iii=(float)(_24_bit-AMPara.II[ch])*_10_bit/_23_bit*KI;}
	MP.AMReal.I[CH]=iii;
}

void ReadFct( UCHAR ch )                //读功率因数
{
    float iii;

    AMPara.Fct[ch]=spi_read_parameter(ch+0x14);

    if(AMPara.Fct[ch]<=_23_bit)
        iii=((float)AMPara.Fct[ch]/_23_bit)*1.000;
    else
        iii=((float)(_24_bit-AMPara.Fct[ch]))/_23_bit*1.000;

	MP.AMReal.Factor[ch]=iii;
}


void ReadPhs( UCHAR ch )                //读相位
{
    float iii;

    AMPara.Phs[ch]=spi_read_parameter(ch+0x18);

    if(AMPara.Phs[ch]<=_23_bit)
        iii=(float)AMPara.Phs[ch]/_23_bit*2*180/Pi*1.0;
    else
        iii=(float)(_24_bit-AMPara.Phs[ch])/_23_bit*2*180/Pi*1.0;
	MP.AMReal.Phs[ch]=iii;
}


void ReadFreq(void)                 //读频率
{
    float iii;

    AMPara.Freq=spi_read_parameter(0x1C);

    iii=(float)AMPara.Freq*_10_bit/_23_bit;
	MP.AMReal.Frequency=iii;

}


void ReadActE(void)                 //读有功能量//
{
    UCHAR i;
    for(i=0;i<4;i++)
    {	AMPara.ActE[i]=spi_read_parameter(i+0x1E);
		MP.AMReal.ActEnergy[i]=(float)AMPara.ActE[i]/3200.0;		//单位是KWh,既度
	}
}


void ReadReaE(void)                 //读无功能量//
{
    UCHAR i;
    for(i=0;i<4;i++)
    {	AMPara.ReactE[i]=spi_read_parameter(i+0x22);
		MP.AMReal.ReactEnergy[i]=(float)AMPara.ReactE[i]/3200.0;
	}
}


void ReadStatus(void)
{

    AMPara.SpiStatus1=spi_read_parameter(0x2C);
}


void ReadReal(void)
{
    ReadPwr();              //读有功,无功和视在功率//

    ReadU(PhsA);            //读A相电压//
    ReadU(PhsB);            //读B相电压//
    ReadU(PhsC);            //读C相电压//

    ReadI(PhsA);            //读A相电流//
    ReadI(PhsB);            //读B相电流//
    ReadI(PhsC);            //读C相电流//
	ReadI(PhsAll);			//读三相电量失量和的有效值

    ReadFct(PhsA);          //读A相功率因数//
    ReadFct(PhsB);          //读B相功率因数//
    ReadFct(PhsC);          //读C相功率因数//
    ReadFct(PhsAll);        //读合相功率因数//

	ReadPhs(PhsA);			//读A相相位
	ReadPhs(PhsB);			//读A相相位
	ReadPhs(PhsC);			//读A相相位
	ReadPhs(PhsAll);		//读A相相位

    ReadFreq();             //读频率//
    ReadActE();             //读有功电能//
    ReadReaE();             //读无功电能//
	ReadStatus();			//读状态寄存器//

}


//*********************************************************//

//较表程序//
//相位补偿区域设置,分两段
void	adjIregion(void)
{
//	spi_write_parameter(0x05,0x00013E81);	//相位补偿区域设置4  Is=15%Vi=0.015v,Iregion4=INT(G*Is*2^23)=0x013E81
	spi_write_parameter(0x05,0x00000000);
}


//功率增益校正
void 	adjPgain(void)			
{
	float err,temp;
	UDWORD Pgain=0;
	
	err=(PowMeasA-PowRealA)/PowRealA;
	temp=-err/(1+err);
	if(temp>=0)
		{Pgain=(UDWORD)(temp*_23_bit);}
	else
		{Pgain=(UDWORD)((float)_24_bit+temp*_23_bit);}
	spi_write_parameter(0x06,Pgain);	//A相功率0校正
	spi_write_parameter(0x09,Pgain);	//A相功率0校正



	err=(PowMeasB-PowRealB)/PowRealB;
	temp=-err/(1+err);
	if(temp>=0)
		{Pgain=(UDWORD)(temp*_23_bit);}
	else
		{Pgain=(UDWORD)((float)_24_bit+temp*_23_bit);}
	spi_write_parameter(0x07,Pgain);	//A相功率0校正
	spi_write_parameter(0x0A,Pgain);	//A相功率0校正



	err=(PowMeasC-PowRealC)/PowRealC;
	temp=-err/(1+err);
	if(temp>=0)
		{Pgain=(UDWORD)(temp*_23_bit);}
	else
		{Pgain=(UDWORD)((float)_24_bit+temp*_23_bit);}
	spi_write_parameter(0x08,Pgain);	//A相功率0校正
	spi_write_parameter(0x0B,Pgain);	//A相功率0校正

}


//角差校正
void adjPhs(void)
{
	signed char i;
	float err,angle;
	UDWORD Phsreg=0;

//A相相位校正,不分段
	err=(PhsMeasA-PhsRealA)/PhsRealA;
	angle=acos((1+err)*0.5)-Pi/3;
	if(angle>=0)
		Phsreg=(UDWORD)(angle*_23_bit);
	else
		Phsreg=(UDWORD)((float)_24_bit+angle*_23_bit);
	for(i=0x0c;i<=0x10;i++)
	spi_write_parameter(i,Phsreg);

//B相相位校正,不分段	
	err=(PhsMeasB-PhsRealB)/PhsRealB;
	angle=acos((1+err)*0.5)-Pi/3;
	if(angle>=0)
		Phsreg=(UDWORD)(angle*_23_bit);
	else
		Phsreg=(UDWORD)((float)_24_bit+angle*_23_bit);
	for(i=0x11;i<=0x15;i++)
	spi_write_parameter(i,Phsreg);

//C相相位校正,不分段
	err=(PhsMeasC-PhsRealC)/PhsRealC;
	angle=acos((1+err)*0.5)-Pi/3;
	if(angle>=0)
		Phsreg=(UDWORD)(angle*_23_bit);
	else
		Phsreg=(UDWORD)((float)_24_bit+angle*_23_bit);
	for(i=0x16;i<=0x1A;i++)
	spi_write_parameter(i,Phsreg);
}




//调整测量电压
void adjU(void)
{
	float	tempu;
	UDWORD	Ugain=0;
	tempu=UrA/UrmsA-1;
	if(tempu<0)
		Ugain=(UDWORD)((float)_24_bit+tempu*_23_bit);
	else
		Ugain=(UDWORD)(tempu*_23_bit);	
	spi_write_parameter(0x1B,Ugain);	//A相电压校正


	tempu=UrB/UrmsB-1;
	if(tempu<0)
		Ugain=(UDWORD)((float)_24_bit+tempu*_23_bit);
	else
		Ugain=(UDWORD)(tempu*_23_bit);
	spi_write_parameter(0x1C,Ugain);	//B相电压校正


	tempu=UrC/UrmsC-1;
	if(tempu<0)
		Ugain=(UDWORD)((float)_24_bit+tempu*_23_bit);
	else
		Ugain=(UDWORD)(tempu*_23_bit);
	spi_write_parameter(0x1D,Ugain);	//C相电压校正
}	

//调整测量电流
void adjI(void)
{
	float	tempI;
	UDWORD	Igain=0;
	tempI=IrA/IrmsA-1;
	if(tempI<0)
		Igain=(UDWORD)((float)_24_bit+tempI*_23_bit);
	else
		Igain=(UDWORD)(tempI*_23_bit);
	spi_write_parameter(0x26,Igain);	//A相电流校正


	tempI=IrB/IrmsB-1;
	if(tempI<0)
		Igain=(UDWORD)((float)_24_bit+tempI*_23_bit);
	else
		Igain=(UDWORD)(tempI*_23_bit);	
	spi_write_parameter(0x27,Igain);	//B相电流校正


	tempI=IrC/IrmsC-1;
	if(tempI<0)
		Igain=(UDWORD)((float)_24_bit+tempI*_23_bit);
	else
		Igain=(UDWORD)(tempI*_23_bit);
	spi_write_parameter(0x28,Igain);	//C相电流校正
}


void	readAdjMeter(void)
{
	UCHAR	i;
	UDWORD	tempdata;
	output_high(PIN_E2);		//CS置高
	;
	;
	output_low(PIN_E2);			//CS置低
	spi_write(0xC6);
	do
	{
		;
	}while(!spi_data_is_in());
	i=spi_read();

	spi_write(0x00);
	do
	{
		;
	}while(!spi_data_is_in());
	i=spi_read();

	spi_write(0x00);
	do
	{
		;
	}while(!spi_data_is_in());
	i=spi_read();

	spi_write(0x5B);
	do
	{
		;
	}while(!spi_data_is_in());
	i=spi_read();
	output_high(PIN_E2);		//CS置高
	delay_us(100);
	tempdata=spi_read_parameter(0x00);
	i+=i;
}

void checkmeter(void)
{

//	adjIregion();
//	adjPgain();
//	adjPhs();
//	adjU();
//	adjI();
	readAdjMeter();
}




void main()
{
	setup_spi(spi_master|spi_l_to_h);
	delay_ms(300);
//	checkmeter();
		
	do	
	{	
	delay_ms(700);	
		ReadReal();

	}while(1);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -