新聞中心

STM32_ADE7758驅(qū)動

作者: 時間:2016-11-11 來源:網(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ù)中置位
  16. static unsigned char divider=1;//電能分頻器,默認(rèn)值為零,視在功率超出一定值時,自動將該值提高
  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ù) 50us
  31. */
  32. void ADE_udelay(void)
  33. {
  34. delay_ms(1);
  35. }
  36. /**
  37. *功能:通過SPI寫入數(shù)據(jù)至芯片
  38. *入口參數(shù):
  39. *buf->數(shù)據(jù)緩沖區(qū)
  40. *len->數(shù)據(jù)長度
  41. */
  42. void ADE_SPIWrite(unsigned char*buf,unsigned charlen)
  43. {
  44. SPI2_Write(buf,len);
  45. }
  46. /**
  47. *功能:通過SPI讀芯片數(shù)據(jù)
  48. *入口參數(shù):len->數(shù)據(jù)長度
  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寫數(shù)據(jù)函數(shù)
  58. *入口參數(shù):
  59. *type:目標(biāo)寄存器的地址
  60. *wdata:寫進(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. *功能:檢測異常
  142. */
  143. void ADE_AuCheck(void)
  144. {
  145. unsigned char i;
  146. unsignedinttemp_data[5];//存放運算過程的中間變量
  147. unsignedinttemp_v,temp_i;
  148. //自動檢測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. //自動設(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];//存放運算過程的中間變量
  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. //轉(zhuǎn)換成千瓦時
  207. for(i=0;i<3;i++)
  208. {
  209. working.watt_hour[i]+=(energy[i]/3600000);//轉(zhuǎn)換成千瓦時
  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)換成千伏安時
  214. for(i=0;i<3;i++)
  215. {
  216. working.va_hour[i]+=(energy[i+6]/3600000);//轉(zhuǎn)換成千瓦時
  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初始化函數(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();//添加延時 確保復(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ū)

評論


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

關(guān)閉