打印
[万用表]

ATT7022校表遇到问题,绕了一大圈才发现的低级错误

[复制链接]
4856|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dcxq13|  楼主 | 2017-2-10 09:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dcxq13 于 2017-4-18 13:13 编辑

最近在用ATT7022C做一款三相电流表,校表遇到问题。
1.使用校表值为0,读出电压值为320V,实际电压输入值为220V,按照数据手册计算
220/320=0.6875然后再减去1等于-0.3125,因为是小于0所以按照手册要求要乘2的23次方加上2的24次方最好算出校表值为14155776
写入以后重新读取电压值还是显示320,查找不出是为什么!
2.我的ADC增益寄存器值为0,按照手册那就是没有打开增益。
3.我往电压校正寄存器里面写入其他值,读出值会产生变化,照理说校表应该是有写进去了。
下面附上电压采集电路  和我的驱动程序
/**************************写ATT7022********************/
void WR_ATT7022(u8 reg_addr,u32 wr_data)
{
        u8   i;
        ATT7022_CS=1;
        ATT7022_SCLK=0;
        reg_addr|=0x80;                        //最高位写1表示写命令
        ATT7022_CS=0;
        for(i=0;i<8;i++)                          //写入命令字
        {
                ATT7022_SCLK=1;
                if(reg_addr&0x80)ATT7022_DIN=1;
                else  ATT7022_DIN=0;
                reg_addr<<=1;
                ATT7022_SCLK=0;
        }
        for(i=0;i<24;i++)                        //写入数据
        {
                ATT7022_SCLK=1;
                if(wr_data&0x80)ATT7022_DIN=1;
                else  ATT7022_DIN=0;
                wr_data<<=1;
                ATT7022_SCLK=0;                //Delay5us();
        }
        ATT7022_CS=1;
}
/*********************初始化ATT7022*********************/
void ATT7022_Init()
{
        ATT7022_REST=0;
        delay_ms(20);
        ATT7022_REST=1;
        ATT7022_CS=1;
        ATT7022_SCLK=1;
        ATT7022_DIN=1;
        ATT7022_DOUT=1;
        delay_s(1);
}
/**************************读ATT7022********************/
u32 RD_ATT7022(u8 reg_addr)
{
        u8   i;
        u32 att7022_rdbuf;     //数据读取缓存
        att7022_rdbuf=0;
        ATT7022_CS=1;
        ATT7022_SCLK=0;
        reg_addr&= 0x7f;       //最高位写0表示读命令
        ATT7022_CS=0;
        for(i=0;i<8;i++)                       //写入命令字
        {
                ATT7022_SCLK=1;
                if(reg_addr&0x80)ATT7022_DIN=1;
                else  ATT7022_DIN=0;
                reg_addr<<=1;
                ATT7022_SCLK=0;
        }
        ATT7022_SCLK=0;
        Delay5us();
        for(i=0;i<24;i++)                     //存储数字
        {
                ATT7022_SCLK=1;
                att7022_rdbuf<<=1;
                if(ATT7022_DOUT)att7022_rdbuf=att7022_rdbuf|0x01;
                ATT7022_SCLK=0;
        }
        ATT7022_CS=1;
        return att7022_rdbuf;
}
/********************读取三相参数值**********************/
void RD_ATT7022_Three_Phrase_Dat()            //芯片数据读出后根据计算公式进行换算
{
        //float a,b,c,d;
        u32 value_tmp;
        u32 toal_value;
        if(Protection_Work_State==Protection_Failure)return;
        value_tmp=RD_ATT7022(r_Pt);
        if(value_tmp>8388608)value_tmp=value_tmp-16777216;
        value_tmp=(value_tmp/256);                //2的(23-17)次方2的6次方64
        T_phrase_Pt=(u16)value_tmp;                //合相有功功率

        value_tmp=RD_ATT7022(r_St);
        if(value_tmp>8388608)value_tmp=value_tmp-16777216;
        value_tmp=(value_tmp/64)*100;
    T_phrase_St=(u16)value_tmp;                        //合相视在功率
        
        toal_value=0;
        value_tmp=(RD_ATT7022(r_URmsa)/8192.0);        //读各相电压有效值,除以2的13次方
        A_phrase.r_UR=(u32)value_tmp;
        toal_value=value_tmp;

        value_tmp=(RD_ATT7022(r_URmsb)/8192.0);
        B_phrase.r_UR=(u32)value_tmp;
        toal_value=toal_value+(value_tmp);

        value_tmp=(RD_ATT7022(r_URmsc)/8192.0);
        C_phrase.r_UR=(u32)value_tmp;
        toal_value=toal_value+(value_tmp);

        toal_value=toal_value/3;
        T_phrase.r_UR=(u32)toal_value;

        value_tmp=((RD_ATT7022(r_IRmsa)&0x7fffff)/8192.00*0.05)*10;       //读取各相电流有效值
        A_phrase.r_IR=(u32)value_tmp;
        toal_value=value_tmp;
        //a=value_tmp;

        value_tmp=((RD_ATT7022(r_IRmsb)&0x7fffff)/8192.00*0.05)*10;
        B_phrase.r_IR=(u32)value_tmp;
        toal_value=toal_value+(value_tmp);
        //b=value_tmp;

        value_tmp=((RD_ATT7022(r_IRmsc)&0x7fffff)/8192.00*0.05)*10;
        C_phrase.r_IR=(u32)value_tmp;
        
        value_tmp=((RD_ATT7022(r_IRmst)&0x7fffff)/8192.00*0.05)*10;
        
        T_phrase.r_IR=(u32)(value_tmp/3);
        
//        T_phrase.r_IR=(u32)toal_value;
//        c=value_tmp;
//        
//toal_value=toal_value+(value_tmp);
//        toal_value=toal_value/3;
        
        value_tmp=RD_ATT7022(r_Pft);          //读取合相功率因数
        if(value_tmp>8388608)value_tmp=value_tmp-16777216;
        value_tmp=(value_tmp/8388608);
        T_phrase_Ptf=(u16)value_tmp;        
        
        value_tmp=RD_ATT7022(r_Freq);      //读取电网工作频率
        T_Phrase_Freq=(u16)(value_tmp/8192);

        value_tmp=RD_ATT7022(r_Ept);        //读取合相有功电能
        T_Phrase_Ep=(u16)value_tmp;
        
        value_tmp=RD_ATT7022(0x3f);//读漏电流
        Leak_Current_Value=(u16)value_tmp;
        
}

