单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:8280|回复:11
打印上一主题下一主题

单片机+CS5463单相用电器分析监测装置程序+电路设计与制作

 [复制链接]
跳转到指定楼层
楼主
ID:602704发表于 2019-8-28 15:45|只看该作者回帖奖励
大家好:

       这是我第二天在51黑电子论坛的知识海洋里与各位共师兄习和探讨,做了一个单相用电器分析监测装置,希望哪里有需要完善的地方请各位多多赐教。
       话不多说上图


1,实物照片



2,测试数据照片




3,原理图及PCB文件







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. …………
复制代码

  最后,如果这个设计对你有所帮助请给我个评论赞   谢谢



全部资料51hei下载地址:
单相用电器分析监测装置设计 CS5463.7z(4.49 MB, 下载次数: 350)

评分

黑币 +106
收起理由
+ 6
共享资料的黑币奖励!
+ 100
共享资料的黑币奖励!

查看全部评分

沙发
ID:282095发表于 2019-8-29 08:43|只看该作者
楼主名不符实啊
板凳
ID:602704发表于 2019-9-24 11:21|只看该作者

你这是褒义词还是贬义词啊
地板
ID:440960发表于 2020-4-16 20:45|只看该作者
楼主太强了
5#
ID:230915发表于 2020-12-15 08:29|只看该作者
谢谢分享!!资料相当好。
6#
ID:902022发表于 2021-4-8 22:17|只看该作者
学长,麻烦看到联系一下我,帮我添加视在、无功、有功功率的程序段呗
7#
ID:904473发表于 2021-4-16 12:56|只看该作者
你好,请问protues里面没有的元件怎么办呢?比如各种电能计量芯片
8#
ID:59830发表于 2021-11-5 18:29|只看该作者
市电产品不多,参考学习一下.
9#
ID:405840发表于 2021-11-6 18:22|只看该作者
感谢楼主分享 21年电赛正好能用上]
10#
ID:1004160发表于 2023-10-25 11:44|只看该作者
牛啊,希望楼主能看到,几年前的帖子还能发现这种宝贝。我最近被电压、电流检测折磨死了。 用ACS712测电流,输出的是交流电压,给到PCF8591后好像不可以。8591好像只认直流电压,没办法用低通滤波将ACS712输出的交流电压转成直流电压,再给到8591,这样算出来,最后把低通滤波二极管降压的部分给反加回去,这样是不是有点儿弱?不过,稍有些误差(1A以内误差大)。
11#
ID:978743发表于 2024-5-15 12:14|只看该作者
计算电压比例和电流是怎样求的
12#
ID:978743发表于 2024-5-15 13:08|只看该作者
好厉害,这个 计算电压比例和电流比例为啥是这样的,我不太懂,220V*250mv/110mv=500V

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网