新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ADE7758驅動程序

        ADE7758驅動程序

        作者: 時間:2016-11-11 來源:網絡 收藏
        1. /*
        2. *ade7758.c
        3. *
        4. *Createdon:2014-9-12
        5. *Author:lzy
        6. */
        7. #include
        8. #include"debug.h"
        9. #include"ade7758.h"
        10. #include"SpiDev.h"
        11. unsigned char bWorkModel=0;//工作模式標志位 1:校準模式;0:正常工作模式;
        12. unsigned char bit_1s=0;//1s鐘標志,在時鐘中斷函數中置位
        13. static unsigned char divider=1;//電能分頻器,默認值為零,視在功率超出一定值時,自動將該值提高
        14. static unsignedintenergy[9];//用于累加電能值 36
        15. struct all_data working;//正常工作模式下存放的電參量 95
        16. struct adjust_data adjusting;//校準模式下存放的數據 65
        17. static unsignedintvo_buffer[5][3];//用于電壓的積分慮波 36
        18. static unsignedintio_buffer[5][3];//用于電流的積分慮波 36
        19. static unsigned char b_adjust=0;//ADE7758已經校準標志
        20. static unsigned char sample_cycle=0;//電壓采樣周期,5次取平均
        21. static unsigned char ADE_AdjustDataBuf[2+sizeof(struct adjust_dataw)]={0};/*校準數據暫存緩沖區*/
        22. void ADE_Check7758(void);
        23. /**
        24. *功能:延時函數 50us
        25. */
        26. void ADE_udelay(void)
        27. {
        28. //usleep(50);
        29. }
        30. /**
        31. *功能:片選使能
        32. */
        33. void ADE_CS(unsigned char cs)
        34. {
        35. //CSADE7758_A=cs;//=====
        36. }
        37. /**
        38. *功能:通過SPI寫入數據至芯片
        39. *入口參數:
        40. *buf->數據緩沖區
        41. *len->數據長度
        42. */
        43. void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
        44. {
        45. SPI_Write(buf,len);
        46. }
        47. /**
        48. *功能:通過SPI讀芯片數據
        49. *入口參數:len->數據長度
        50. *出口參數:buf->數據緩沖區
        51. *
        52. */
        53. void ADE_SPIRead(unsigned char*buf,unsigned charlen)
        54. {
        55. SPI_Read(buf,len);
        56. }
        57. /**
        58. *功能:7758寫數據函數
        59. *入口參數:
        60. *type:目標寄存器的地址
        61. *wdata:寫進寄存器的內容
        62. *databit:目標寄存器的寬度
        63. *出口參數:NULL
        64. *返回值:NULL
        65. */
        66. void ADE_Write(unsigned char type,unsignedintwdata,unsigned char databit)
        67. {
        68. unsigned char data[3];
        69. ADE_CS(0);
        70. type=type|0x80;
        71. data[0]=type;
        72. ADE_SPIWrite(data,1);
        73. ADE_udelay();
        74. if(databit==8)
        75. {
        76. data[0]=wdata;
        77. ADE_SPIWrite(data,1);
        78. }
        79. elseif(databit==16)
        80. {
        81. data[0]=(wdata&0xff00)>>8;/*高8位*/
        82. data[1]=(wdata&0x00ff);/*底8位*/
        83. ADE_SPIWrite(data,2);
        84. }
        85. else
        86. pr_err("ADE write databit Error:%dn",databit);
        87. ADE_CS(1);
        88. }
        89. /**
        90. *功能:7758讀寄存器函數
        91. *入口參數:
        92. * type:目標寄存器的地址
        93. *databit:目標寄存器的寬度
        94. *出口參數:指定寄存器的內容
        95. *返回值:指定寄存器的內容
        96. */
        97. unsignedintADE_Read(unsigned char type,unsigned char databit)
        98. {
        99. unsigned char data[4]={0,0,0,0};
        100. unsignedintrtdata=0;
        101. ADE_CS(0);
        102. type=type&0x7F;
        103. data[0]=type;
        104. ADE_SPIWrite(data,1);
        105. ADE_udelay();
        106. if(databit==8)
        107. {
        108. ADE_SPIRead(data,1);
        109. rtdata=data[0];
        110. }
        111. elseif(databit==12)
        112. {
        113. ADE_SPIRead(data,2);
        114. rtdata=(data[0]&0x0f)<<8;
        115. rtdata+=data[1];
        116. }
        117. elseif(databit==16)
        118. {
        119. ADE_SPIRead(data,2);
        120. rtdata=data[0]<<8;
        121. rtdata+=data[1];
        122. }elseif(databit==24)
        123. {
        124. ADE_SPIRead(data,3);
        125. rtdata=data[0]<<16;
        126. rtdata+=(data[1]<<8);
        127. rtdata+=data[2];
        128. }
        129. else
        130. pr_err("ADE Read databit Error:%dn",databit);
        131. ADE_CS(1);
        132. return(rtdata);
        133. }
        134. /**
        135. *功能:檢測異常
        136. */
        137. void ADE_AuCheck(void)
        138. {
        139. unsigned char i;
        140. unsignedinttemp_data[5];//存放運算過程的中間變量
        141. unsignedinttemp_v,temp_i;
        142. //自動檢測ADE7758是否出現異常
        143. if(working.voltage[0]>ERR_VOLTAGE||
        144. working.voltage[1]>ERR_VOLTAGE||
        145. working.voltage[2]>ERR_VOLTAGE)
        146. {
        147. ADE_Check7758();
        148. }
        149. //自動設置分頻器的大小
        150. for(i=0;i<3;i++)
        151. {
        152. temp_v=working.voltage[i];
        153. temp_i=working.current[i];
        154. temp_data[i]=((temp_v*temp_i)/DIVI_VALUE)&0x000000ff;
        155. }
        156. temp_data[3]=(temp_data[0]>temp_data[1])?
        157. ((temp_data[0]>temp_data[2])?temp_data[0]:temp_data[2]):
        158. ((temp_data[1]>temp_data[2])?temp_data[1]:temp_data[2]);
        159. if(divider!=(char)temp_data[3])
        160. {
        161. //writetoade7758
        162. divider=(char)temp_data[3]+1;
        163. for(i=0;i<3;i++)
        164. ADE_Write(ADD_WDIV+i,((int)divider<<8),8);
        165. }
        166. }
        167. /**
        168. *功能:每秒讀取功率
        169. */
        170. void ADE_ReadHR(void)
        171. {
        172. unsigned char i;
        173. unsignedinttemp_data[9];//存放運算過程的中間變量
        174. //有功
        175. temp_data[ADD_AWATTHR-1]=ADE_Read(ADD_AWATTHR,16);
        176. temp_data[ADD_BWATTHR-1]=ADE_Read(ADD_BWATTHR,16);
        177. temp_data[ADD_CWATTHR-1]=ADE_Read(ADD_CWATTHR,16);
        178. //無功
        179. temp_data[ADD_AVARHR-1]=ADE_Read(ADD_AVARHR,16);
        180. temp_data[ADD_BVARHR-1]=ADE_Read(ADD_BVARHR,16);
        181. temp_data[ADD_CVARHR-1]=ADE_Read(ADD_CVARHR,16);
        182. //視在
        183. temp_data[ADD_AVAHR-1]=ADE_Read(ADD_AVAHR,16);
        184. temp_data[ADD_BVAHR-1]=ADE_Read(ADD_BVAHR,16);
        185. temp_data[ADD_CVAHR-1]=ADE_Read(ADD_CVAHR,16);
        186. for(i=0;i<9;i++)
        187. {
        188. if(temp_data[i]>0x7fff)
        189. temp_data[i]=0xffff-temp_data[i]+1;
        190. }
        191. if(divider>1)
        192. {
        193. for(i=0;i<9;i++)
        194. temp_data[i]=temp_data[i]*divider;//乘上分頻器的值
        195. }
        196. //能量的計算
        197. for(i=0;i<9;i++)
        198. energy[i]+=temp_data[i];//累加電能值,單位為 WS(瓦秒)
        199. //轉換成千瓦時
        200. for(i=0;i<3;i++)
        201. {
        202. working.watt_hour[i]+=(energy[i]/3600000);//轉換成千瓦時
        203. energy[i]=energy[i]%3600000;
        204. }
        205. working.watt_hour[3]=working.watt_hour[0]+working.watt_hour[1]+working.watt_hour[2];//總和
        206. //轉換成千伏安時
        207. for(i=0;i<3;i++)
        208. {
        209. working.va_hour[i]+=(energy[i+6]/3600000);//轉換成千瓦時
        210. energy[i+6]=energy[i+6]%3600000;
        211. }
        212. working.va_hour[3]=working.va_hour[0]+working.va_hour[1]+working.va_hour[2];//總和
        213. for(working.watt[3]=0,i=0;i<3;i++)
        214. {
        215. working.watt[i]=temp_data[i]/1000;//千瓦
        216. working.watt[3]+=working.watt[i];
        217. }
        218. for(working.var[3]=0,i=0;i<3;i++)
        219. {
        220. working.var[i]=temp_data[i+3]/1000;
        221. working.var[3]+=working.var[i];
        222. }
        223. for(working.va[3]=0,i=0;i<3;i++)
        224. {
        225. working.va[i]=temp_data[i+6]/1000;//千伏安
        226. if(working.va[i]
        227. working.va[i]=working.watt[i];
        228. working.va[3]+=working.va[i];
        229. }
        230. }
        231. /**
        232. *功能:實時讀取電流電壓值
        233. */
        234. void ADE_ReadVC(void)
        235. {
        236. unsigned char i,j;
        237. for(i=0;i<3;i++)
        238. {
        239. working.voltage[i]=0;
        240. working.current[i]=0;
        241. }
        242. for(i=0;i<3;i++)
        243. {
        244. for(j=0;j<5;j++)
        245. {
        246. working.voltage[i]+=vo_buffer[j][i];
        247. working.current[i]+=io_buffer[j][i];
        248. }
        249. }
        250. for(i=0;i<3;i++)
        251. {
        252. working.voltage[i]=working.voltage[i]/5;
        253. working.current[i]=working.current[i]/5;
        254. }
        255. //電壓電流的三相平均值
        256. working.voltage[3]=(working.voltage[0]+working.voltage[1]+working.voltage[2])/3;
        257. working.current[3]=(working.current[0]+working.current[1]+working.current[2])/3;
        258. printf(" voltage=%d current=%dn",working.voltage[3],working.current[3]);
        259. }
        260. /**
        261. *校準模式下 每秒讀取功率
        262. */
        263. void ADE_AdjustHR(void)
        264. {
        265. unsigned char i;
        266. unsignedinttemp_data[9];//存放運算過程的中間變量
        267. //有功
        268. temp_data[ADD_AWATTHR-1]=ADE_Read(ADD_AWATTHR,16);
        269. temp_data[ADD_BWATTHR-1]=ADE_Read(ADD_BWATTHR,16);
        270. temp_data[ADD_CWATTHR-1]=ADE_Read(ADD_CWATTHR,16);
        271. //無功
        272. temp_data[ADD_AVARHR-1]=ADE_Read(ADD_AVARHR,16);
        273. temp_data[ADD_BVARHR-1]=ADE_Read(ADD_BVARHR,16);
        274. temp_data[ADD_CVARHR-1]=ADE_Read(ADD_CVARHR,16);
        275. //視在
        276. temp_data[ADD_AVAHR-1]=ADE_Read(ADD_AVAHR,16);
        277. temp_data[ADD_BVAHR-1]=ADE_Read(ADD_BVAHR,16);
        278. temp_data[ADD_CVAHR-1]=ADE_Read(ADD_CVAHR,16);
        279. for(i=0;i<3;i++)
        280. {
        281. adjusting.read_data.watt[i]=temp_data[i+0]&0x0000ffff;
        282. adjusting.read_data.var[i]=temp_data[i+3]&0x0000ffff;//沒有校準有功功率
        283. adjusting.read_data.va[i]=temp_data[i+6]&0x0000ffff;
        284. }
        285. }
        286. /**
        287. *校準模式下實時讀取電流電壓值
        288. */
        289. void ADE_AdjustVC(void)
        290. {
        291. unsigned char i,j;
        292. for(i=0;i<3;i++)
        293. {
        294. adjusting.read_data.voltage[i]=0;
        295. adjusting.read_data.current[i]=0;
        296. }
        297. for(i=0;i<3;i++)
        298. {
        299. for(j=0;j<5;j++)
        300. {
        301. adjusting.read_data.voltage[i]+=vo_buffer[j][i];
        302. adjusting.read_data.current[i]+=io_buffer[j][i];
        303. }
        304. }
        305. for(i=0;i<3;i++)
        306. {
        307. adjusting.read_data.voltage[i]=adjusting.read_data.voltage[i]/5;
        308. adjusting.read_data.current[i]=adjusting.read_data.current[i]/5;
        309. }
        310. }
        311. /**
        312. *功能:從ADE7758中取出三相電壓電流功率等電參量
        313. */
        314. void ADE_GetData(void)
        315. {
        316. static unsigned char bit_3s=0;
        317. unsigned char j;
        318. if(!bWorkModel)//正常工作模式
        319. {
        320. if(bit_1s)
        321. {
        322. bit_1s=0;
        323. ADE_ReadHR();
        324. if((bit_3s++)>=3)/*三秒檢測一次異常*/
        325. {
        326. ADE_AuCheck();
        327. bit_3s=0;
        328. }
        329. }
        330. for(j=0;j<3;j++)
        331. {
        332. vo_buffer[sample_cycle][j]=ADE_Read(ADD_AVRMS+j,24)>>12;//voltage
        333. io_buffer[sample_cycle][j]=ADE_Read(ADD_AIRMS+j,24)>>13;//current
        334. }
        335. if(sample_cycle==4)/*讀取5次取平均值*/
        336. ADE_ReadVC();
        337. }
        338. else
        339. {
        340. if(bit_1s)
        341. {
        342. bit_1s=0;
        343. ADE_AdjustHR();
        344. }
        345. for(j=0;j<3;j++)
        346. {
        347. vo_buffer[sample_cycle][j]=ADE_Read(ADD_AVRMS+j,24);
        348. io_buffer[sample_cycle][j]=ADE_Read(ADD_AIRMS+j,24);
        349. }
        350. if(sample_cycle==4)
        351. ADE_AdjustVC();
        352. //save_set_to_e2prom();//===
        353. }
        354. if(sample_cycle<4)
        355. sample_cycle+=1;
        356. else
        357. sample_cycle=0;
        358. }
        359. /**
        360. *校準數據保存至緩沖區
        361. */
        362. void ADE_WriteByte(unsigned short data,unsigned short addr)
        363. {
        364. memcpy(ADE_AdjustDataBuf+addr,&data,sizeof(unsigned short));
        365. }
        366. /**
        367. *讀取校準數據緩沖區中數據
        368. */
        369. unsigned short ADE_ReadByte(unsigned short addr)
        370. {
        371. unsigned short data;
        372. memcpy(&data,ADE_AdjustDataBuf+addr,sizeof(unsigned short));
        373. return data;
        374. }
        375. /**
        376. *功能:保存校準數據
        377. */
        378. void ADE_AdjustSaveData(void)
        379. {
        380. unsigned char i;
        381. unsigned short temp_data;
        382. unsigned short temp_add=0;
        383. ADE_WriteByte(SAVE_OK,ADE_SET_ADDR);//寫入標志
        384. temp_add+=2;
        385. for(i=0;i<3;i++)
        386. {
        387. temp_data=adjusting.write_data.voltage[i];
        388. ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
        389. temp_add+=2;
        390. }
        391. for(i=0;i<3;i++)
        392. {
        393. temp_data=adjusting.write_data.current[i];
        394. ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
        395. temp_add+=2;
        396. }
        397. for(i=0;i<3;i++)
        398. {
        399. temp_data=adjusting.write_data.watt[i];
        400. ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
        401. temp_add+=2;
        402. }
        403. for(i=0;i<3;i++)
        404. {
        405. temp_data=adjusting.write_data.var[i];
        406. ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
        407. temp_add+=2;
        408. }
        409. for(i=0;i<3;i++)
        410. {
        411. temp_data=adjusting.write_data.va[i];
        412. ADE_WriteByte(temp_data,ADE_SET_ADDR+temp_add);
        413. temp_add+=2;
        414. }
        415. }
        416. /**
        417. *功能: 將緩沖區中的校準參數寫入ADE7758
        418. *當確定校準參數的值后,便調用該函數,寫數據寫入ADE7758特定的寄存器中
        419. */
        420. void ADE_AdjustWriteValue(void)
        421. {
        422. unsigned char i;
        423. unsigned short temp_data;
        424. for(i=0;i<3;i++)
        425. {
        426. temp_data=adjusting.write_data.voltage[i];
        427. if(temp_data<0x1000)//4096
        428. ADE_Write(ADD_AVRMSGAIN+i,temp_data,16);
        429. }
        430. for(i=0;i<3;i++)
        431. {
        432. temp_data=adjusting.write_data.current[i];
        433. if(temp_data<0x1000)//4096
        434. ADE_Write(ADD_AIGAIN+i,temp_data,16);
        435. }
        436. for(i=0;i<3;i++)
        437. {
        438. temp_data=adjusting.write_data.watt[i];
        439. if(temp_data<0x1000)//4096
        440. ADE_Write(ADD_AWG+i,temp_data,16);
        441. }
        442. for(i=0;i<3;i++)
        443. {
        444. temp_data=adjusting.write_data.var[i];
        445. if(temp_data<0x1000)//4096
        446. ADE_Write(ADD_AVARG+i,temp_data,16);
        447. }
        448. for(i=0;i<3;i++)
        449. {
        450. temp_data=adjusting.write_data.va[i];
        451. if(temp_data<0x1000)//4096
        452. ADE_Write(ADD_AVAG+i,temp_data,16);
        453. }
        454. }
        455. /**
        456. *功能:讀出已保存的校準參數
        457. */
        458. void ADE_AdjustReadData(void)
        459. {
        460. unsigned char i;
        461. unsigned short temp_data;
        462. unsigned short temp_add=0;
        463. if(ADE_ReadByte(ADE_SET_ADDR)==SAVE_OK)
        464. {
        465. b_adjust=1;//ADE7758已經校準標志
        466. temp_add+=2;
        467. for(i=0;i<3;i++)
        468. {
        469. temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
        470. adjusting.write_data.voltage[i]=temp_data;
        471. temp_add+=2;
        472. }
        473. for(i=0;i<3;i++)
        474. {
        475. temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
        476. adjusting.write_data.current[i]=temp_data;
        477. temp_add+=2;
        478. }
        479. for(i=0;i<3;i++)
        480. {
        481. temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
        482. adjusting.write_data.watt[i]=temp_data;
        483. temp_add+=2;
        484. }
        485. for(i=0;i<3;i++)
        486. {
        487. temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
        488. adjusting.write_data.var[i]=temp_data;
        489. temp_add+=2;
        490. }
        491. for(i=0;i<3;i++)
        492. {
        493. temp_data=ADE_ReadByte(ADE_SET_ADDR+temp_add);
        494. adjusting.write_data.va[i]=temp_data;
        495. temp_add+=2;
        496. }
        497. ADE_AdjustWriteValue();
        498. }
        499. }
        500. /**
        501. *功能:檢測7758是否異常,有則修復
        502. */
        503. void ADE_Check7758(void)
        504. {
        505. unsigned short temp,temp1;
        506. if(!b_adjust)//ADE7758已經校準標志
        507. return;
        508. temp=ADE_ReadByte(ADE_SET_ADDR+2);
        509. temp1=ADE_Read(ADD_AVRMSGAIN,12)&0x0fff;
        510. if(temp!=temp1)//檢測A相校準參數是否正確
        511. ADE_AdjustReadData();
        512. }
        513. /**
        514. *功能:將標志寫入中斷寄存器中,允許能量寄存器容量超出一半時產生中斷
        515. */
        516. void ADE_WriteMask(void)
        517. {
        518. unsigned char data[3];
        519. unsigned char type;
        520. unsignedintwdata=0x00000700;//AEHF=1,VAEHF=1,低8位無用
        521. ADE_CS(0);
        522. type=ADD_MASK&0x7F;
        523. type=type|0x80;
        524. data[0]=type;
        525. ADE_SPIWrite(data,1);
        526. ADE_udelay();
        527. data[0]=(wdata>>16)&0xFF;
        528. data[1]=(wdata>>8)&0xFF;
        529. data[2]=wdata&0xFF;
        530. ADE_SPIWrite(data,3);
        531. ADE_CS(1);
        532. }
        533. /**
        534. *功能:清除校準數據
        535. */
        536. void ADE_Clean(void)
        537. {
        538. unsigned char i;
        539. for(i=0;i<3;i++)
        540. adjusting.write_data.voltage[i]=0;
        541. for(i=0;i<3;i++)
        542. adjusting.write_data.current[i]=0;
        543. for(i=0;i<3;i++)
        544. adjusting.write_data.watt[i]=0;
        545. for(i=0;i<3;i++)
        546. adjusting.write_data.var[i]=0;
        547. for(i=0;i<3;i++)
        548. adjusting.write_data.va[i]=0;
        549. ADE_AdjustWriteValue();
        550. memset(ADE_AdjustDataBuf,0,sizeof(ADE_AdjustDataBuf));/*校驗數據緩沖區清0*/
        551. }
        552. /**
        553. *功能:7758初始化函數
        554. */
        555. void ADE_Init(void)
        556. {
        557. unsigned char TempData,i;
        558. ADE_WriteMask();//write interrupt masktoade7758
        559. TempData=(0xff&ADE_Read(ADD_COMPMODE,8))|0x80;
        560. ADE_Write(ADD_COMPMODE,((int)TempData<<8),8);//seting activate the no-load threshold
        561. if(bWorkModel)
        562. {
        563. ADE_Clean();
        564. for(i=0;i<3;i++)
        565. ADE_Write(ADD_WDIV+i,0X00,8);
        566. }
        567. else//正常工作模式
        568. ADE_AdjustReadData();
        569. }
        570. intmain(void)
        571. {
        572. intret=0;
        573. ret=SPI_Open();
        574. if(ret)
        575. return ret;
        576. ADE_AdjustSaveData();
        577. ADE_Init();
        578. while(1)
        579. {
        580. sleep(1);
        581. bit_1s=1;
        582. ADE_GetData();
        583. }
        584. SPI_Close();
        585. return 0;
        586. }


        關鍵詞: ADE7758驅動程

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 磐石市| 大方县| 怀宁县| 河西区| 噶尔县| 武穴市| 虹口区| 开原市| 巴中市| 和政县| 瑞金市| 稻城县| 桂平市| 静宁县| 出国| 四平市| 寿阳县| 房产| 新干县| 股票| 黄平县| 通海县| 屏南县| 娄烦县| 简阳市| 大石桥市| 两当县| 建平县| 浦县| 阜平县| 来凤县| 阿拉善右旗| 边坝县| 安徽省| 张家口市| 许昌县| 江北区| 芷江| 泉州市| 句容市| 清水河县|