新闻中心

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驱

评论


技术专区

关闭