搜索
bottom↓
回复: 29

交流电参数测量 之 CS5460A程序实例【恢复】

[复制链接]

出0入0汤圆

发表于 2008-10-8 15:21:21 | 显示全部楼层 |阅读模式
    在OURAVR潜水一年多,学到了很多东西。下面发布一个自己一个作品中部分程序,希望能给有需要的朋友一些帮助。由于水平有限,程序可能写得不是非常漂亮,望众大侠包涵啦。也希望阿莫能给我加分啦。    还要说明的是,为提高编程效率,程序中利用了avrlib函数库。    使用中也发现了一些问题,希望高手们指教:执行完偏置寄存器校准和增益寄存器校准后,将得到的24位AD值按手册上的方法处理后仍得不到实际值。但是该值与实际值有很好的线性关系,因此我就是利用这一线性关系,进行线性拟合,得到最终结果。    下面直接贴一些程序段出来SHOW一下:/*--------------------------------------------------------------------------------------------------------编译平台:winavr2007MCU:ATMEGA32作者:张子佑时间:2008年10月8日功能:运用CS5460A测量交流电压、电流有效值。根据实际需要,还可以测量能量,电压、电流瞬时值。功率因素也可通过计算获得。-----------------------------------------------------------------------------------------------------------*///----------------------------------------------------------------#include<util/delay.h>#include "avrlib/global.h"#include "avrlib/rprintf.h"#include "avrlib/ks0108.h"#include "avrlib/glcd.h"#include "ks0108conf.h"#include "avrlib/timer.h"//--------CS5460 CODE ----------------------------/*CS5460内部寄存器的低六位*/#define CONFIG            0x00  //配置寄存器#define CYCLE_COUNT       0x0A  //周期计数 #define LAST_CURRENT      0x0E  //上一次电流值#define LAST_VOLT         0x10  //上一次电压值#define LAST_POWER        0x12  //上一次的功率值#define LAST_ENERGY       0x14  //上一周期的总能量值#define LAST_CURRENT_RMS  0x16  //上一周期电流有效值#define LAST_VOLT_RMS     0x18  //上一周期电压有效值#define STATUS            0x1E  //状态寄存器#define MASK              0x34  //中断屏蔽寄存器#define VOLT_DC_OFFSET    0X06  //电压通道 直流 偏置寄存器#define CURRENT_DC_OFFSET 0X02  //电流通道 直流 偏置寄存器#define VOLT_AC_OFFSET    0X22  //电压通道 交流 偏置寄存器#define CURRENT_AC_OFFSET 0X20  //电流通道 交流 偏置寄存器/*直流偏置(已校准)*/#define CURRENT_DC      0xCC4ADD //电压偏置   #define VOLT_DC         0X331396 //电流偏置/*寄存器的读写*/#define READ  0x00    //读#define WRITE 0x40    //写/*各寄存器复位后的初始值*/#define CONFIG_INIT      0x000001   //配置寄存器#define STATUS_INIT      0x000001   //状态寄存器#define MASK_INIT        0x000000   //中断屏蔽寄存器#define CYCLE_COUNT_INIT 0x000FA0   //周期计数寄存器/*定义以上寄存器的初始化后的值*/#define  CONFIG_DATA      0x0010E1  //软件复位#define  CALCULATE_DOWN   0x800000  //数据已经就绪,转换结束#define  LOW_POWER        0x000004  //检测到低电源#define  WDT              0X000020  //能量超过5秒未被读取,该位置位 /*定义其他命令*/#define  POWER_OFF_CTRL  0X88  //掉电控制#define  STANDERED_CTRL  0XC0  //标准控制#define  TRANSFORM_START 0Xe8 //开始转换,执行连续计算周期/*定义端口与CS5460的连接*/#define  SDI_H()    PORTB |= _BV(1) #define  SDI_L()    PORTB &= ~BV(1)#define  SDO        ((PINB & _BV(4))==_BV(4))#define  EN_CS()    PORTB &= ~_BV(3)#define  UN_CS()    PORTB |= _BV(3)#define  SCLK_H() PORTB |= _BV(5)#define  SCLK_L() PORTB &= ~_BV(5)//--------全局变量定义-------------------------------------u08 buf[5];float CurrentRMS,VoltRMS,POWER,ENERGY, COS;//--------------函数声明----------------------------------------void Write_CS5460A(u08 *ptr,u08 n);void Read_CS5460A(u08 reg,u08 *ptr);//---------CS5460端口初始化---------------------void InitPort(void){        DDRB |= _BV(1)+_BV(3)+_BV(5);                PORTB &= ~_BV(4);        DDRB &= ~_BV(4);}//-------------CS5460 SPI读写-------------------------void Write_CS5460A(u08 *ptr,u08 n){  s08 i=0,j=0;  SCLK_L();    EN_CS();  for(j=n;j>=1;j--)  {        for(i=7;i>=0;i--)      {          SCLK_L();          if( ((*ptr)&(1<<i)) != 0 )                SDI_H();          else               SDI_L();      _delay_us(5);      SCLK_H();      _delay_us(5);      }      ptr++;   }//  if(j==0) UN_CS();}void Read_CS5460A(u08 reg,u08 *ptr){    s08 i,j;    EN_CS();    *ptr=reg;      Write_CS5460A(ptr,1);    ptr++;    SDI_H();    for(i=3;i>0;i--)    {        for(j=7;j>=0;j--)        {            SCLK_L();            _delay_us(5);                        if(SDO == 1)                *ptr |= (1<<j);            else                *ptr &= ~(1<<j);                        if(j==0)                SDI_L();            else                 SDI_H();                        _delay_us(5);            SCLK_H();            _delay_us(5);        }        ptr++;    }    UN_CS();}  void Clear_DRDY(void) {     buf[0]=0x5e;     buf[1]=0xff;     buf[2]=0xff;     buf[3]=0xff;     Write_CS5460A(buf,4);      }void Wait_DRDY_High(void) {      while(1)     {          Read_CS5460A(0x1e,buf);           if( (buf[1]&0x80) != 0 ) break;       } } //------------5460初始化-----------------------void Init5460(void){    _delay_ms(5);          buf[0]=0xff;            //SYNC1     buf[1]=0xff;            //SYNC1     buf[2]=0xff;            //SYNC1     buf[3]=0xfe;            //SYNC0     Write_CS5460A(buf,4);   // 3 1 1 0         buf[0]=0x40;             buf[1]=0x00;            //GI=1      buf[2]=0x10;              buf[3]=0x61;            //DCLK=MCLK/1,高通         Write_CS5460A(buf,4);   //写配置寄存器       /**************************************************/    buf[0]=WRITE|0x20;             buf[1]=0x3D;              buf[2]=0xC2;     buf[3]=0x5C;               Write_CS5460A(buf,4);   //电流 交流偏置 校准寄存器      buf[0]=WRITE|0x22;             buf[1]=0x1F;            buf[2]=0xBB;     buf[3]=0x65;                   Write_CS5460A(buf,4);   //电压 交流偏置 校准寄存器   /***************************/    buf[0]=WRITE|0x04;             buf[1]=0x29;              buf[2]=0x71;     buf[3]=0xCA;               Write_CS5460A(buf,4);     //电流增益校准寄存器**    buf[0]=WRITE|0x08;             buf[1]=0x40;                buf[2]=0x96;     buf[3]=0xD3;                   Write_CS5460A(buf,4);     //电压增益校准寄存器**    buf[0]=0x5e;              buf[1]=0xF0;     buf[2]=0x00;     buf[3]=0x00;     Write_CS5460A(buf,4);  //清除状态寄存器     buf[0]=0x74;                     buf[1]=0x80; //DRDY    buf[2]=0x00;     buf[3]=0x00;     Write_CS5460A(buf,4);   //写中断屏蔽寄存器           buf[0]=0x78;    buf[1]=0x00;    buf[2]=0x00;    buf[3]=0x00; //缺省值    Write_CS5460A(buf,4); //写控制寄存器    buf[0]=0x4c;    buf[1]=0x00;    buf[2]=0x34;    buf[3]=0x9C;    Write_CS5460A(buf,4); //写EOUT 脉冲输出寄存器        buf[0]=0x4A;    buf[1]=0x00;    buf[2]=0x01;           //每秒钟计算20 次,N=400     buf[3]=0x90;    Write_CS5460A(buf,4); //写CYCLE COUNT 寄存器            Read_CS5460A(0x1e,buf); //读状态寄存器    buf[0]=0X5E;    Write_CS5460A(buf,4); //写状态寄存器            buf[0]=0xe8;    Write_CS5460A(buf,1); //启动CS5460A}/*-------------------------------------------------------------------------功能:读交流电压寄存器,并对数据进行处理和校准,返回交流电压有效值。需根据实际测量范围调整。---------------------------------------------------------------------------*/double CS5460_GetVoltRMS(void){        float G=1.0/2.0,temp=0.0;    Read_CS5460A(READ|LAST_VOLT_RMS,buf);    for(u08 i=1;i<=3;i++)    {        for(s08 j=7;j>=0;j--)        {            if( (buf&(1<<j)) != 0 )                temp+=G;            G = G/2.0;        }    }        //软件校准    VoltRMS = 20*temp/0.6;         VoltRMS = VoltRMS*1.542*0.9864+0.332;        return VoltRMS;}        /*--------------------------------------------------------------------------------功能:读交流电流寄存器,并对数据进行处理和校准,返回交流电流有效值。需根据实际测量范围调整。-----------------------------------------------------------------------------------*/double CS5460_GetCurrentRMS(void){        float G=1.0/2.0,temp=0.0;                Read_CS5460A(READ|LAST_CURRENT_RMS,buf);    for(u08 i=1;i<=3;i++)    {        for(s08 j=7;j>=0;j--)        {            if( (buf&(1<<j)) != 0 )                temp+=G;            G = G/2.0;        }    }        //软件校准    CurrentRMS =7.8*temp/0.6 ;        CurrentRMS = 5.5203*CurrentRMS+0.0873;        return CurrentRMS;}//-----------软件滤波函数----------------------------------------------#define N 24#define         CS_VRMS  0#define  CS_IRMS  1double filter(u08 CS){   u08 count,i,j;   double value_buf[N],temp;   double  sum=0;   for  (count=0;count<N;count++)   {                if(CS==CS_VRMS)                        value_buf[count] = CS5460_GetVoltRMS();                else                         value_buf[count] = CS5460_GetCurrentRMS();   }   for (j=0;j<N-1;j++)   {      for (i=0;i<N-j-1;i++)      {         if ( value_buf>value_buf[i+1] )         {            temp = value_buf;            value_buf = value_buf[i+1];             value_buf[i+1] = temp;         }      }   }   for(count=4;count<N-4;count++)      sum += value_buf[count];   return (sum/(N-8));}int main (void){        double VRMS=0,VRMSNew=0;        double IRMS=0,IRMSNew=0;        glcdInit();        // send rprintf output to lcd display    rprintfInit(glcdWriteChar);        // perform basic functionality test        glcdSetAddress(4,LINE2);        rprintf("Welcome to george's");        glcdSetAddress(60,LINE4);        rprintf("workspace");        _delay_ms(1000);                glcdClearScreen();        glcdSetAddress(0,LINE1);        rprintf("VRMS=");        glcdSetAddress(0,LINE2);        rprintf("IRMS=");        glcdSetAddress(70,LINE1);        rprintf("(V)");        glcdSetAddress(70,LINE2);        rprintf("(A)");                InitPort();        Init5460();                while(1)        {                                VRMSNew = filter(CS_VRMS);                if( (VRMSNew-VRMS>0.03)||(VRMS-VRMSNew>0.03) )                {                        VRMS = VRMSNew;                }                                IRMSNew = filter(CS_IRMS);                if( (IRMSNew-IRMS>0.003)||(IRMS-IRMSNew>0.003) )                {                        IRMS=IRMSNew;                }                                glcdSetAddress(30,LINE1);                rprintfFloat(4,  VRMS);                glcdSetAddress(30,LINE2);                rprintfFloat(4,  IRMS);                _delay_ms(50);        }}点击此处下载 ourdev_443670.rar(文件大小:243K) (原文件名:CS5460A.rar) 

