ADE7758驅(qū)動程序
- /*
- *ade7758.c
- *
- *Createdon:2014-9-12
- *Author:lzy
- */
- #include
- #include"debug.h"
- #include"ade7758.h"
- #include"SpiDev.h"
- unsigned char bWorkModel=0;//工作模式標(biāo)志位 1:校準(zhǔn)模式;0:正常工作模式;
- unsigned char bit_1s=0;//1s鐘標(biāo)志,在時鐘中斷函數(shù)中置位
- static unsigned char divider=1;//電能分頻器,默認(rèn)值為零,視在功率超出一定值時,自動將該值提高
- static unsignedintenergy[9];//用于累加電能值 36
- struct all_data working;//正常工作模式下存放的電參量 95
- struct adjust_data adjusting;//校準(zhǔn)模式下存放的數(shù)據(jù) 65
- static unsignedintvo_buffer[5][3];//用于電壓的積分慮波 36
- static unsignedintio_buffer[5][3];//用于電流的積分慮波 36
- static unsigned char b_adjust=0;//ADE7758已經(jīng)校準(zhǔn)標(biāo)志
- static unsigned char sample_cycle=0;//電壓采樣周期,5次取平均
- static unsigned char ADE_AdjustDataBuf[2+sizeof(struct adjust_dataw)]={0};/*校準(zhǔn)數(shù)據(jù)暫存緩沖區(qū)*/
- void ADE_Check7758(void);
- /**
- *功能:延時函數(shù) 50us
- */
- void ADE_udelay(void)
- {
- //usleep(50);
- }
- /**
- *功能:片選使能
- */
- void ADE_CS(unsigned char cs)
- {
- //CSADE7758_A=cs;//=====
- }
- /**
- *功能:通過SPI寫入數(shù)據(jù)至芯片
- *入口參數(shù):
- *buf->數(shù)據(jù)緩沖區(qū)
- *len->數(shù)據(jù)長度
- */
- void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
- {
- SPI_Write(buf,len);
- }
- /**
- *功能:通過SPI讀芯片數(shù)據(jù)
- *入口參數(shù):len->數(shù)據(jù)長度
- *出口參數(shù):buf->數(shù)據(jù)緩沖區(qū)
- *
- */
- void ADE_SPIRead(unsigned char*buf,unsigned charlen)
- {
- SPI_Read(buf,len);
- }
- /**
- *功能:7758寫數(shù)據(jù)函數(shù)
- *入口參數(shù):
- *type:目標(biāo)寄存器的地址
- *wdata:寫進(jìn)寄存器的內(nèi)容
- *databit:目標(biāo)寄存器的寬度
- *出口參數(shù):NULL
- *返回值:NULL
- */
- void ADE_Write(unsigned char type,unsignedintwdata,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);
- }
- elseif(databit==16)
- {
- data[0]=(wdata&0xff00)>>8;/*高8位*/
- data[1]=(wdata&0x00ff);/*底8位*/
- ADE_SPIWrite(data,2);
- }
- else
- pr_err("ADE write databit Error:%dn",databit);
- ADE_CS(1);
- }
- /**
- *功能:7758讀寄存器函數(shù)
- *入口參數(shù):
- * type:目標(biāo)寄存器的地址
- *databit:目標(biāo)寄存器的寬度
- *出口參數(shù):指定寄存器的內(nèi)容
- *返回值:指定寄存器的內(nèi)容
- */
- unsignedintADE_Read(unsigned char type,unsigned char databit)
- {
- unsigned char data[4]={0,0,0,0};
- unsignedintrtdata=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];
- }
- elseif(databit==12)
- {
- ADE_SPIRead(data,2);
- rtdata=(data[0]&0x0f)<<8;
- rtdata+=data[1];
- }
- elseif(databit==16)
- {
- ADE_SPIRead(data,2);
- rtdata=data[0]<<8;
- rtdata+=data[1];
- }elseif(databit==24)
- {
- ADE_SPIRead(data,3);
- rtdata=data[0]<<16;
- rtdata+=(data[1]<<8);
- rtdata+=data[2];
- }
- else
- pr_err("ADE Read databit Error:%dn",databit);
- ADE_CS(1);
- return(rtdata);
- }
- /**
- *功能:檢測異常
- */
- void ADE_AuCheck(void)
- {
- unsigned char i;
- unsignedinttemp_data[5];//存放運算過程的中間變量
- unsignedinttemp_v,temp_i;
- //自動檢測ADE7758是否出現(xiàn)異常
- if(working.voltage[0]>ERR_VOLTAGE||
- working.voltage[1]>ERR_VOLTAGE||
- working.voltage[2]>ERR_VOLTAGE)
- {
- ADE_Check7758();
- }
- //自動設(shè)置分頻器的大小
- for(i=0;i<3;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])
- {
- //writetoade7758
- divider=(char)temp_data[3]+1;
- for(i=0;i<3;i++)
- ADE_Write(ADD_WDIV+i,((int)divider<<8),8);
- }
- }
- /**
- *功能:每秒讀取功率
- */
- void ADE_ReadHR(void)
- {
- unsigned char i;
- unsignedinttemp_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<9;i++)
- {
- if(temp_data[i]>0x7fff)
- temp_data[i]=0xffff-temp_data[i]+1;
- }
- if(divider>1)
- {
- for(i=0;i<9;i++)
- temp_data[i]=temp_data[i]*divider;//乘上分頻器的值
- }
- //能量的計算
- for(i=0;i<9;i++)
- energy[i]+=temp_data[i];//累加電能值,單位為 WS(瓦秒)
- //轉(zhuǎn)換成千瓦時
- for(i=0;i<3;i++)
- {
- working.watt_hour[i]+=(energy[i]/3600000);//轉(zhuǎn)換成千瓦時
- energy[i]=energy[i]%3600000;
- }
- working.watt_hour[3]=working.watt_hour[0]+working.watt_hour[1]+working.watt_hour[2];//總和
- //轉(zhuǎn)換成千伏安時
- for(i=0;i<3;i++)
- {
- working.va_hour[i]+=(energy[i+6]/3600000);//轉(zhuǎn)換成千瓦時
- 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<3;i++)
- {
- working.watt[i]=temp_data[i]/1000;//千瓦
- working.watt[3]+=working.watt[i];
- }
- for(working.var[3]=0,i=0;i<3;i++)
- {
- working.var[i]=temp_data[i+3]/1000;
- working.var[3]+=working.var[i];
- }
- for(working.va[3]=0,i=0;i<3;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<3;i++)
- {
- working.voltage[i]=0;
- working.current[i]=0;
- }
- for(i=0;i<3;i++)
- {
- for(j=0;j<5;j++)
- {
- working.voltage[i]+=vo_buffer[j][i];
- working.current[i]+=io_buffer[j][i];
- }
- }
- for(i=0;i<3;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=%dn",working.voltage[3],working.current[3]);
- }
- /**
- *校準(zhǔn)模式下 每秒讀取功率
- */
- void ADE_AdjustHR(void)
- {
- unsigned char i;
- unsignedinttemp_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<3;i++)
- {
- adjusting.read_data.watt[i]=temp_data[i+0]&0x0000ffff;
- adjusting.read_data.var[i]=temp_data[i+3]&0x0000ffff;//沒有校準(zhǔn)有功功率
- adjusting.read_data.va[i]=temp_data[i+6]&0x0000ffff;
- }
- }
- /**
- *校準(zhǔn)模式下實時讀取電流電壓值
- */
- void ADE_AdjustVC(void)
- {
- unsigned char i,j;
- for(i=0;i<3;i++)
- {
- adjusting.read_data.voltage[i]=0;
- adjusting.read_data.current[i]=0;
- }
- for(i=0;i<3;i++)
- {
- for(j=0;j<5;j++)
- {
- adjusting.read_data.voltage[i]+=vo_buffer[j][i];
- adjusting.read_data.current[i]+=io_buffer[j][i];
- }
- }
- for(i=0;i<3;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<3;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<3;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<4)
- sample_cycle+=1;
- else
- sample_cycle=0;
- }
- /**
- *校準(zhǔn)數(shù)據(jù)保存至緩沖區(qū)
- */
- void ADE_WriteByte(unsigned short data,unsigned short addr)
- {
- memcpy(ADE_AdjustDataBuf+addr,&data,sizeof(unsigned short));
- }
- /**
- *讀取校準(zhǔn)數(shù)據(jù)緩沖區(qū)中數(shù)據(jù)
- */
- unsigned short ADE_ReadByte(unsigned short addr)
- {
- unsigned short data;
- memcpy(&data,ADE_AdjustDataBuf+addr,sizeof(unsigned short));
- return data;
- }
- /**
- *功能:保存校準(zhǔn)數(shù)據(jù)
- */
- void ADE_AdjustSaveData(void)
- {
- unsigned char i;
- unsigned short temp_data;
- unsigned short temp_add=0;
- ADE_WriteByte(SAVE_OK,ADE_SET_ADDR);//寫入標(biāo)志
- temp_add+=2;
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.voltage[i];
- ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.current[i];
- ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.watt[i];
- ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.var[i];
- ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.va[i];
- ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
- temp_add+=2;
- }
- }
- /**
- *功能: 將緩沖區(qū)中的校準(zhǔn)參數(shù)寫入ADE7758
- *當(dāng)確定校準(zhǔn)參數(shù)的值后,便調(diào)用該函數(shù),寫數(shù)據(jù)寫入ADE7758特定的寄存器中
- */
- void ADE_AdjustWriteValue(void)
- {
- unsigned char i;
- unsigned short temp_data;
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.voltage[i];
- if(temp_data<0x1000)//4096
- ADE_Write(ADD_AVRMSGAIN+i,temp_data,16);
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.current[i];
- if(temp_data<0x1000)//4096
- ADE_Write(ADD_AIGAIN+i,temp_data,16);
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.watt[i];
- if(temp_data<0x1000)//4096
- ADE_Write(ADD_AWG+i,temp_data,16);
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.var[i];
- if(temp_data<0x1000)//4096
- ADE_Write(ADD_AVARG+i,temp_data,16);
- }
- for(i=0;i<3;i++)
- {
- temp_data=adjusting.write_data.va[i];
- if(temp_data<0x1000)//4096
- ADE_Write(ADD_AVAG+i,temp_data,16);
- }
- }
- /**
- *功能:讀出已保存的校準(zhǔn)參數(shù)
- */
- 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已經(jīng)校準(zhǔn)標(biāo)志
- temp_add+=2;
- for(i=0;i<3;i++)
- {
- temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
- adjusting.write_data.voltage[i]=temp_data;
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
- adjusting.write_data.current[i]=temp_data;
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
- adjusting.write_data.watt[i]=temp_data;
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
- adjusting.write_data.var[i]=temp_data;
- temp_add+=2;
- }
- for(i=0;i<3;i++)
- {
- temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
- adjusting.write_data.va[i]=temp_data;
- temp_add+=2;
- }
- ADE_AdjustWriteValue();
- }
- }
- /**
- *功能:檢測7758是否異常,有則修復(fù)
- */
- void ADE_Check7758(void)
- {
- unsigned short temp,temp1;
- if(!b_adjust)//ADE7758已經(jīng)校準(zhǔn)標(biāo)志
- return;
- temp=ADE_ReadByte(ADE_SET_ADDR+2);
- temp1=ADE_Read(ADD_AVRMSGAIN,12)&0x0fff;
- if(temp!=temp1)//檢測A相校準(zhǔn)參數(shù)是否正確
- ADE_AdjustReadData();
- }
- /**
- *功能:將標(biāo)志寫入中斷寄存器中,允許能量寄存器容量超出一半時產(chǎn)生中斷
- */
- void ADE_WriteMask(void)
- {
- unsigned char data[3];
- unsigned char type;
- unsignedintwdata=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);
- }
- /**
- *功能:清除校準(zhǔn)數(shù)據(jù)
- */
- void ADE_Clean(void)
- {
- unsigned char i;
- for(i=0;i<3;i++)
- adjusting.write_data.voltage[i]=0;
- for(i=0;i<3;i++)
- adjusting.write_data.current[i]=0;
- for(i=0;i<3;i++)
- adjusting.write_data.watt[i]=0;
- for(i=0;i<3;i++)
- adjusting.write_data.var[i]=0;
- for(i=0;i<3;i++)
- adjusting.write_data.va[i]=0;
- ADE_AdjustWriteValue();
- memset(ADE_AdjustDataBuf,0,sizeof(ADE_AdjustDataBuf));/*校驗數(shù)據(jù)緩沖區(qū)清0*/
- }
- /**
- *功能:7758初始化函數(shù)
- */
- void ADE_Init(void)
- {
- unsigned char TempData,i;
- ADE_WriteMask();//write interrupt masktoade7758
- 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<3;i++)
- ADE_Write(ADD_WDIV+i,0X00,8);
- }
- else//正常工作模式
- ADE_AdjustReadData();
- }
- intmain(void)
- {
- intret=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;
- }
評論