新聞中心

ADE7758驅(qū)動程序

作者: 時間:2016-11-11 來源:網(wǎng)絡(luò) 收藏
  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;//工作模式標(biāo)志位 1:校準(zhǔn)模式;0:正常工作模式;
  12. unsigned char bit_1s=0;//1s鐘標(biāo)志,在時鐘中斷函數(shù)中置位
  13. static unsigned char divider=1;//電能分頻器,默認(rèn)值為零,視在功率超出一定值時,自動將該值提高
  14. static unsignedintenergy[9];//用于累加電能值 36
  15. struct all_data working;//正常工作模式下存放的電參量 95
  16. struct adjust_data adjusting;//校準(zhǔn)模式下存放的數(shù)據(jù) 65
  17. static unsignedintvo_buffer[5][3];//用于電壓的積分慮波 36
  18. static unsignedintio_buffer[5][3];//用于電流的積分慮波 36
  19. static unsigned char b_adjust=0;//ADE7758已經(jīng)校準(zhǔn)標(biāo)志
  20. static unsigned char sample_cycle=0;//電壓采樣周期,5次取平均
  21. static unsigned char ADE_AdjustDataBuf[2+sizeof(struct adjust_dataw)]={0};/*校準(zhǔn)數(shù)據(jù)暫存緩沖區(qū)*/
  22. void ADE_Check7758(void);
  23. /**
  24. *功能:延時函數(shù) 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寫入數(shù)據(jù)至芯片
  39. *入口參數(shù):
  40. *buf->數(shù)據(jù)緩沖區(qū)
  41. *len->數(shù)據(jù)長度
  42. */
  43. void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
  44. {
  45. SPI_Write(buf,len);
  46. }
  47. /**
  48. *功能:通過SPI讀芯片數(shù)據(jù)
  49. *入口參數(shù):len->數(shù)據(jù)長度
  50. *出口參數(shù):buf->數(shù)據(jù)緩沖區(qū)
  51. *
  52. */
  53. void ADE_SPIRead(unsigned char*buf,unsigned charlen)
  54. {
  55. SPI_Read(buf,len);
  56. }
  57. /**
  58. *功能:7758寫數(shù)據(jù)函數(shù)
  59. *入口參數(shù):
  60. *type:目標(biāo)寄存器的地址
  61. *wdata:寫進(jìn)寄存器的內(nèi)容
  62. *databit:目標(biāo)寄存器的寬度
  63. *出口參數(shù):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讀寄存器函數(shù)
  91. *入口參數(shù):
  92. * type:目標(biāo)寄存器的地址
  93. *databit:目標(biāo)寄存器的寬度
  94. *出口參數(shù):指定寄存器的內(nèi)容
  95. *返回值:指定寄存器的內(nèi)容
  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是否出現(xiàn)異常
  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. //自動設(shè)置分頻器的大小
  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. //轉(zhuǎn)換成千瓦時
  200. for(i=0;i<3;i++)
  201. {
  202. working.watt_hour[i]+=(energy[i]/3600000);//轉(zhuǎn)換成千瓦時
  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. //轉(zhuǎn)換成千伏安時
  207. for(i=0;i<3;i++)
  208. {
  209. working.va_hour[i]+=(energy[i+6]/3600000);//轉(zhuǎn)換成千瓦時
  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. *校準(zhǔn)模式下 每秒讀取功率
  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;//沒有校準(zhǔn)有功功率
  283. adjusting.read_data.va[i]=temp_data[i+6]&0x0000ffff;
  284. }
  285. }
  286. /**
  287. *校準(zhǔn)模式下實時讀取電流電壓值
  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. *校準(zhǔn)數(shù)據(jù)保存至緩沖區(qū)
  361. */
  362. void ADE_WriteByte(unsigned short data,unsigned short addr)
  363. {
  364. memcpy(ADE_AdjustDataBuf+addr,&data,sizeof(unsigned short));
  365. }
  366. /**
  367. *讀取校準(zhǔn)數(shù)據(jù)緩沖區(qū)中數(shù)據(jù)
  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. *功能:保存校準(zhǔn)數(shù)據(jù)
  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);//寫入標(biāo)志
  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. *功能: 將緩沖區(qū)中的校準(zhǔn)參數(shù)寫入ADE7758
  418. *當(dāng)確定校準(zhǔn)參數(shù)的值后,便調(diào)用該函數(shù),寫數(shù)據(jù)寫入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. *功能:讀出已保存的校準(zhǔn)參數(shù)
  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已經(jīng)校準(zhǔn)標(biāo)志
  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是否異常,有則修復(fù)
  502. */
  503. void ADE_Check7758(void)
  504. {
  505. unsigned short temp,temp1;
  506. if(!b_adjust)//ADE7758已經(jīng)校準(zhǔn)標(biāo)志
  507. return;
  508. temp=ADE_ReadByte(ADE_SET_ADDR+2);
  509. temp1=ADE_Read(ADD_AVRMSGAIN,12)&0x0fff;
  510. if(temp!=temp1)//檢測A相校準(zhǔn)參數(shù)是否正確
  511. ADE_AdjustReadData();
  512. }
  513. /**
  514. *功能:將標(biāo)志寫入中斷寄存器中,允許能量寄存器容量超出一半時產(chǎn)生中斷
  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. *功能:清除校準(zhǔn)數(shù)據(jù)
  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));/*校驗數(shù)據(jù)緩沖區(qū)清0*/
  551. }
  552. /**
  553. *功能:7758初始化函數(shù)
  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. }


關(guān)鍵詞: ADE7758驅(qū)動程

評論


技術(shù)專區(qū)

關(guān)閉