本贴被 georgezz007 编辑过,最后修改时间:2008-10-08,15:25:12.

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2008-10-8 15:40:20 | 显示全部楼层
我也在用5460,刚开始用,感觉国产跟进口的片子性能还是有差距,主要是零点偏移比较大,不进行校准不能用,进口的不进行校准零点输出还可以接受,毕竟差两块钱。

出0入0汤圆

 楼主| 发表于 2008-12-26 10:04:25 | 显示全部楼层
    自从发了这个帖子后,很多朋友通过QQ与我交流。    惭愧的是,由于本人水平的问题,许多问题也许没能给予较满意的答复。其实当初使用这块芯片时,没有全面的理解它,我只关注了我所需要的部分。    我对于CS5460的理解程度,只是了解到了:            1.其通信方法;            2.初始化及校准过程;            3.读相关寄存器以获取需要的结果。    我发此贴的目的,是在我实际做的时候,感觉芯片的初始化和校准过程比较繁琐,稍不注意可能通信方面就会出问题,所以分享一些我的实际经验,以供参考。    现在,我可能没太大机会再使用该芯片了。希望对于这块芯片使用上有问题的朋友今后加我QQ的时候要慎重,当然我也十分欢迎大家相互学习。但是说实话,我的QQ上人突然暴多起来,还是有些不便,希望体谅。