void ATT7022_CLR()                       //清除校表数据
{
        u8   i;

        WR_ATT7022(0xc3,0x000000);            //清除软件数据
        WR_ATT7022(0xc9,0x000000);            //较表数据写使能
        WR_ATT7022(0x20,0x000022);            //写入脉冲常数3200
        WR_ATT7022(0x1e,0x000000);            //比差补偿区域设置
        WR_ATT7022(0x02,0x000000);            //相位补偿区域设置1
        WR_ATT7022(0x03,0x000000);            //相位补偿区域设置2
        WR_ATT7022(0x04,0x000000);            //相位补偿区域设置3
        WR_ATT7022(0x05,0x000000);            //相位补偿区域设置4

        WR_ATT7022(0x2A,0x000000);            //设置合相能量叠加模式

        WR_ATT7022(0x86,0x000000);            //A相功率增益0
        WR_ATT7022(0x89,0x000000);            //A相功率增益1
        WR_ATT7022(0x87,0x000000);            //B相功率增益0
        WR_ATT7022(0x8A,0x000000);            //B相功率增益1
        WR_ATT7022(0x88,0x000000);            //C相功率增益
        WR_ATT7022(0x8B,0x000000);            //0相功率增益1

        for(i=0x0c;i<0x1a;i++)WR_ATT7022(i,0x000000);//区域相位校正

        WR_ATT7022(0x1B,14155776);   //三相电压校正
        WR_ATT7022(0x1C,0x000000);
        WR_ATT7022(0x1D,0x000000);

        WR_ATT7022(0x26,0x000000);  //三相电流校正
        WR_ATT7022(0x27,0x000000);
        WR_ATT7022(0x28,0x000000);

        WR_ATT7022(0x3f,0x000000);
        WR_ATT7022(0x2c,0x000000);  //第七路ADC使能
        //        WR_ATT7022(0xb0,0x5678);  //电路相序检测使能
        //        WR_ATT7022(0xae,0x3584);

        WR_ATT7022(0xc9,0x000001); //关闭校表使能
        WR_ATT7022(0xc6,0x000011);          //读电参数使能
}


求大神指教,到底是软件的问题还是硬件的问题,帮我解决了话,我有重谢!

QQ截图20170210095320.png (46.73 KB )

att7022采集电路

att7022采集电路

QQ截图20170210093026.png (61.81 KB )

ATT7022主控电路

ATT7022主控电路

相关帖子

沙发
dcxq13|  楼主 | 2017-2-11 13:18 | 只看该作者
本帖最后由 dcxq13 于 2017-2-11 13:21 编辑

