色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          STM32_ADE7758驅(qū)動(dòng)

          作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò) 收藏
          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;//工作模式標(biāo)志位 1:校準(zhǔn)模式;0:正常工作模式;
          15. unsigned char bit_1s=0;//1s鐘標(biāo)志,在時(shí)鐘中斷函數(shù)中置位
          16. static unsigned char divider=1;//電能分頻器,默認(rèn)值為零,視在功率超出一定值時(shí),自動(dòng)將該值提高
          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. *功能:延時(shí)函數(shù) 50us
          31. */
          32. void ADE_udelay(void)
          33. {
          34. delay_ms(1);
          35. }
          36. /**
          37. *功能:通過(guò)SPI寫(xiě)入數(shù)據(jù)至芯片
          38. *入口參數(shù):
          39. *buf->數(shù)據(jù)緩沖區(qū)
          40. *len->數(shù)據(jù)長(zhǎng)度
          41. */
          42. void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
          43. {
          44. SPI2_Write(buf,len);
          45. }
          46. /**
          47. *功能:通過(guò)SPI讀芯片數(shù)據(jù)
          48. *入口參數(shù):len->數(shù)據(jù)長(zhǎng)度
          49. *出口參數(shù):buf->數(shù)據(jù)緩沖區(qū)
          50. *
          51. */
          52. void ADE_SPIRead(unsigned char*buf,unsigned charlen)
          53. {
          54. SPI2_Read(buf,len);
          55. }
          56. /**
          57. *功能:7758寫(xiě)數(shù)據(jù)函數(shù)
          58. *入口參數(shù):
          59. *type:目標(biāo)寄存器的地址
          60. *wdata:寫(xiě)進(jìn)寄存器的內(nèi)容
          61. *databit:目標(biāo)寄存器的寬度
          62. *出口參數(shù):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讀寄存器函數(shù)
          97. *入口參數(shù):
          98. * type:目標(biāo)寄存器的地址
          99. *databit:目標(biāo)寄存器的寬度
          100. *出口參數(shù):指定寄存器的內(nèi)容
          101. *返回值:指定寄存器的內(nèi)容
          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. *功能:檢測(cè)異常
          142. */
          143. void ADE_AuCheck(void)
          144. {
          145. unsigned char i;
          146. unsignedinttemp_data[5];//存放運(yùn)算過(guò)程的中間變量
          147. unsignedinttemp_v,temp_i;
          148. //自動(dòng)檢測(cè)ADE7758是否出現(xiàn)異常
          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. //自動(dòng)設(shè)置分頻器的大小
          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];//存放運(yùn)算過(guò)程的中間變量
          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. //無(wú)功
          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. //能量的計(jì)算
          204. for(i=0;i<9;i++)
          205. energy[i]+=temp_data[i];//累加電能值,單位為 WS(瓦秒)
          206. //轉(zhuǎn)換成千瓦時(shí)
          207. for(i=0;i<3;i++)
          208. {
          209. working.watt_hour[i]+=(energy[i]/3600000);//轉(zhuǎn)換成千瓦時(shí)
          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. //轉(zhuǎn)換成千伏安時(shí)
          214. for(i=0;i<3;i++)
          215. {
          216. working.va_hour[i]+=(energy[i+6]/3600000);//轉(zhuǎn)換成千瓦時(shí)
          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. *功能:實(shí)時(shí)讀取電流電壓值
          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)/*三秒檢測(cè)一次異常*/
          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. *測(cè)試硬件連接是否正確
          302. */
          303. u8 ADE_TestHard(void)
          304. {
          305. unsignedintrdata,wdata=0xaa5577;//AEHF=1,VAEHF=1,低8位無(wú)用
          306. u8 ret=0;
          307. ADE_Write(ADD_MASK,wdata,24);
          308. rdata=ADE_Read(ADD_MASK,24);//驗(yàn)證通訊是否有問(wèn)題
          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初始化函數(shù)
          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);//軟件復(fù)位
          333. ADE_udelay();//添加延時(shí) 確保復(fù)位成功
          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權(quán)限,切換到其他線程*/
          344. }
          345. }


          關(guān)鍵詞: STM32ADE7758驅(qū)

          評(píng)論


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

          關(guān)閉