出0入0汤圆

发表于 2008-12-11 00:52:18 | 显示全部楼层

出0入0汤圆

发表于 2008-12-10 10:05:20 | 显示全部楼层
ding十分感谢

出0入0汤圆

发表于 2008-10-10 21:02:33 | 显示全部楼层
不错

出0入0汤圆

 楼主| 发表于 2008-10-10 20:57:10 | 显示全部楼层
只是做一个高功率因素电源(学生作品),加一个交流电参数测量是增加亮点。因为需要测功率因素,所以选择了这块芯片,顺便将交流电压和交流电流一起显示。希望拿到高分呀。

出0入0汤圆

发表于 2008-10-10 15:40:45 | 显示全部楼层
早就用CS5463了,LZ是做什么的?多功能表?配变?

出0入0汤圆

 楼主| 发表于 2008-10-10 15:31:00 | 显示全部楼层
我的QQ号是: 569536244

出0入0汤圆

发表于 2008-10-10 15:23:13 | 显示全部楼层
刚刚使用CS5460A,有好些不懂的地方,能不能请教楼主,能给个QQ或者MSN么,谢谢,或者您加我QQ973391979 等待您的消息,谢谢,很着急

出0入0汤圆

 楼主| 发表于 2008-10-9 10:01:57 | 显示全部楼层
