久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10332|回復: 12
收起左側

單片機+CS5463單相用電器分析監測裝置程序+電路設計與制作

  [復制鏈接]
ID:602704 發表于 2019-8-28 15:45 | 顯示全部樓層 |閱讀模式
大家好:

          這是我第二天在51黑電子論壇的知識海洋里與各位共師兄習和探討,做了一個單相用電器分析監測裝置,希望哪里有需要完善的地方請各位多多賜教。
          話不多說上圖


1,實物照片
IMG_4702.JPG


2,測試數據照片


IMG_4705.JPG

3,原理圖及PCB文件

51hei截圖_20190828153208.png

51hei截圖_20190828153241.png



4,CS5463  單相雙向功率/電能IC *****************************

    這塊是需要大家重視的一個知識點
特性
  電能數據線性度:在1000 :1 動態范圍內線性度為 ±0.1%  片內功能:    ——可以測量瞬時電壓,電流和功率;IRMS和 VRMS, 視在功率,有功和無功功率;有功的基波和諧波功;
無功的基波功率, 功率因數, 頻率 —— 具有電能-脈沖轉換功能 ——具有系統校準和相位補償 ——具有溫度傳感器  兩種無功計算方式  符合IEC, ANSI, JIS
工業標準  功耗<12mW  優化的分流器接口  單電源地參考信號  片內2.5V 參考電壓(大溫漂25ppm/℃)  內帶電源監視器  簡單的三線數字串行接口  可以從串行EEPROM 智能“自引導”,不需要微控制器  電源配置 VA+ = +5 V; AGND = 0 V; VD+ = +3.3V~+5 V

概述 CS5463 是一個包含兩個ΔΣ模-數轉換器(ADC)、功率計算功能、電能到頻率轉換器和一個串行接口的 完整的功率測量芯片。它可以精確測量瞬時電壓,電流和計算IRMS、VRMS、瞬時功率、有功功率、無功功率,用 于研制開發單相、2線或3線電表。 CS5463可以使用低成本的分流器或互感器測量電流,使用分壓電阻或電壓互感器測量電壓。 CS5463具有與微控制器通訊的雙向串口,可編程的電能-脈沖輸出功能。CS5463還具有方便的片上系統校準。


            pin24=SSOP  