早上又折腾了一早上,经过测试感觉问题还是出在了 SPI的写操作问题上面,通过程序试着读0x2d和0x2e这两个寄存器的值,这两个寄存器的作用就是能保存上次SPI写入的数据发现结果并不等于上次写入的值,比如我向某个地址写入了0X00005A,而这两个寄存器读出的结果都是0x5a0000,,这就说明我的SPI数据写入并没有成功,让我不经怀疑是不是我程序的数据位发送顺序错了,但是查验手册之后我很确定自己是按照最高位开始发送数据的,并没有错误啊,这很奇怪,这也许是导致我电压校正值写入之后无法校正电压值的原因,而后我又测试了SPI的读操作,读取电压寄存器的值是0x0001ec,在读出保存上次SPI读出结果的寄存器0x28,这个寄存器的值也是0x0001ec,由此我判断我的SPI读操作程序应该是没有问题的,问题还是应该出现在了SPI的写操作上面,我接下来使用逻辑分析仪来检查下我的猜测。
我的帖子最近会不断的更新,记录我在使用这款芯片的时候面临的问题,和解决的过程,希望各位大神看到能给小弟指正,本人算是刚刚入门级的开发者,经验不足,渴望和各位前辈多多沟通多多交流!

使用特权

评论回复
板凳
dcxq13|  楼主 | 2017-2-12 13:36 | 只看该作者
昨天下午用逻辑分析仪看了下SPI通讯过程,终于找到了原因所在,if(wr_data&0x80)ATT7022_DIN=1;这句应该改为if(wr_data&0x800000)ATT7022_DIN=1;这样写入的数据就对了,电压电流的校正已经成功,其他参数校正下一步即将继续。

使用特权

评论回复
评分
参与人数 1威望 +6 收起 理由
dirtwillfly + 6 能者自答,很给力!
地板
dcxq13|  楼主 | 2017-2-12 13:37 | 只看该作者
本帖最后由 dcxq13 于 2017-2-12 13:40 编辑

希望各位吸取我的教训,不要犯我的低级错误。写这段代码时候我受到前面写入命令字的影响,没有考虑到这是一个24位的数据,误当成8位数据写入,造成了实际数据的高8位数据,而引发了一连串的错误,同时真的感受到了逻辑分析仪在实际开发中的好处,是个好帮手!

使用特权

评论回复
5
souching| | 2017-2-17 11:40 | 只看该作者
写得不错哦.
面对新事物我也经常犯低级错误,由于太多不熟悉的内容,所以查问题是挺让人抓狂的

使用特权

评论回复
6
ningling_21| | 2017-2-17 14:20 | 只看该作者
dcxq13 发表于 2017-2-12 13:37
希望各位吸取我的教训,不要犯我的低级错误。写这段代码时候我受到前面写入命令字的影响,没有考虑到这是一 ...

谢谢楼主分享

使用特权

评论回复
7
l10618| | 2017-2-23 13:14 | 只看该作者
WR_ATT7022(0x86,0x000000);            //A相功率增益0
        WR_ATT7022(0x89,0x000000);            //A相功率增益1
        WR_ATT7022(0x87,0x000000);            //B相功率增益0
        WR_ATT7022(0x8A,0x000000);            //B相功率增益1
        WR_ATT7022(0x88,0x000000);            //C相功率增益
        WR_ATT7022(0x8B,0x000000);            //0相功率增益1
这几个地址对吗?手册里不是0x06开始的吗

使用特权

评论回复
8
ningling_21| | 2017-2-23 18:21 | 只看该作者
l10618 发表于 2017-2-23 13:14
WR_ATT7022(0x86,0x000000);            //A相功率增益0
        WR_ATT7022(0x89,0x000000);            / ...

按照手册操作即可

使用特权

评论回复
9
dirtwillfly| | 2017-2-25 11:25 | 只看该作者

使用特权

评论回复
10
dcxq13|  楼主 | 2017-4-18 13:12 | 只看该作者
l10618 发表于 2017-2-23 13:14
WR_ATT7022(0x86,0x000000);            //A相功率增益0
        WR_ATT7022(0x89,0x000000);            / ...

抱歉,最近忙别的项目没有过来看,这个是我的参数校正程序,按照手册要求写命令最高位要置1,所以这是置1之后的值,减去0x80就是原来的值了

使用特权

评论回复
11
renegade1123| | 2017-7-11 16:56 | 只看该作者
最近也在做这个项目,先看看。

使用特权

评论回复
12
yangzhen1001| | 2021-3-10 11:14 | 只看该作者
有用,刚接触这个芯片

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

42

帖子

2

粉丝