查看一下它的数据手册就行了。这里有一些我编程时的参考资料。点击此处下载 ourdev_444710.rar(文件大小:913K) (原文件名:cs5460a资料.rar) 

出0入0汤圆

发表于 2008-10-9 09:17:29 | 显示全部楼层
好东西,有应用电路图吗?

出0入0汤圆

发表于 2008-10-9 08:36:16 | 显示全部楼层
记号

出0入0汤圆

发表于 2008-10-9 07:17:07 | 显示全部楼层
电能分析可以用炬力的片子,好像是7022,带谐波分析,估计够用了,我买的5460国产6元,进口8元,不含税。

出0入0汤圆

发表于 2008-10-9 00:27:16 | 显示全部楼层
含6个点的税不到10元,大概是八九元电能分析的不能够,只能够测量单相的大部分电参量

出0入0汤圆

发表于 2008-10-9 00:22:50 | 显示全部楼层
这东西大概多少钱一片?  电能分析是不是都用得他?

出0入0汤圆

 楼主| 发表于 2008-10-8 21:05:02 | 显示全部楼层
知道呀,但是没有试过。好像是要把内部的高通滤波器关掉,再进行直流增益校准过程。但是有一点,采样输入电压有限制,所以若当做24位的AD用恐怕不是很好。

出0入0汤圆

发表于 2008-10-8 18:05:43 | 显示全部楼层
顶一下,楼主知道5460 能测直流电压电流吗?

本贴被 thoro_avr 编辑过,最后修改时间:2008-10-08,18:05:57.

出0入0汤圆

发表于 2009-5-26 19:01:53 | 显示全部楼层
版主能否将原理图一并发上来看看参考下?

出0入0汤圆

发表于 2010-1-22 17:23:15 | 显示全部楼层
楼主的程序中好象并没有校准操作啊~~~~~~~

出0入0汤圆

发表于 2010-2-2 14:45:11 | 显示全部楼层
这程序技术含量太高,调试2天未果,很是郁闷

出0入0汤圆

发表于 2010-7-13 11:25:26 | 显示全部楼层
请教楼主
数据处理部分
//软件校准
    VoltRMS = 20*temp/0.6;
        VoltRMS = VoltRMS*1.542*0.9864+0.332;
        return VoltRMS;
能解释下吗       感谢

另外   代码写的不错  赞一个

出0入0汤圆

 楼主| 发表于 2010-7-14 10:41:21 | 显示全部楼层
各位朋友,十分抱歉的告诉大家。小弟我已经不从事单片机方面的工作。平时因为工作繁忙,很多朋友通过qq向我询问有关问题都无法进行答复,希望见谅。

出0入0汤圆

发表于 2010-8-20 12:05:44 | 显示全部楼层
天啊!看看大家把楼主逼的。。。

出0入0汤圆

发表于 2011-2-24 15:44:32 | 显示全部楼层
cs5460A   电流输入端  下限能能测到多少mV

出0入0汤圆

发表于 2011-2-24 20:07:53 | 显示全部楼层
请教楼主
数据处理部分
//软件校准
    VoltRMS = 20*temp/0.6;  
VoltRMS = VoltRMS*1.542*0.9864+0.332;
return VoltRMS;
能解释下吗       感谢

另外   代码写的不错  赞一个

出0入0汤圆

发表于 2011-5-7 22:02:05 | 显示全部楼层
taobao上有现成的方案,对于做产品会,节约很多时间与精力.http://shop59944437.taobao.com/

出0入0汤圆

发表于 2011-8-1 13:28:19 | 显示全部楼层
谁帮帮我,cs5460读不出数据

出0入0汤圆

发表于 2011-8-4 12:04:47 | 显示全部楼层
谁能告诉我读的数据怎么转换成实际值

出0入0汤圆

发表于 2012-11-2 12:49:52 | 显示全部楼层
qsm627421059 发表于 2011-8-4 12:04
谁能告诉我读的数据怎么转换成实际值

你好,你读出数据了吗?我这里还一直读不出数据,不知道为什么,能否请教下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表