5,整機程序


  1. //頭文件
  2. #include <REG52.h>
  3. #include <string.h>
  4. #include <intrins.h>
  5. #define uint  unsigned int
  6. #define uchar unsigned char

  7. typedef bit  bool;
  8. typedef unsigned char  uint8;                   /* defined for unsigned 8-bits integer variable         無符號8位整型變量  */
  9. typedef signed   char  int8;                    /* defined for signed 8-bits integer variable                有符號8位整型變量  */
  10. typedef unsigned int   uint16;                  /* defined for unsigned 16-bits integer variable         無符號16位整型變量 */
  11. typedef signed   int   int16;                   /* defined for signed 16-bits integer variable                 有符號16位整型變量 */
  12. typedef unsigned long  uint32;                  /* defined for unsigned 32-bits integer variable         無符號32位整型變量 */
  13. typedef signed   long  int32;                   /* defined for signed 32-bits integer variable                 有符號32位整型變量 */
  14. typedef float          fp32;                    /* single precision floating point variable (32bits) 單精度浮點數(32位長度) */

  15. /*****************************************************************************/
  16. sbit LCM_cs   = P0^0;  //RS
  17. sbit LCM_std  = P0^1;  //SID
  18. sbit LCM_sclk = P0^2;  //SCLK
  19. //sbit LCM_psb  = P2^3;   //H=并口; L=串口;

  20. char a,b,c;
  21. char aa,bb,cc,dd,ee;
  22. char i,q,T=125;
  23. uchar code tab1[]={
  24. "電壓:           "
  25. "功率:           "
  26. "電流:           "
  27. "溫度:           "
  28. };
  29. /****************************************************************************/

  30. uchar r[3]={0x00,0x00,0x00};

  31. /******************************************************************
  32.                            接口定義
  33. ******************************************************************/
  34. sbit SCLK=P2^2;         //ck
  35. sbit MOSI=P2^1;         //DI
  36. sbit MISO=P2^0;         //DO
  37. sbit INT=P3^2;
  38. sbit CS=P2^3;
  39. sbit RST=P2^4;        //RST

  40. #define CS5463_VScale       525             //計算電壓比例,220V*250mv/110mv=500V
  41. #define CS5463_IScale       (250/10)        //計算電流比例

  42. static uint8 RX_Buff[4];                                        //CS5463讀寫緩沖區
  43. uint8 sta;                                                                        //芯片狀態

  44. #define READ_MASK                        0xBF        //讀寄存器時的屏蔽碼,與(寫)地址相與
  45. #define CMD_SYNC0            0XFE          //結束串口重新初始化
  46. #define CMD_SYNC1            0XFF          //開始串口重新初始化
  47. #define REG_CONFR           0x40           //配置
  48. #define REG_CYCCONT         0x4A           //一個計算周期的A/D轉換數
  49. #define REG_STATUSR         0x5E         //狀態
  50. #define REG_MODER           0x64          //操作模式
  51. #define REG_MASKR           0x74          //中斷屏蔽
  52. #define REG_CTRLR           0x78          //控制
  53. #define CMD_STARTC           0XE8          //執行連續計算周期

  54. #define REG_VRMSR           0X18          //VRMS
  55. #define REG_IRMSR           0X16          //IRMS
  56. #define REG_Pactive           0X14          //Pactive

  57. sbit Relay = P3^7;//斷電器引腳定義
  58. uint32 CurrentCtl;//電流全局變量

  59. /*************************************************************
  60. ** 函數名稱:uDelay
  61. ** 函數功能:延時
  62. ** 函數參數:j
  63. ** 返回值:無
  64. ** 創建時間:2009-4-23
  65. ** 第一次修改時間:無
  66. **************************************************************/
  67. static  void uDelay(uint8 j)
  68. {
  69.   uint8 i;
  70.   for(;j>0;j--)
  71.         { for(i=0;i<255;i--)
  72.                 {
  73.                 ;
  74.                 }
  75.         }
  76. }
  77. /*************************************************************
  78. ** 函數名稱:CS5463CMD
  79. ** 函數功能:CS5463命令函數
  80. ** 函數參數:無
  81. ** 創建時間:2009-9-14
  82. ** 第一次修改時間:無
  83. **************************************************************/
  84. static void CS5463CMD(uint8 cmd)
  85. {
  86. uint8 i;
  87. SCLK = 1;
  88. CS = 0;
  89. i = 0;
  90. while(i<8)
  91. {
  92.   uDelay(50);
  93.         SCLK = 0;
  94.         if(cmd&0x80)MOSI = 1;
  95.         else                MOSI = 0;
  96.         uDelay(50);
  97.         SCLK = 1;                                         //在時鐘上升沿,數據被寫入CS5463
  98.         cmd <<= 1;
  99.         i++;
  100. }
  101. uDelay(50);
  102. CS = 1;
  103. }
  104. /*************************************************************
  105. ** 函數名稱:CS5463WriteReg
  106. ** 函數功能:CS5463寫寄存器函數
  107. ** 函數參數:無
  108. ** 創建時間:2009-9-14
  109. ** 第一次修改時間:無
  110. **************************************************************/
  111. void CS5463WriteReg(uint8 addr,uint8 *p)
  112. {
  113. uint8 i,j;
  114. uint8 dat;
  115. SCLK = 1;
  116. CS = 0;
  117. i = 0;
  118. while(i<8)
  119. {
  120.           uDelay(50);
  121.         SCLK = 0;
  122.         if(addr&0x80)MOSI = 1;
  123.         else                 MOSI = 0;
  124.         uDelay(50);
  125.         SCLK = 1;                                         //在時鐘上升沿,數據被寫入CS5463
  126.         addr <<= 1;
  127.         i++;
  128. }
  129. j = 0;
  130. while(j<3)
  131. {
  132.           dat = *(p+j);
  133.         i = 0;
  134.         while(i<8)
  135.         {
  136.                   uDelay(50);
  137.                 SCLK = 0;
  138.                 if(dat&0x80)MOSI = 1;
  139.                 else                MOSI = 0;
  140.                 uDelay(50);
  141.                 SCLK = 1;                                  //在時鐘上升沿,數據被寫入CS5463
  142.                 dat <<= 1;
  143.                 i++;
  144.         }
  145.         j++;
  146. }
  147. uDelay(50);
  148. CS = 1;
  149. }
  150. /*************************************************************
  151. ** 函數名稱:CS5463ReadReg
  152. ** 函數功能:CS5463讀寄存器函數
  153. ** 函數參數:無
  154. ** 創建時間:2009-9-14
  155. ** 第一次修改時間:無
  156. **************************************************************/
  157. void CS5463ReadReg(uint8 addr,uint8 *p)
  158. {
  159. uint8 i,j;
  160. uint8 dat;
  161. SCLK = 0;
  162. CS = 0;
  163. addr &= READ_MASK;
  164. i = 0;
  165. while(i<8)
  166. {
  167.           uDelay(50);
  168.         SCLK = 0;
  169.         if(addr&0x80)MOSI = 1;
  170.         else                 MOSI = 0;
  171.         uDelay(50);
  172.         SCLK = 1;
  173.         addr <<= 1;                                         //在時鐘上升沿,數據被寫入CS5463
  174.         i++;
  175. }
  176. uDelay(50);
  177. MOSI = 1;
  178. j = 0;
  179. while(j<3)
  180. {
  181.         i = 0;
  182.         dat = 0;
  183.         while(i<8)
  184.         {
  185.                 if(i==7)MOSI = 0;
  186.                 else        MOSI = 1;
  187.                 SCLK = 0;
  188.                 uDelay(50);
  189.                 dat <<= 1;                                                
  190.                 if(MISO)dat |= 0x01;
  191.                 else        dat &= 0xFE;
  192.                 SCLK = 1;
  193.                 uDelay(50);                                                         
  194.                 i++;
  195.         }
  196.         *(p+j) = dat;
  197.         j++;
  198. }
  199. MOSI = 1;
  200. CS = 1;
  201. }
  202. /*************************************************************************************************
  203. ** CS5463 應用函數
  204. *************************************************************************************************/
  205. /*************************************************************
  206. ** 函數名稱:CS5463Init
  207. ** 函數功能:CS5463復位和初始化函數
  208. ** 函數參數:無
  209. ** 創建時間:2009-9-14
  210. ** 第一次修改時間:無
  211. **************************************************************/
  212. bit CS5463_Init(void)           //
  213. {
  214. RST = 0;
  215. uDelay(200);
  216. RST = 1;
  217. uDelay(100);
  218. //----------------------
  219. //發送同步序列
  220. RX_Buff[0] = CMD_SYNC1;
  221. RX_Buff[1] = CMD_SYNC1;
  222. RX_Buff[2] = CMD_SYNC0;
  223. CS5463WriteReg(CMD_SYNC1,RX_Buff);          //#define CMD_SYNC1            0XFF          //開始串口重新初始化               
  224. //----------------------
  225. //初始化--配置寄存器
  226. //相位補償為PC[6:0]=[0000000];
  227. //電流通道增益為Igain=10;
  228. //EWA=0;
  229. //INT中斷為低電平有效IMODE:IINV=[00]
  230. //iCPU=0
  231. //K[3:0]=[0001]
  232. RX_Buff[0] = 0x00;                                                
  233. RX_Buff[1] = 0x00;
  234. RX_Buff[2] = 0x01;
  235. CS5463WriteReg(REG_CONFR,RX_Buff);         //        #define REG_CONFR           0x40           //配置
  236. //----------------------
  237. //初始化--操作寄存器
  238. RX_Buff[0] = 0x00; //B0000_0000;                                 
  239. RX_Buff[1] = 0x00;//B0000_0000;
  240. RX_Buff[2] = 0x60;//B0110_0000;
  241. CS5463WriteReg(REG_MODER,RX_Buff);          //#define REG_MODER           0x64          //操作模式
  242. //----------------------
  243. //初始化--電流 交流偏置 校準寄存器
  244. // RW24XX(RX_Buff,3,EE_IACBIAS,0xA1);
  245. // CS5463WriteReg(REG_IACOFF,RX_Buff);        
  246. //----------------------
  247. //初始化--電流 增益校準寄存器
  248. // RW24XX(RX_Buff,3,EE_IACGAIN,0xA1);
  249. // CS5463WriteReg(REG_IGN,RX_Buff);               
  250. //----------------------
  251. //初始化--電壓 交流偏置 校準寄存器
  252. // RW24XX(RX_Buff,3,EE_VACBIAS,0xA1);
  253. // CS5463WriteReg(REG_VACOFF,RX_Buff);        
  254. //----------------------
  255. //初始化--電壓 增益校準寄存器
  256. // RW24XX(RX_Buff,3,EE_VACGAIN,0xA1);
  257. // CS5463WriteReg(REG_VGN,RX_Buff);               
  258. //----------------------
  259. RX_Buff[0] = 0x00;
  260. RX_Buff[1] = 0x0F;
  261. RX_Buff[2] = 0xA0;                                                //#define REG_CYCCONT         0x4A           //一個計算周期的A/D轉換數
  262. CS5463WriteReg(REG_CYCCONT,RX_Buff);        //初始化--CYCLE COUNT 寄存器,4000
  263. //----------------------
  264. //初始化--脈沖速率寄存器
  265. // RX_Buff[0] = 0x00;
  266. // RX_Buff[1] = 0x34;
  267. // RX_Buff[2] = 0x9C;
  268. // CS5463WriteReg(REG_PULRATE,RX_Buff);        
  269. //----------------------
  270. RX_Buff[0] = 0xFF;
  271. RX_Buff[1] = 0xFF;
  272. RX_Buff[2] = 0xFF;
  273. CS5463WriteReg(REG_STATUSR,RX_Buff);        //初始化--狀態寄存器  #define REG_STATUSR         0x5E         //狀態
  274. //----------------------
  275. RX_Buff[0] = 0x80;                                                //開電流、電壓、功率測量完畢中斷
  276. RX_Buff[1] = 0x00;
  277. RX_Buff[2] = 0x80;                                                //開溫度測量完畢中斷
  278. CS5463WriteReg(REG_MASKR,RX_Buff);                //初始化--中斷屏蔽寄存器    #define REG_MASKR           0x74          //中斷屏蔽
  279. //----------------------
  280. RX_Buff[0] = 0x00;
  281. RX_Buff[1] = 0x00;
  282. RX_Buff[2] = 0x00;
  283. CS5463WriteReg(REG_CTRLR,RX_Buff);                //初始化--控制寄存器   #define REG_CTRLR           0x78          //控制  
  284. //----------------------
  285. CS5463CMD(CMD_STARTC);                                           //啟動連續轉換            #define CMD_STARTC           0XE8          //執行連續計算周期
  286. //CS5463_Status = 0;                                                //初始化任務進程狀態
  287. //Load_Status = 0;
  288. //CS5463_CrmsSmallCunt = 0;
  289. //CS5463_CrmsOverCunt = 0;
  290. return(1);                    //只要做完這些步驟就返回true  1
  291. }
  292. /*************************************************************
  293. ** 函數名稱:CS5463_ResetStatusReg
  294. ** 函數功能:復位狀態寄存器函數
  295. ** 函數參數:無
  296. ** 創建時間:2009-9-15
  297. ** 第一次修改時間:無
  298. **************************************************************/
  299. static void CS5463_ResetStatusReg(void)
  300. {
  301. RX_Buff[0] = 0xFF;
  302. RX_Buff[1] = 0xFF;
  303. RX_Buff[2] = 0xFF;
  304. CS5463WriteReg(0x5E,RX_Buff);                //復位狀態寄存器        #define REG_STATUSR         0x5E         //狀態  
  305. }
  306. /*************************************************************
  307. ** 函數名稱:CS5463_GetStatusReg
  308. ** 函數功能:讀取狀態寄存器函數
  309. ** 函數參數:無
  310. ** 創建時間:2009-9-15
  311. ** 第一次修改時間:無
  312. **************************************************************/
  313. static uint8 CS5463_GetStatusReg(void)
  314. {
  315. uint8 sta=0;
  316. CS5463ReadReg(0x1E,RX_Buff);           //1E 是什么?   狀態寄存器
  317. if(RX_Buff[0]&0x80)                                           //檢測:電流、電壓、功率測量是否完畢
  318. {
  319.         //檢測電流/電壓是否超出范圍
  320.         //檢測電流有效值/電壓有效值/電能是否超出范圍
  321.         if((RX_Buff[0]&0x03)||(RX_Buff[1]&0x70))
  322.         {
  323.                  CS5463_ResetStatusReg();                //復位狀態寄存器
  324.         }
  325.         else
  326.         {
  327.                 sta |= 0x01;//B0000_0001;        //
  328.         }
  329. }

  330. if(RX_Buff[2]&0x80)                                   //檢測:溫度測量是否完畢
  331. {
  332.           sta |=0x02; //B0000_0010;
  333. }
  334. return(sta);        
  335. }  

  336. void DelayM(unsigned int a)       //延時函數 1MS/次        
  337. {
  338.                 unsigned char i;
  339.                 while( --a != 0)
  340.        {               
  341.                 for(i = 0; i < 125; i++);  //一個 ; 表示空語句,CPU空轉從0加到125
  342.                 }                                      
  343. }

  344. void Delay(int num)//延時函數
  345. {
  346.         while(num--);
  347. }

  348. /******************************************************************************/
  349. //寫指令或數據  (0,指令) (1,數據)
  350. void LCM_WriteDatOrCom(bit dat_comm,uchar content)
  351. {
  352.   uchar a,i,j;
  353.   Delay(50);
  354.   a=content;
  355.   LCM_cs=1;
  356.   LCM_sclk=0;
  357.   LCM_std=1;
  358.   for(i=0;i<5;i++)
  359.   {
  360.     LCM_sclk=1;
  361.     LCM_sclk=0;
  362.   }
  363.   LCM_std=0;
  364.   LCM_sclk=1;
  365.   LCM_sclk=0;
  366.   if(dat_comm)
  367.     LCM_std=1;   //data
  368.   else
  369.    LCM_std=0;   //command
  370.   LCM_sclk=1;
  371.   LCM_sclk=0;
  372.   LCM_std=0;
  373.   LCM_sclk=1;
  374.   LCM_sclk=0;
  375.   for(j=0;j<2;j++)
  376.   {
  377.     for(i=0;i<4;i++)
  378.     {
  379.       a=a<<1;
  380.       LCM_std=CY;
  381.       LCM_sclk=1;
  382.       LCM_sclk=0;
  383.     }
  384.     LCM_std=0;
  385.     for(i=0;i<4;i++)
  386.     {
  387.       LCM_sclk=1;
  388.       LCM_sclk=0;
  389.     }
  390.   }
  391. }
  392. /*********************************************************************************/


  393. /*****************************************************************************/
  394. //初始化LCM
  395. void LCM_init(void)         
  396. {
  397. //  LCM_psb=0;
  398.   LCM_WriteDatOrCom (0,0x30);  /*30---基本指令動作*/   
  399.   LCM_WriteDatOrCom (0,0x01);  /*清屏,地址指針指向00H*/
  400.   Delay (100);
  401.   LCM_WriteDatOrCom (0,0x06);  /*光標的移動方向*/
  402.   LCM_WriteDatOrCom(0,0x0c);   /*開顯示,關游標*/
  403. }

  404. void chn_disp (uchar code *chn)   //顯示4行 指針
  405. {
  406.   uchar i,j;
  407.   LCM_WriteDatOrCom  (0,0x30);         //        
  408.   LCM_WriteDatOrCom  (0,0x80);         //
  409.   for (j=0;j<4;j++)
  410.   {
  411.     for (i=0;i<16;i++)
  412.     LCM_WriteDatOrCom  (1,chn[j*16+i]);
  413.   }
  414. }
  415. /*****************************************************************************/
  416. //清屏函數
  417. void LCM_clr(void)
  418. {
  419.   LCM_WriteDatOrCom (0,0x30);
  420.   LCM_WriteDatOrCom (0,0x01);   /*清屏,地址指針指向00H*/
  421.   Delay (180);
  422. }
  423. /*****************************************************************************/
  424. //向LCM發送一個字符串,長度64字符之內。
  425. //應用:LCM_WriteString("您好!");
  426. void LCM_WriteString(unsigned char *str)
  427. {
  428.                 while(*str != '\0')
  429.        {
  430.                         LCM_WriteDatOrCom(1,*str++);
  431.         }
  432.                 *str = 0;        
  433. }

  434. /*************************************************************
  435. ** 函數名稱:CS5463_GetCurrentRMS
  436. ** 函數功能:讀取電流有效值函數
  437. ** 函數參數:無
  438. ** 創建時間:2009-9-15
  439. ** 第一次修改時間:無
  440. **************************************************************/
  441. static void CS5463_GetCurrentRMS(void)
  442. {
  443. fp32 G = 0.5,result;
  444. uint32 temp1;
  445. uint8 temp,i,j;
  446. CS5463ReadReg(REG_IRMSR,RX_Buff);                   //讀取電流有效值
  447. //SndCom1Data(RX_Buff,3);
  448. i = 0;
  449. result = 0;
  450. while(i<3)
  451. {
  452.           temp = RX_Buff[i];                                          
  453.         j = 0;
  454.         while(j<8)
  455.         {
  456.                  if(temp&0x80)
  457.                 {
  458.                          result += G;        
  459.                 }
  460.                 temp <<= 1;
  461.                 j++;
  462.                 G = G/2;        
  463.         }
  464.         i++;
  465. }
  466. result = result*CS5463_IScale;//I_Coff;                                                //計算電流值 暫時不用
  467. result *= 1000;                                                                //單位mA(毫安)  12345ma
  468. temp1 = (uint32)result;
  469. CurrentCtl = temp1;

  470. LCM_WriteDatOrCom  (0,0x94);
  471.         aa=        temp1/10000;
  472.         if(aa==0)
  473.                 LCM_WriteDatOrCom(1,' ');
  474.         else
  475.                 LCM_WriteDatOrCom(1,aa+0x30);
  476.         bb=        (temp1%10000)/1000;
  477.         if((aa==0)&&(bb==0))
  478.                 LCM_WriteDatOrCom(1,' ');
  479.         else
  480.                 LCM_WriteDatOrCom(1,bb+0x30);
  481.         cc=(temp1%1000)/100;
  482.         if((aa==0)&&(bb==0)&&(cc==0))
  483.                 LCM_WriteDatOrCom(1,' ');
  484.         else
  485.                 LCM_WriteDatOrCom(1,cc+0x30);
  486. //        LCM_WriteDatOrCom(1,0x2e);  //小數點  不需要小數點
  487.         dd=        (temp1%100)/10;
  488.         LCM_WriteDatOrCom(1,dd+0x30);
  489.         ee=temp1%10;
  490.         LCM_WriteDatOrCom(1,ee+0x30);
  491.         LCM_WriteString(" mA");

  492. }


  493. /*************************************************************
  494. ** 函數名稱:CS5463_GetPactiveRMS
  495. ** 函數功能:讀取有功功率函數
  496. ** 函數參數:無
  497. ** 創建時間:2009-9-15
  498. ** 第一次修改時間:無
  499. **************************************************************/
  500. static void CS5463_GetPactiveRMS(void)
  501. {
  502. fp32 G = 1.0,result;
  503. uint8 temp,i,j;
  504. uint32 temp1;
  505. CS5463ReadReg(0x14,RX_Buff);           //讀取有功功率REG_Pactive
  506. //SndCom1Data(RX_Buff,3);
  507. temp = RX_Buff[0];
  508. if(temp&0x80)                                                          //如果為負數,計算原碼
  509. {
  510.           RX_Buff[0] = ~RX_Buff[0];                        //本來為取反+1,這里因為精度的原因,不+1
  511.         RX_Buff[1] = ~RX_Buff[1];
  512.         RX_Buff[2] = ~RX_Buff[2];                        
  513. }
  514. i = 0;
  515. result = 0;
  516. while(i<3)
  517. {
  518.           temp = RX_Buff[i];                                          
  519.         j = 0;
  520.         while(j<8)
  521.         {
  522.                  if(temp&0x80)
  523.                 {
  524.                          result += G;        
  525.                 }
  526.                 temp <<= 1;
  527.                 j++;
  528.                 G = G/2;        
  529.         }
  530.         i++;
  531. }
  532. // result = result*P_Coff;                                //計算功率,單位W(瓦特)
  533. // result = Vrms*Irms;                                        ////////直接計算功率
  534.   result = result*13125;
  535. temp1 = (uint32)result;

  536.   LCM_WriteDatOrCom  (0,0x8C);                //26W  12345W
  537.         aa=        temp1/10000;
  538.         if(aa==0)
  539.                 LCM_WriteDatOrCom(1,' ');
  540.         else
  541.                 LCM_WriteDatOrCom(1,aa+0x30);
  542.         bb=        (temp1%10000)/1000;
  543.         if((aa==0)&&(bb==0))
  544.                 LCM_WriteDatOrCom(1,' ');
  545.         else
  546.                 LCM_WriteDatOrCom(1,bb+0x30);
  547.         cc=(temp1%1000)/100;
  548.         if((aa==0)&&(bb==0)&&(cc==0))
  549.                 LCM_WriteDatOrCom(1,' ');
  550.         else
  551.                 LCM_WriteDatOrCom(1,cc+0x30);
  552. //        LCM_WriteDatOrCom(1,0x2e);  //小數點  不需要小數點
  553.         dd=        (temp1%100)/10;
  554.         LCM_WriteDatOrCom(1,dd+0x30);
  555.         ee=temp1%10;
  556.         LCM_WriteDatOrCom(1,ee+0x30);
  557.         LCM_WriteString(" W");

  558. }
  559. /*************************************************************
  560. ** 函數名稱:CS5463_GetPowerFactor
  561. ** 函數功能:讀取功率因數函數
  562. ** 函數參數:無
  563. ** 創建時間:2009-11-02
  564. ** 第一次修改時間:無
  565. **************************************************************
  566. static void CS5463_GetPowerFactor(void)
  567. {
  568. fp32 G = 1.0,result;
  569. uint8 temp,i,j;
  570. uint32 temp1;
  571. CS5463ReadReg(0x32,RX_Buff);                   //讀取功率因數
  572. //SndCom1Data(RX_Buff,3);
  573. temp = RX_Buff[0];
  574. if(temp&0x80)                                                          //如果為負數,計算原碼
  575. {
  576.           RX_Buff[0] = ~RX_Buff[0];                        //本來為取反+1,這里因為精度的原因,不+1
  577.         RX_Buff[1] = ~RX_Buff[1];
  578.         RX_Buff[2] = ~RX_Buff[2];                        
  579. }
  580. i = 0;
  581. result = 0;
  582. while(i<3)
  583. {
  584.           temp = RX_Buff[i];                                          
  585.         j = 0;
  586.         while(j<8)
  587.         {
  588.                  if(temp&0x80)
  589.                 {
  590.                          result += G;        
  591.                 }
  592.                 temp <<= 1;
  593.                 j++;
  594.                 G = G/2;        
  595.         }
  596.         i++;
  597. }
  598. result *= 10000;
  599. temp1 = (uint32)result;

  600. }


  601. /*************************************************************
  602. ** 函數名稱:CS5463_GetTemperature
  603. ** 函數功能:讀取溫度函數
  604. ** 函數參數:無
  605. ** 創建時間:2009-11-03
  606. ** 第一次修改時間:無
  607. **************************************************************/
  608. static void CS5463_GetTemperature(void)          //溫度能顯示了 PT2017-2-12
  609. {
  610. fp32 G = 128,result;
  611. uint8 temp,i,j,pn=0;
  612. uint32 temp1;
  613. CS5463ReadReg(0x26,RX_Buff);                   //讀取溫度        是的在這里就讀到了溫度
  614. //SndCom1Data(RX_Buff,3);
  615. temp = RX_Buff[0];
  616. if(temp&0x80)                                                          //如果為負數,計算原碼
  617. {
  618.           pn = 1;                                                                //負數標志
  619.         RX_Buff[0] = ~RX_Buff[0];                        //本來為取反+1,這里因為精度的原因,不+1
  620.         RX_Buff[1] = ~RX_Buff[1];
  621.         RX_Buff[2] = ~RX_Buff[2];                        
  622. }
  623. i = 0;
  624. result = 0;    //這個值是浮點數 先清零 再逐個把0.5的權 數據加進來
  625. while(i<3)
  626. {
  627.           temp = RX_Buff[i];        //雖然這個數組定義了4個字節 實際就用了 Buff[0]  Buff[1]  RX_Buff[2]                                   
  628.         j = 0;
  629.         while(j<8)
  630.         {
  631.                  if(temp&0x80)
  632.                 {
  633.                          result += G;        //把0.5的權數據加進來                  
  634.                 }
  635.                 temp <<= 1;
  636.                 j++;
  637.                 G = G/2;        
  638.         }
  639.         i++;
  640. }
  641. if(result<128)                          //是的這個result 是 -127,128   這里已經獲取了溫度浮點值 最多是一個3位數? 還有小數點
  642. {
  643.          result *= 100;
  644.         temp1 = (uint32)result;          //是的 這里就是 例如12523  -----> 125.23  怎么去顯示? 如何分離 從8A開始顯示

  645.             LCM_WriteDatOrCom  (0,0x9C);        // 顯示起始位置  第4行
  646.                 aa=        temp1/ 10000;
  647.                 if(pn==1)
  648.                         LCM_WriteDatOrCom(1,'-');        
  649.                 else
  650.                         LCM_WriteDatOrCom(1,'+');        
  651.                         
  652.                 bb=temp1/1000- aa*10;
  653.                 LCM_WriteDatOrCom(1,bb+0x30);

  654.                 cc=        temp1/100- aa*100-bb*10;
  655.                 LCM_WriteDatOrCom(1,cc+0x30);
  656.             LCM_WriteDatOrCom(1,0x2e);         //"."
  657.                 dd=        (temp1%100)/10;
  658.                 LCM_WriteDatOrCom(1,dd+0x30);
  659.                 ee=temp1%10;
  660.                 LCM_WriteDatOrCom(1,ee+0x30);
  661.                 LCM_WriteString("℃");

  662. }
  663. }
  664. /*************************************************************
  665. ** 函數名稱:CS5463_GetVoltRMS
  666. ** 函數功能:讀取電壓有效值函數
  667. ** 函數參數:無
  668. ** 創建時間:2009-9-15
  669. ** 第一次修改時間:2009-9-23,修改電壓系數(需驗證)
  670. ** 第二次修改時間:2010-3-22,設定測量讀數小于100V時數據無效
  671. ** 第三次修改時間:
  672. **************************************************************/
  673. static void CS5463_GetVoltRMS(void)                 //PT2017-2-12 電壓顯示OK
  674. {
  675. float G = 0.5,result;                //typedef float          fp32;          就是浮點類型
  676. int temp1;                          //  int
  677. uint8 temp,i,j;                  //  byte
  678. CS5463ReadReg(REG_VRMSR,RX_Buff);                   //讀取電壓有效值  #define REG_VRMSR           0x58
  679. //SndCom1Data(RX_Buff,3);
  680. i = 0;
  681. result = 0;
  682. while(i<3)
  683. {
  684.           temp = RX_Buff[i];                                          
  685.         j = 0;
  686.         while(j<8)
  687.         {
  688.                  if(temp&0x80)
  689.                 {
  690.                          result += G;        
  691.                 }
  692.                 temp <<= 1;
  693.                 j++;
  694.                 G = G/2;        
  695.         }
  696.         i++;                                                               
  697. }                                                                                //電壓在220時取樣電壓為78mv
  698. result = result*CS5463_VScale;//V_Coff;                                //計算電壓值220V*250mv/(110mv/1.414)=704.8V            可以暫時不用  
  699. // if(result<=100)return;                                        //如果測量讀出電壓小于100V,確認讀數錯誤
  700. result *= 100;                                                //單位為mV(毫伏) 12345mv  5位你怎么顯示
  701. temp1 = (uint32)result;

  702.         LCM_WriteDatOrCom  (0,0x84);
  703.         aa=        temp1/10000;
  704.         LCM_WriteDatOrCom(1,aa+0x30);
  705.         bb=        (temp1%10000)/1000;
  706.         LCM_WriteDatOrCom(1,bb+0x30);
  707.         cc=(temp1%1000)/100;
  708.         LCM_WriteDatOrCom(1,cc+0x30);
  709.         LCM_WriteDatOrCom(1,0x2e);
  710.         dd=        (temp1%100)/10;
  711.         LCM_WriteDatOrCom(1,dd+0x30);
  712.         ee=temp1%10;
  713.         LCM_WriteDatOrCom(1,ee+0x30);
  714.         LCM_WriteString(" V");

  715. }

  716. void main() //整個程序函數從這里開始執行
  717. {
  718.   CS5463_Init();
  719.   LCM_init();       //初始化液晶顯示器
  720.         LCM_clr();       //清屏
  721.         chn_disp(tab1); //顯示歡迎字
  722.         DelayM(500);  //顯示等留3秒
  723.   Relay = 1;
  724.   
  725.           while(1)
  726.           {
  727.         //        if(INT)break;                                                        //檢查中斷信號

  728.                 sta        = CS5463_GetStatusReg();                          //檢測中斷產生的原因
  729.                 if(0x01==(sta&0x01))                                           //讀取電流電壓
  730.                 {        
  731.         //                CS5463Monitor_Cunt = 0;                                //如果有中斷,表明芯片正常工作,清除監控定時器
  732.                         CS5463_ResetStatusReg();                        //清除標志
  733.                         CS5463_GetVoltRMS();                                //獲取電壓
  734.                         CS5463_GetCurrentRMS();                                //獲取電流
  735.                         CS5463_GetPactiveRMS();                                //獲取功率
  736. //                        CS5463_GetPowerFactor();                        //獲取功率因數
  737.                         if(0x02==(sta&0x02))                                //讀取溫度
  738.                         {        
  739.                         CS5463_GetVoltRMS();                                //獲取電壓                                                               
  740.                         CS5463_GetTemperature();                    //溫度讀取不需要太頻繁,所以跟電流電壓一起讀取

  741.                                 //CS5463_Init();                                //重新初始化芯片
  742.                         }                                                
  743.                         //SndCom1Data(MeasureData,16);
  744.                 }
  745.                 if(CurrentCtl > 5000)//如果電流大于要求設置的5A則斷電
  746. …………
  747. …………
復制代碼

  最后,如果這個設計對你有所幫助請給我個評論贊   謝謝

0.png

全部資料51hei下載地址:
單相用電器分析監測裝置設計 CS5463.7z (4.49 MB, 下載次數: 374)

評分

參與人數 3黑幣 +136 收起 理由
piplxh + 30
andyhallo + 6 共享資料的黑幣獎勵!
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:282095 發表于 2019-8-29 08:43 | 顯示全部樓層
樓主名不符實啊
回復

使用道具 舉報

ID:602704 發表于 2019-9-24 11:21 | 顯示全部樓層

你這是褒義詞還是貶義詞啊
回復

使用道具 舉報

ID:440960 發表于 2020-4-16 20:45 | 顯示全部樓層
樓主太強了
回復

使用道具 舉報

ID:230915 發表于 2020-12-15 08:29 | 顯示全部樓層
謝謝分享!!資料相當好。
回復

使用道具 舉報

ID:902022 發表于 2021-4-8 22:17 | 顯示全部樓層
學長,麻煩看到聯系一下我,幫我添加視在、無功、有功功率的程序段唄
回復

使用道具 舉報

ID:904473 發表于 2021-4-16 12:56 | 顯示全部樓層
你好,請問protues里面沒有的元件怎么辦呢?比如各種電能計量芯片
回復

使用道具 舉報

ID:59830 發表于 2021-11-5 18:29 | 顯示全部樓層
市電產品不多,參考學習一下.
回復

使用道具 舉報

ID:405840 發表于 2021-11-6 18:22 | 顯示全部樓層
感謝樓主分享 21年電賽正好能用上]
回復

使用道具 舉報

ID:1004160 發表于 2023-10-25 11:44 | 顯示全部樓層
牛啊,希望樓主能看到,幾年前的帖子還能發現這種寶貝。我最近被電壓、電流檢測折磨死了。 用ACS712測電流,輸出的是交流電壓,給到PCF8591后好像不可以。8591好像只認直流電壓,沒辦法用低通濾波將ACS712輸出的交流電壓轉成直流電壓,再給到8591,這樣算出來,最后把低通濾波二極管降壓的部分給反加回去,這樣是不是有點兒弱?不過,稍有些誤差(1A以內誤差大)。
回復

使用道具 舉報

ID:978743 發表于 2024-5-15 12:14 | 顯示全部樓層
計算電壓比例和電流是怎樣求的
回復

使用道具 舉報

ID:978743 發表于 2024-5-15 13:08 | 顯示全部樓層
好厲害,這個 計算電壓比例和電流比例為啥是這樣的,我不太懂,220V*250mv/110mv=500V
回復

使用道具 舉報

ID:206695 發表于 2024-11-28 13:59 | 顯示全部樓層
感謝能用上
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲最新网址 | 一级毛片在线看 | 国精产品一区一区三区免费完 | 精品91久久久 | 精品国产一区二区在线 | 成人教育av| 黄色网址在线免费观看 | 国产精品国产精品国产专区不片 | 欧美日韩成人在线观看 | 成人在线视频一区 | 欧美片网站免费 | 亚洲一区二区三区免费视频 | 中文字幕精品一区二区三区精品 | 91精品国产综合久久久久 | 国产免费又色又爽又黄在线观看 | 久久久久99| 久久精品在线 | 97人人澡人人爽91综合色 | 久久精品免费一区二区三 | 一区二区三区四区视频 | 欧美美乳 | 欧美精品福利 | 成人国产精品色哟哟 | 欧美精品欧美精品系列 | 日韩精品在线视频免费观看 | 欧美综合自拍 | 成人午夜在线 | 久久国产欧美日韩精品 | 精品久久久久久亚洲精品 | 伊人春色成人网 | 国产精品久久久久一区二区三区 | 国产一级片一区二区三区 | 亚洲三区在线观看 | 亚洲高清成人 | www.黄色片视频 | 三级av网址 | 成人国产精品久久久 | 新超碰97| 欧美黄色片 | 日韩成人中文字幕 | 91性高湖久久久久久久久_久久99 |