新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32_ADE7758驅動

        STM32_ADE7758驅動

        作者: 時間:2016-11-11 來源:網絡 收藏
        1. /*
        2. *ade7758.c
        3. *
        4. *Createdon:2014年10月11日
        5. *Author:Lzy
        6. */
        7. //#include
        8. #include"ade7758.h"
        9. #include"sys.h"
        10. #define ADE_CS_PIN PBout(12)
        11. #define ADE_RCC RCC_APB2Periph_GPIOB
        12. #define ADE_GPIO GPIOB
        13. #define ADE_PIN(GPIO_Pin_12)
        14. unsigned char bWorkModel=0;//工作模式標志位 1:校準模式;0:正常工作模式;
        15. unsigned char bit_1s=0;//1s鐘標志,在時鐘中斷函數中置位
        16. static unsigned char divider=1;//電能分頻器,默認值為零,視在功率超出一定值時,自動將該值提高
        17. static unsignedintenergy[9];//用于累加電能值 36
        18. struct all_data working;//正常工作模式下存放的電參量 95
        19. static unsignedintvo_buffer[5][3];//用于電壓的積分慮波 36
        20. static unsignedintio_buffer[5][3];//用于電流的積分慮波 36
        21. /**
        22. *功能:片選使能
        23. */
        24. void ADE_CS(unsigned char cs)
        25. {
        26. ADE_CS_PIN=cs;
        27. delay_ms(1);
        28. }
        29. /**
        30. *功能:延時函數 50us
        31. */
        32. void ADE_udelay(void)
        33. {
        34. delay_ms(1);
        35. }
        36. /**
        37. *功能:通過SPI寫入數據至芯片
        38. *入口參數:
        39. *buf->數據緩沖區
        40. *len->數據長度
        41. */
        42. void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
        43. {
        44. SPI2_Write(buf,len);
        45. }
        46. /**
        47. *功能:通過SPI讀芯片數據
        48. *入口參數:len->數據長度
        49. *出口參數:buf->數據緩沖區
        50. *
        51. */
        52. void ADE_SPIRead(unsigned char*buf,unsigned charlen)
        53. {
        54. SPI2_Read(buf,len);
        55. }
        56. /**
        57. *功能:7758寫數據函數
        58. *入口參數:
        59. *type:目標寄存器的地址
        60. *wdata:寫進寄存器的內容
        61. *databit:目標寄存器的寬度
        62. *出口參數:NULL
        63. *返回值:NULL
        64. */
        65. void ADE_Write(unsigned char type,unsignedintwdata,unsigned char databit)
        66. {
        67. unsigned char data[4];
        68. ADE_CS(0);
        69. type=type|0x80;
        70. data[0]=type;
        71. ADE_SPIWrite(data,1);
        72. ADE_udelay();
        73. if(databit==8)
        74. {
        75. data[0]=wdata;
        76. ADE_SPIWrite(data,1);
        77. }
        78. elseif(databit==16)
        79. {
        80. data[0]=(wdata&0xff00)>>8;/*高8位*/
        81. data[1]=(wdata&0x00ff);/*底8位*/
        82. ADE_SPIWrite(data,2);
        83. }
        84. elseif(databit==24)
        85. {
        86. data[0]=(wdata&0xff0000)>>16;/*高8位*/
        87. data[1]=(wdata&0xff00)>>8;
        88. data[2]=(wdata&0xff);
        89. ADE_SPIWrite(data,3);
        90. }
        91. else
        92. printf("ADE write databit Error:%dn",databit);
        93. ADE_CS(1);
        94. }
        95. /**
        96. *功能:7758讀寄存器函數
        97. *入口參數:
        98. * type:目標寄存器的地址
        99. *databit:目標寄存器的寬度
        100. *出口參數:指定寄存器的內容
        101. *返回值:指定寄存器的內容
        102. */
        103. unsignedintADE_Read(unsigned char type,unsigned char databit)
        104. {
        105. unsigned char data[4]={0,0,0,0};
        106. unsignedintrtdata=0;
        107. ADE_CS(0);
        108. type=type&0x7F;
        109. data[0]=type;
        110. ADE_SPIWrite(data,1);
        111. ADE_udelay();
        112. if(databit==8)
        113. {
        114. ADE_SPIRead(data,1);
        115. rtdata=data[0];
        116. }
        117. elseif(databit==12)
        118. {
        119. ADE_SPIRead(data,2);
        120. rtdata=(data[0]&0x0f)<<8;
        121. rtdata+=data[1];
        122. }
        123. elseif(databit==16)
        124. {
        125. ADE_SPIRead(data,2);
        126. rtdata=data[0]<<8;
        127. rtdata+=data[1];
        128. }elseif(databit==24)
        129. {
        130. ADE_SPIRead(data,3);
        131. rtdata=data[0]<<16;
        132. rtdata+=(data[1]<<8);
        133. rtdata+=data[2];
        134. }
        135. else
        136. printf("ADE Read databit Error:%dn",databit);
        137. ADE_CS(1);
        138. return(rtdata);
        139. }
        140. /**
        141. *功能:檢測異常
        142. */
        143. void ADE_AuCheck(void)
        144. {
        145. unsigned char i;
        146. unsignedinttemp_data[5];//存放運算過程的中間變量
        147. unsignedinttemp_v,temp_i;
        148. //自動檢測ADE7758是否出現異常
        149. if(working.voltage[0]>ERR_VOLTAGE||
        150. working.voltage[1]>ERR_VOLTAGE||
        151. working.voltage[2]>ERR_VOLTAGE)
        152. {
        153. //ADE_Check7758();
        154. printf("ADE Errorn");
        155. }
        156. //自動設置分頻器的大小
        157. for(i=0;i<3;i++)
        158. {
        159. temp_v=working.voltage[i];
        160. temp_i=working.current[i];
        161. temp_data[i]=((temp_v*temp_i)/DIVI_VALUE)&0x000000ff;
        162. }
        163. temp_data[3]=(temp_data[0]>temp_data[1])?
        164. ((temp_data[0]>temp_data[2])?temp_data[0]:temp_data[2]):
        165. ((temp_data[1]>temp_data[2])?temp_data[1]:temp_data[2]);
        166. if(divider!=(char)temp_data[3])
        167. {
        168. //writetoade7758
        169. divider=(char)temp_data[3]+1;
        170. for(i=0;i<3;i++)
        171. ADE_Write(ADD_WDIV+i,((int)divider<<8),8);
        172. }
        173. }
        174. /**
        175. *功能:每秒讀取功率
        176. */
        177. void ADE_ReadHR(void)
        178. {
        179. unsigned char i;
        180. unsignedinttemp_data[9];//存放運算過程的中間變量
        181. //有功
        182. temp_data[ADD_AWATTHR-1]=ADE_Read(ADD_AWATTHR,16);
        183. temp_data[ADD_BWATTHR-1]=ADE_Read(ADD_BWATTHR,16);
        184. temp_data[ADD_CWATTHR-1]=ADE_Read(ADD_CWATTHR,16);
        185. //無功
        186. temp_data[ADD_AVARHR-1]=ADE_Read(ADD_AVARHR,16);
        187. temp_data[ADD_BVARHR-1]=ADE_Read(ADD_BVARHR,16);
        188. temp_data[ADD_CVARHR-1]=ADE_Read(ADD_CVARHR,16);
        189. //視在
        190. temp_data[ADD_AVAHR-1]=ADE_Read(ADD_AVAHR,16);
        191. temp_data[ADD_BVAHR-1]=ADE_Read(ADD_BVAHR,16);
        192. temp_data[ADD_CVAHR-1]=ADE_Read(ADD_CVAHR,16);
        193. for(i=0;i<9;i++)
        194. {
        195. if(temp_data[i]>0x7fff)
        196. temp_data[i]=0xffff-temp_data[i]+1;
        197. }
        198. if(divider>1)
        199. {
        200. for(i=0;i<9;i++)
        201. temp_data[i]=temp_data[i]*divider;//乘上分頻器的值
        202. }
        203. //能量的計算
        204. for(i=0;i<9;i++)
        205. energy[i]+=temp_data[i];//累加電能值,單位為 WS(瓦秒)
        206. //轉換成千瓦時
        207. for(i=0;i<3;i++)
        208. {
        209. working.watt_hour[i]+=(energy[i]/3600000);//轉換成千瓦時
        210. energy[i]=energy[i]%3600000;
        211. }
        212. working.watt_hour[3]=working.watt_hour[0]+working.watt_hour[1]+working.watt_hour[2];//總和
        213. //轉換成千伏安時
        214. for(i=0;i<3;i++)
        215. {
        216. working.va_hour[i]+=(energy[i+6]/3600000);//轉換成千瓦時
        217. energy[i+6]=energy[i+6]%3600000;
        218. }
        219. working.va_hour[3]=working.va_hour[0]+working.va_hour[1]+working.va_hour[2];//總和
        220. for(working.watt[3]=0,i=0;i<3;i++)
        221. {
        222. working.watt[i]=temp_data[i]/1000;//千瓦
        223. working.watt[3]+=working.watt[i];
        224. }
        225. for(working.var[3]=0,i=0;i<3;i++)
        226. {
        227. working.var[i]=temp_data[i+3]/1000;
        228. working.var[3]+=working.var[i];
        229. }
        230. for(working.va[3]=0,i=0;i<3;i++)
        231. {
        232. working.va[i]=temp_data[i+6]/1000;//千伏安
        233. if(working.va[i]
        234. working.va[i]=working.watt[i];
        235. working.va[3]+=working.va[i];
        236. }
        237. }
        238. /**
        239. *功能:實時讀取電流電壓值
        240. */
        241. void ADE_ReadVC(void)
        242. {
        243. unsigned char i,j;
        244. for(i=0;i<3;i++)
        245. {
        246. working.voltage[i]=0;
        247. working.current[i]=0;
        248. }
        249. for(i=0;i<3;i++)
        250. {
        251. for(j=0;j<5;j++)
        252. {
        253. working.voltage[i]+=vo_buffer[j][i];
        254. working.current[i]+=io_buffer[j][i];
        255. }
        256. }
        257. for(i=0;i<3;i++)
        258. {
        259. working.voltage[i]=working.voltage[i]/5;
        260. working.current[i]=working.current[i]/5;
        261. }
        262. //電壓電流的三相平均值
        263. working.voltage[3]=(working.voltage[0]+working.voltage[1]+working.voltage[2])/3;
        264. working.current[3]=(working.current[0]+working.current[1]+working.current[2])/3;
        265. printf("voltage=%x current=%xn",working.voltage[0],working.current[0]);
        266. }
        267. /**
        268. *功能:從ADE7758中取出三相電壓電流功率等電參量
        269. */
        270. void ADE_Update(void)
        271. {
        272. static unsigned char sample_cycle=0;//電壓采樣周期,5次取平均
        273. static unsigned char bit_3s=0;
        274. unsigned char j;
        275. if(!bWorkModel)//正常工作模式
        276. {
        277. if(bit_1s)
        278. {
        279. bit_1s=0;
        280. ADE_ReadHR();
        281. if((bit_3s++)>=3)/*三秒檢測一次異常*/
        282. {
        283. //ADE_AuCheck();
        284. bit_3s=0;
        285. }
        286. }
        287. for(j=0;j<3;j++)
        288. {
        289. vo_buffer[sample_cycle][j]=ADE_Read(ADD_AVRMS+j,24)/*>>12*/;//voltage
        290. io_buffer[sample_cycle][j]=ADE_Read(ADD_AIRMS+j,24)/*>>13*/;//current
        291. }
        292. if(sample_cycle==4)/*讀取5次取平均值*/
        293. ADE_ReadVC();
        294. }
        295. if(sample_cycle<4)
        296. sample_cycle+=1;
        297. else
        298. sample_cycle=0;
        299. }
        300. /**
        301. *測試硬件連接是否正確
        302. */
        303. u8 ADE_TestHard(void)
        304. {
        305. unsignedintrdata,wdata=0xaa5577;//AEHF=1,VAEHF=1,低8位無用
        306. u8 ret=0;
        307. ADE_Write(ADD_MASK,wdata,24);
        308. rdata=ADE_Read(ADD_MASK,24);//驗證通訊是否有問題
        309. if(rdata!=wdata)
        310. printf("ADE errorrn");
        311. else
        312. {
        313. ret=1;
        314. printf("ADE OKrn");
        315. }
        316. return ret;
        317. }
        318. /**
        319. *功能:7758初始化函數
        320. */
        321. void ADE_Init(void)
        322. {
        323. GPIO_InitTypeDef GPIO_InitStructure;
        324. RCC_APB2PeriphClockCmd(ADE_RCC,ENABLE);
        325. GPIO_InitStructure.GPIO_Pin=ADE_PIN;
        326. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出
        327. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度為50MHz
        328. GPIO_Init(ADE_GPIO,&GPIO_InitStructure);
        329. ADE_CS(1);
        330. if(ADE_TestHard())
        331. {
        332. ADE_Write(ADD_OPMODE,0x44,8);//軟件復位
        333. ADE_udelay();//添加延時 確保復位成功
        334. }
        335. }
        336. void ADE_thread_entry(void)
        337. {
        338. SPI2_Init();
        339. ADE_Init();
        340. while(1)
        341. {
        342. ADE_Update();
        343. delay_ms(50);/*等待,讓出cpu權限,切換到其他線程*/
        344. }
        345. }


        關鍵詞: STM32ADE7758驅

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 马山县| 德令哈市| 黄山市| 囊谦县| 洱源县| 建湖县| 北碚区| 新巴尔虎左旗| 明水县| 临沭县| 都昌县| 泾源县| 深水埗区| 齐齐哈尔市| 富顺县| 榕江县| 肇庆市| 大余县| 胶南市| 宣化县| 马关县| 日照市| 涞源县| 监利县| 达拉特旗| 安泽县| 嵩明县| 台安县| 年辖:市辖区| 开远市| 肃北| 新乡市| 平塘县| 于田县| 阿拉善左旗| 凌云县| 贡觉县| 娱乐| 鹿泉市| 海淀区| 海原县|