- /*
- * ade7758.c
- *
- * Created on: 2014-9-12
- * Author: lzy
- */
- #include
- #include "debug.h"
- #include "ade7758.h"
- #include "SpiDev.h"
-
- unsigned char bWorkModel=0;//工作模式标志位 1:校准模式;0:正常工作模式;
- unsigned char bit_1s=0; //1s钟标志,在时钟中断函数中置位
-
- static unsigned char divider = 1;//电能分频器,默认值为零,视在功率超出一定值时,自动将该值提高
- static unsigned int energy[9];//用于累加电能值 36
-
- struct all_data working;//正常工作模式下存放的电参量 95
- struct adjust_data adjusting;//校准模式下存放的数据 65
-
- static unsigned int vo_buffer[5][3];//用于电压的积分虑波 36
- static unsigned int io_buffer[5][3];//用于电流的积分虑波 36
-
- static unsigned char b_adjust = 0;//ADE7758已经校准标志
- static unsigned char sample_cycle = 0; //电压采样周期,5次取平均
- static unsigned char ADE_AdjustDataBuf[2+sizeof(struct adjust_dataw)]={0}; /*校准数据暂存缓冲区*/
-
- void ADE_Check7758(void);
-
- /**
- * 功能:延时函数 50us
- */
- void ADE_udelay(void)
- {
- // usleep(50);
- }
-
- /**
- * 功能:片选使能
- */
- void ADE_CS(unsigned char cs)
- {
- // CSADE7758_A = cs; //=====
- }
-
-
- /**
- * 功能:通过SPI写入数据至芯片
- * 入口参数:
- * buf -> 数据缓冲区
- * len -> 数据长度
- */
- void ADE_SPIWrite(unsigned char *buf, unsigned char len)
- {
- SPI_Write(buf,len);
- }
-
-
- /**
- * 功能:通过SPI读芯片数据
- * 入口参数:len -> 数据长度
- * 出口参数: buf -> 数据缓冲区
- *
- */
- void ADE_SPIRead(unsigned char *buf, unsigned char len)
- {
- SPI_Read(buf,len);
- }
-
-
- /**
- * 功能:7758写数据函数
- * 入口参数:
- * type:目标寄存器的地址
- * wdata:写进寄存器的内容
- * databit:目标寄存器的宽度
- * 出口参数:NULL
- * 返回值:NULL
- */
- void ADE_Write(unsigned char type,unsigned int wdata,unsigned char databit)
- {
- unsigned char data[3];
-
- ADE_CS(0);
-
- type = type | 0x80;
-
- data[0] = type;
- ADE_SPIWrite(data, 1);
- ADE_udelay();
-
- if(databit == 8)
- {
- data[0] = wdata;
- ADE_SPIWrite(data, 1);
- }
- else if(databit == 16)
- {
- data[0] = (wdata&0xff00) >> 8; /*高8位*/
- data[1] = (wdata&0x00ff); /*底8位*/
- ADE_SPIWrite(data, 2);
- }
- else
- pr_err("ADE write databit Error:%d
", databit);
- ADE_CS(1);
- }
-
- /**
- * 功能:7758读寄存器函数
- * 入口参数:
- * type:目标寄存器的地址
- * databit:目标寄存器的宽度
- * 出口参数:指定寄存器的内容
- * 返回值:指定寄存器的内容
- */
- unsigned int ADE_Read(unsigned char type,unsigned char databit)
- {
- unsigned char data[4]={0,0,0,0};
- unsigned int rtdata = 0;
-
- ADE_CS(0);
- type = type & 0x7F;
-
- data[0] = type;
- ADE_SPIWrite(data, 1);
- ADE_udelay();
-
- if(databit == 8)
- {
- ADE_SPIRead(data,1);
- rtdata = data[0];
- }
- else if(databit == 12)
- {
- ADE_SPIRead(data,2);
- rtdata = (data[0]&0x0f) <
- rtdata += data[1];
- }
- else if(databit == 16)
- {
- ADE_SPIRead(data,2);
- rtdata = data[0] <
- rtdata += data[1];
- }else if(databit == 24)
- {
- ADE_SPIRead(data,3);
- rtdata = data[0] <
- rtdata += (data[1] <
- rtdata += data[2];
- }
- else
- pr_err("ADE Read databit Error:%d
", databit);
- ADE_CS(1);
-
- return(rtdata);
- }
-
- /**
- * 功能:检测异常
- */
- void ADE_AuCheck(void)
- {
- unsigned char i;
- unsigned int temp_data[5];//存放运算过程的中间变量
- unsigned int temp_v,temp_i;
-
- //自动检测ADE7758是否出现异常
- if( working.voltage[ 0 ] > ERR_VOLTAGE ||
- working.voltage[ 1 ] > ERR_VOLTAGE ||
- working.voltage[ 2 ] > ERR_VOLTAGE )
- {
- ADE_Check7758();
- }
-
- //自动设置分频器的大小
- for( i = 0; i
- {
- temp_v = working.voltage[ i ];
- temp_i = working.current[ i ];
- temp_data[i] = ( ( temp_v * temp_i ) / DIVI_VALUE ) & 0x000000ff;
- }
-
- temp_data[3] = ( temp_data[0] > temp_data[1] )?
- ( ( temp_data[0] > temp_data[2] )? temp_data[0] : temp_data[2] ) :
- ( ( temp_data[1] > temp_data[2] )? temp_data[1] : temp_data[2] ) ;
-
- if( divider != (char)temp_data[3] )
- {
- //write to ade7758
- divider = (char)temp_data[3] + 1;
-
- for(i = 0; i
- ADE_Write( ADD_WDIV + i, ( (int) divider <
- }
- }
-
-
- /**
- * 功能:每秒读取功率
- */
- void ADE_ReadHR(void)
- {
- unsigned char i;
- unsigned int temp_data[9];//存放运算过程的中间变量
-
- //有功
- temp_data[ADD_AWATTHR - 1 ] = ADE_Read(ADD_AWATTHR,16);
- temp_data[ADD_BWATTHR - 1 ] = ADE_Read(ADD_BWATTHR,16);
- temp_data[ADD_CWATTHR - 1 ] = ADE_Read(ADD_CWATTHR,16);
- //无功
- temp_data[ADD_AVARHR - 1 ] = ADE_Read(ADD_AVARHR,16);
- temp_data[ADD_BVARHR - 1 ] = ADE_Read(ADD_BVARHR,16);
- temp_data[ADD_CVARHR - 1 ] = ADE_Read(ADD_CVARHR,16);
- //视在
- temp_data[ADD_AVAHR - 1 ] = ADE_Read(ADD_AVAHR,16);
- temp_data[ADD_BVAHR - 1 ] = ADE_Read(ADD_BVAHR,16);
- temp_data[ADD_CVAHR - 1 ] = ADE_Read(ADD_CVAHR,16);
-
- for( i = 0; i
- {
- if( temp_data[ i ] > 0x7fff )
- temp_data[ i ] = 0xffff - temp_data[ i ] + 1;
- }
-
- if( divider > 1)
- {
- for( i = 0; i
- temp_data[ i ] = temp_data[ i ] * divider;//乘上分频器的值
- }
-
- //能量的计算
- for( i = 0; i
- energy[i] += temp_data[i];//累加电能值,单位为 WS(瓦秒)
-
- //转换成千瓦时
- for( i = 0; i
- {
- working.watt_hour[i] += (energy[i] / 3600000);//转换成千瓦时
- energy[i] = energy[i] % 3600000;
- }
-
- working.watt_hour[3] = working.watt_hour[0] + working.watt_hour[1] + working.watt_hour[2];//总和
-
- //转换成千伏安时
- for( i = 0; i
- {
- working.va_hour[i] += (energy[ i+6 ] / 3600000);//转换成千瓦时
- energy[ i+6 ] = energy[i+6] % 3600000;
- }
-
- working.va_hour[3] = working.va_hour[0] + working.va_hour[1] + working.va_hour[2];//总和
-
- for( working.watt[ 3 ] = 0, i = 0; i
- {
- working.watt[ i ] = temp_data[ i ]/1000;//千瓦
- working.watt[ 3 ] += working.watt[ i ];
- }
-
- for( working.var[ 3 ] = 0, i = 0; i
- {
- working.var[ i ] = temp_data[ i +3 ]/1000;
- working.var[ 3 ] += working.var[ i ];
- }
-
- for( working.va[ 3 ] = 0, i = 0; i
- {
- working.va[ i ] = temp_data[ i + 6 ] /1000;//千伏安
-
- if(working.va[ i ]
- working.va[ i ] = working.watt[ i ];
-
- working.va[ 3 ] += working.va[ i ];
- }
-
-
- }
-
- /**
- * 功能:实时读取电流电压值
- */
- void ADE_ReadVC(void)
- {
- unsigned char i, j;
-
- for( i = 0; i
- {
- working.voltage[ i ] = 0;
- working.current[ i ] = 0;
- }
-
- for( i = 0; i
- {
- for( j = 0; j
- {
- working.voltage[ i ] += vo_buffer[j][i];
- working.current[ i ] += io_buffer[j][i];
- }
- }
-
- for( i = 0; i
- {
- working.voltage[ i ] = working.voltage[ i ]/5;
- working.current[ i ] = working.current[ i ]/5;
- }
-
- //电压电流的三相平均值
- working.voltage[ 3 ] = (working.voltage[ 0 ] + working.voltage[ 1 ] + working.voltage[ 2 ] ) / 3;
- working.current[ 3 ] = ( working.current[ 0 ] + working.current[ 1 ] + working.current[ 2 ] ) / 3;
-
- printf(" voltage=%d current=%d
",working.voltage[ 3 ], working.current[ 3 ]);
- }
-
- /**
- * 校准模式下 每秒读取功率
- */
- void ADE_AdjustHR(void)
- {
- unsigned char i;
- unsigned int temp_data[9];//存放运算过程的中间变量
-
- //有功
- temp_data[ADD_AWATTHR - 1 ] = ADE_Read(ADD_AWATTHR,16);
- temp_data[ADD_BWATTHR - 1 ] = ADE_Read(ADD_BWATTHR,16);
- temp_data[ADD_CWATTHR - 1 ] = ADE_Read(ADD_CWATTHR,16);
- //无功
- temp_data[ADD_AVARHR - 1 ] = ADE_Read(ADD_AVARHR,16);
- temp_data[ADD_BVARHR - 1 ] = ADE_Read(ADD_BVARHR,16);
- temp_data[ADD_CVARHR - 1 ] = ADE_Read(ADD_CVARHR,16);
- //视在
- temp_data[ADD_AVAHR - 1 ] = ADE_Read(ADD_AVAHR,16);
- temp_data[ADD_BVAHR - 1 ] = ADE_Read(ADD_BVAHR,16);
- temp_data[ADD_CVAHR - 1 ] = ADE_Read(ADD_CVAHR,16);
-
- for( i = 0 ; i
- {
- adjusting.read_data.watt[i] = temp_data[ i + 0 ] & 0x0000ffff;
- adjusting.read_data.var[i] = temp_data[ i + 3 ] & 0x0000ffff;//没有校准有功功率
- adjusting.read_data.va[i] = temp_data[ i + 6 ] & 0x0000ffff;
- }
- }
-
-
- /**
- * 校准模式下实时读取电流电压值
- */
- void ADE_AdjustVC(void)
- {
- unsigned char i, j;
-
- for( i = 0; i
- {
- adjusting.read_data.voltage[i] = 0;
- adjusting.read_data.current[i] = 0;
- }
-
- for( i = 0; i
- {
- for( j = 0; j
- {
- adjusting.read_data.voltage[i] += vo_buffer[j][i];
- adjusting.read_data.current[i] += io_buffer[j][i];
- }
- }
-
- for( i = 0; i
- {
- adjusting.read_data.voltage[i] = adjusting.read_data.voltage[i]/5;
- adjusting.read_data.current[i] = adjusting.read_data.current[i]/5;
- }
- }
-
-
- /**
- * 功能:从ADE7758中取出三相电压电流功率等电参量
- */
- void ADE_GetData(void)
- {
- static unsigned char bit_3s=0;
- unsigned char j;
-
- if( !bWorkModel ) //正常工作模式
- {
- if( bit_1s )
- {
- bit_1s = 0;
- ADE_ReadHR();
-
- if( (bit_3s++) >= 3 ) /*三秒检测一次异常*/
- {
- ADE_AuCheck();
- bit_3s=0;
- }
- }
-
- for( j = 0; j
- {
- vo_buffer[ sample_cycle ][j] = ADE_Read( ADD_AVRMS + j, 24 ) >> 12;//voltage
- io_buffer[ sample_cycle ][j] = ADE_Read( ADD_AIRMS + j, 24 ) >> 13;//current
- }
-
- if( sample_cycle == 4) /*读取5次取平均值*/
- ADE_ReadVC();
- }
- else
- {
- if( bit_1s )
- {
- bit_1s = 0;
- ADE_AdjustHR();
- }
-
- for( j = 0; j
- {
- vo_buffer[sample_cycle][j] = ADE_Read( ADD_AVRMS + j, 24 );
- io_buffer[sample_cycle][j] = ADE_Read( ADD_AIRMS + j, 24 );
- }
-
- if( sample_cycle == 4)
- ADE_AdjustVC();
-
-
- // save_set_to_e2prom(); //===
- }
-
- if( sample_cycle
- sample_cycle += 1;
- else
- sample_cycle = 0;
- }
-
-
- /**
- * 校准数据保存至缓冲区
- */
- void ADE_WriteByte(unsigned short data, unsigned short addr)
- {
- memcpy(ADE_AdjustDataBuf+addr, &data, sizeof(unsigned short));
- }
-
-
- /**
- * 读取校准数据缓冲区中数据
- */
- unsigned short ADE_ReadByte(unsigned short addr)
- {
- unsigned short data;
-
- memcpy(&data, ADE_AdjustDataBuf+addr, sizeof(unsigned short));
-
- return data;
- }
-
-
-
- /**
- * 功能:保存校准数据
- */
- void ADE_AdjustSaveData(void)
- {
- unsigned char i;
- unsigned short temp_data;
- unsigned short temp_add = 0;
-
- ADE_WriteByte( SAVE_OK, ADE_SET_ADDR ); //写入标志
- temp_add +=2;
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.voltage[i];
- ADE_WriteByte(temp_data , ADE_SET_ADDR + temp_add );
- temp_add += 2;
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.current[i];
- ADE_WriteByte(temp_data , ADE_SET_ADDR + temp_add );
- temp_add += 2;
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.watt[i];
- ADE_WriteByte(temp_data , ADE_SET_ADDR + temp_add );
- temp_add += 2;
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.var[i];
- ADE_WriteByte(temp_data , ADE_SET_ADDR + temp_add );
- temp_add += 2;
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.va[i];
- ADE_WriteByte(temp_data , ADE_SET_ADDR + temp_add );
- temp_add += 2;
- }
-
- }
-
-
- /**
- * 功能: 将缓冲区中的校准参数写入ADE7758
- * 当确定校准参数的值后,便调用该函数,写数据写入ADE7758特定的寄存器中
- */
- void ADE_AdjustWriteValue(void)
- {
- unsigned char i;
- unsigned short temp_data;
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.voltage[i];
- if( temp_data
- ADE_Write( ADD_AVRMSGAIN + i, temp_data , 16 );
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.current[i];
- if( temp_data
- ADE_Write( ADD_AIGAIN + i, temp_data , 16 );
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.watt[i];
- if( temp_data
- ADE_Write( ADD_AWG + i, temp_data , 16 );
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.var[i];
- if( temp_data
- ADE_Write( ADD_AVARG + i, temp_data , 16 );
- }
-
- for(i = 0; i
- {
- temp_data = adjusting.write_data.va[i];
- if( temp_data
- ADE_Write( ADD_AVAG + i, temp_data , 16 );
- }
-
- }
-
-
-
- /**
- * 功能:读出已保存的校准参数
- */
- void ADE_AdjustReadData(void)
- {
- unsigned char i;
- unsigned short temp_data;
- unsigned short temp_add = 0;
-
- if( ADE_ReadByte(ADE_SET_ADDR) == SAVE_OK)
- {
- b_adjust = 1;//ADE7758已经校准标志
- temp_add += 2;
-
- for( i = 0; i
- {
- temp_data = ADE_ReadByte( ADE_SET_ADDR + temp_add );
- adjusting.write_data.voltage[i]= temp_data;
- temp_add += 2;
- }
-
- for( i = 0; i
- {
- temp_data = ADE_ReadByte( ADE_SET_ADDR + temp_add );
- adjusting.write_data.current[i]= temp_data;
- temp_add += 2;
- }
- for( i = 0; i
- {
- temp_data = ADE_ReadByte( ADE_SET_ADDR + temp_add );
- adjusting.write_data.watt[i]= temp_data;
- temp_add += 2;
- }
-
- for( i = 0; i
- {
- temp_data = ADE_ReadByte( ADE_SET_ADDR + temp_add );
- adjusting.write_data.var[i]= temp_data;
- temp_add += 2;
- }
-
- for( i = 0; i
- {
- temp_data = ADE_ReadByte( ADE_SET_ADDR + temp_add );
- adjusting.write_data.va[i]= temp_data;
- temp_add += 2;
- }
-
- ADE_AdjustWriteValue();
- }
-
- }
-
-
- /**
- * 功能:检测7758是否异常,有则修复
- */
- void ADE_Check7758(void)
- {
- unsigned short temp,temp1;
-
- if( !b_adjust )//ADE7758已经校准标志
- return;
-
- temp = ADE_ReadByte( ADE_SET_ADDR + 2 );
- temp1 = ADE_Read( ADD_AVRMSGAIN ,12 ) & 0x0fff;
-
- if( temp != temp1 )//检测A相校准参数是否正确
- ADE_AdjustReadData();
- }
-
-
- /**
- * 功能:将标志写入中断寄存器中,允许能量寄存器容量超出一半时产生中断
- */
- void ADE_WriteMask(void)
- {
- unsigned char data[3];
- unsigned char type;
- unsigned int wdata = 0x00000700;//AEHF=1,VAEHF=1,低8位无用
-
- ADE_CS(0);
-
- type = ADD_MASK & 0x7F;
- type = type | 0x80;
-
- data[0] = type;
- ADE_SPIWrite(data, 1);
-
- ADE_udelay();
-
- data[0] = (wdata >> 16)&0xFF;
- data[1] = (wdata >> 8)&0xFF;
- data[2] = wdata&0xFF;
- ADE_SPIWrite(data, 3);
-
- ADE_CS(1);
- }
-
-
- /**
- * 功能:清除校准数据
- */
- void ADE_Clean(void)
- {
- unsigned char i;
-
- for( i = 0; i
- adjusting.write_data.voltage[i] = 0;
-
- for( i = 0; i
- adjusting.write_data.current[i] = 0;
-
- for( i = 0; i
- adjusting.write_data.watt[i] = 0;
-
- for( i = 0; i
- adjusting.write_data.var[i] = 0;
-
- for( i = 0; i
- adjusting.write_data.va[i] = 0;
-
- ADE_AdjustWriteValue();
-
- memset(ADE_AdjustDataBuf,0,sizeof(ADE_AdjustDataBuf)); /*校验数据缓冲区清0*/
-
- }
-
-
- /**
- * 功能:7758初始化函数
- */
- void ADE_Init(void)
- {
- unsigned char TempData, i;
-
- ADE_WriteMask();//write interrupt mask to ade7758
-
- TempData = (0xff & ADE_Read(ADD_COMPMODE,8) ) | 0x80;
- ADE_Write(ADD_COMPMODE,((int)TempData<<8),8);//seting activate the no-load threshold
-
- if( bWorkModel )
- {
- ADE_Clean();
- for(i = 0; i
- ADE_Write( ADD_WDIV + i, 0X00 , 8 );
- }
- else //正常工作模式
- ADE_AdjustReadData();
- }
-
-
- int main(void)
- {
- int ret = 0;
- ret = SPI_Open();
- if(ret)
- return ret;
-
- ADE_AdjustSaveData();
-
- ADE_Init();
-
- while(1)
- {
- sleep(1);
- bit_1s = 1;
- ADE_GetData();
- }
-
- SPI_Close();
- return 0;
- }
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』