[DSP编程] 利用dsp系列16位芯片跟ATT7022芯片的读取问题

[复制链接]
322|4
 楼主 | 2019-5-9 20:51 | 显示全部楼层 |阅读模式
我用的是dsp系列的16位单片机,利用ATT7022C进行采样,想通过ATT7022C读出电压、电流、功率因数等值,可是怎么都读不出来?

SPI通信,根据结果,可以看到读取0x00地址,返回0x7122A0 说明我的SPI通信是成功的,但是为什么读取A相电压有效值0x0d是空的,读取电流有效值0x10却又有一些很怪的数值。

这是我的代码

db_amme.c

#include "db_amme.h"
#include "delay.h"
#include "p30f4011.h"
#include "oled.h"
#include "font.h"
#include "bmp.h"
u32 CurrentElectric;        //总电量
//u32 CurrentElectricA;
//u32 CurrentElectricB;
//u32 CurrentElectricC;


#define HFCONST   369//((2.592 * ATT_G * ATT_G*10000*INATTV*INATTI)/(EC*UI*VI))
#define P_K    0.0259//2.592*pow(10,10) /(HFCONST *EC *pow(2,23))  0.01225 //0.965595/HFCONST//0.0025745

//float data0;
//float data1;

u32 Device_ID = 0;


u8 VoltageA = 0;   //A 相电压有效值

//u32 PA_Q = 0;  // A电量
float CurrentA = 0;         //A 相电流有效值
float  TempA = 0; //A 相功率因数
unsigned int Up_VolA = 0;
unsigned int Up_CurrentA = 0;
u32 Up_PA_Q = 0;
u32 Up_PA_Power = 0;
u32 Up_QA_Power = 0;


u8 VoltageB = 0;   //B 相电压有效值
//u32 PB_Q = 0;  // B电量
float CurrentB = 0;         //B 相电流有效值
float TempB = 0; //B 相功率因数


unsigned int Up_VolB = 0;
unsigned int Up_CurrentB = 0;
u32 Up_PB_Q = 0;
u32 Up_PB_Power = 0;
u32 Up_QB_Power = 0;


u8 VoltageC = 0;   //C 相电压有效值
//u32 PC_Q = 0;  // C电量
float CurrentC = 0;         //C 相电流有效值
float  TempC = 0; //C 相功率因数
unsigned int Up_VolC = 0;
unsigned int Up_CurrentC = 0;
u32 Up_PC_Q = 0;
u32 Up_PC_Power = 0;
u32 Up_QC_Power = 0;

u16 Huganqibeilv = 1;                             //互感器倍率

u32 EST_Q = 0;  // 新计量的合相电量
u32 EST_Q_buff;  // 之前的总合相电量
u8 SetGainData;
/*****************SPI GPIO 功能定义******************************/
void SPI_GPIO_Config(void)
{
    TRISFbits.TRISF0 = 0;  //SCLK
    TRISFbits.TRISF1 = 0;  //DIN
    TRISFbits.TRISF4 = 1;  //DOUT
    TRISFbits.TRISF5 = 0;  //L_CS
    TRISFbits.TRISF6 = 0;  //L_RST
}


/************************* READ_Att7022*************************************************/
u32 READ_Att7022(u8 Address)
{
        u8 i, bTemp;
        u32 dwData;
        unsigned long dwData1;
        SPI_CS_HIGH();
        SPI_CLK_LOW();
        SPI_CS_LOW();    // 开启SPI传输
        bTemp = 0x80;
        for(i=0; i<8; i++)   //Write the Address
        {
                SPI_CLK_HIGH();

                if(Address & bTemp)
{
                   SPI_DI_HIGH();
}
                else
                     SPI_DI_LOW();
//                bTemp >>= 1;
                bTemp = (bTemp>>1)&(0x7f);
delay_us(50) ;
                SPI_CLK_LOW();
delay_us(50) ;
        }
        delay_us(3);

        dwData = 0x00000000;//Read 24bit
        for(i=0; i<24; i++)
        {
//                dwData <<= 1;
                dwData = (dwData<<1)&(0xfffffffe);
                SPI_CLK_HIGH();
                delay_us(50);
               // Delay_us(3);
               //如果是高电平最低位或1
                if (RDSPIData)
                {
//                      dwData |= 1;
                      dwData = dwData | (0x00000001);
                }
                else
                        ;
    //        Delay_us(1);
                SPI_CLK_LOW();
                delay_us(50) ;
//        delay_us(1);
        }
        
        SPI_CS_HIGH();          //关闭SPI传输
        delay_us(2);
        return dwData;
}
/**************************Wr_Dat******************************/

void Write_Att7022(u8 Address, u32 dwData)
{
        u8 i, bTemp;
        unsigned long dwTemp;

        SPI_CS_HIGH();
        SPI_CLK_LOW();
        SPI_CS_LOW();         //开启SPI传输

        Address |= 0x80;//write最高位写1表示写命令
        bTemp = 0x80;
        for(i=0; i<8; i++)         //Write the Address
        {
               SPI_CLK_HIGH();
                if(Address & bTemp)
{
SPI_DI_HIGH();
}
                else
                     SPI_DI_LOW();
//                bTemp >>= 1;
                bTemp = (bTemp>>1)&(0x7f);
delay_us(1) ;
delay_us(50) ;
                SPI_CLK_LOW();
delay_us(1) ;
delay_us(50) ;
        }
        delay_us(3);

        dwTemp = 0x00800000;    //large integer implicitly truncated to unsigned type
        for(i=0; i<24; i++)  //Write Data
        {
                if(dwData & dwTemp)
                {
                    SPI_DI_HIGH();
                }
                else
                     SPI_DI_LOW();
                SPI_CLK_HIGH();
                delay_us(1);
                delay_us(50) ;
                SPI_CLK_LOW();
delay_us(1);
delay_us(50) ;
dwTemp = ((dwTemp>>1)&0x00ffffff);//移位确保是0
        }
        
        SPI_CS_HIGH();            //结束传输
        delay_us(2);
}
void EMU_init(void)
{

Write_Att7022(0xD3,0x0000);//rest
delay_us(2);
Write_Att7022(0xC3,0x000000);  //清除校表数据
Write_Att7022(0xc9,0x00005A);  //使能校表

//Wr_Dat(0xC5,0x000000); //关闭同步
Write_Att7022(0x01,0xB97E);  //配置模式寄存器
Write_Att7022(0x03,0xF884); //EMUcfg   读后清零         0xF884   和功率有关
Write_Att7022(0x02,0x0200);           //电流增益1  电压8
//**//        Write_Att7022(0x02,0x0000);           //各路adc增益为1

//   Write_Att7022(0x30,0x0000); // 关闭所有中断
Write_Att7022(0x31,0x3437); //模拟模块寄存器
Write_Att7022(0x6D, 0xFF00);                //Vrefgain 的补偿曲线系数TCcoffA ,TCcoffB ,TCcoffC(0x6D~0x6F)
Write_Att7022(0x6E, 0x0DB8);                //Vrefgain 的补偿曲线系数TCcoffA ,TCcoffB ,TCcoffC(0x6D~0x6F)
Write_Att7022(0x6F, 0xD1DA);                //Vrefgain 的补偿曲线系数TCcoffA ,TCcoffB ,TCcoffC(0x6D~0x6F)
Write_Att7022(0x1E,HFCONST); // HFconst 3200  109       


Write_Att7022(0x17,(int)(0.98*32768));         //A相电压增益校准
Write_Att7022(0x18,(int)(0.98*32768));  //B 相电压增益校准
Write_Att7022(0x19,(int)(0.98*32768));  //C 相电压增益校准

Write_Att7022(0x1A,1.918*32768); //A相电流增益 校准       
Write_Att7022(0x1B,1.918*32768); //B相电流增益 校准       
Write_Att7022(0x1C,1.908*32768); //C相电流增益 校准

Write_Att7022(0x04,1.442*32768); //A有功率增益 校准   
Write_Att7022(0x07,1.442*32768); //A无功率增益 校准
Write_Att7022(0x0A,1.442*32768);        //A视在功率增益 校准

Write_Att7022(0x05,1.442*32768); //B有功率增益 校准       
Write_Att7022(0x08,1.442*32768); //B无功率增益 校准
Write_Att7022(0x0B,1.442*32768);        //B视在功率增益 校准

Write_Att7022(0x06,1.43*32768); //C有功率增益 校准
Write_Att7022(0x09,1.43*32768); //C无功率增益 校准1.378*(pow(2,15))
Write_Att7022(0x0C,1.43*32768);//C视在功率增益 校准   1.378*(pow(2,15)

Write_Att7022(0x35,0x080F);           //   I/O
Write_Att7022(0xC5,0x0002);        ///打开同步
Write_Att7022(0xc9,0x000000);         //Close the write protection
Write_Att7022(0xC6,0x0000) ;           //打开计量寄存器数据
        Device_ID = READ_Att7022(0x00);          // Device ID
}

主函数
int main()
{
    disn(1,0,55);disn(2,0,69);disn(3,0,76);disn(4,0,67);disn(5,0,79);disn(6,0,77);disn(7,0,69);//Welcome

    SPI_GPIO_Config(); //管脚初始化
EMU_init();    // 电表初始化
READ_Att7022(0x00);          // Device ID
//        delay_us(100);
//        EMU_init();
//        delay_us(100);
delay_ms(50);

while(1)
{
            ;
//    ReadAmmeterData();
    unsigned long readData = 0;
unsigned long readDataUa = 0;
unsigned long readDataUat = 0;
    readDataUa = READ_Att7022(0x0d); //Adianya
    delay_ms(50);
    readDataUat = READ_Att7022(0x32);//A caiyangdianya
    delay_ms(50);
    READ_Att7022(0x2F);
    delay_ms(50);
     }
}
}

使用特权

评论回复
| 2019-5-9 22:30 | 显示全部楼层
DSP都是32位的吧     DSP接口速度比较快  建议将速度降低一些看看

使用特权

评论回复
 楼主 | 2019-5-10 13:01 | 显示全部楼层
zhangmangui 发表于 2019-5-9 22:30
DSP都是32位的吧     DSP接口速度比较快  建议将速度降低一些看看

我用的是模拟SPI的方式,延时已经加了蛮多了,50us的延时,问题是我发送0x00可以看到 dout的回应,看电流寄存器也有数值,所以我在考虑是哪里设置,初始化之类的没有设置好

使用特权

评论回复
| 2019-5-10 23:51 | 显示全部楼层
礁是海的伤疤 发表于 2019-5-10 13:01
我用的是模拟SPI的方式,延时已经加了蛮多了,50us的延时,问题是我发送0x00可以看到 dout的回应,看电流 ...

那就还是寄存器操作不太对   你早找找问题  抓一下时序

使用特权

评论回复
 楼主 | 2019-5-14 12:02 | 显示全部楼层
感谢,问题解决了,读取数据的SPI通信没有问题,但是写数据的SPI是有问题的,写数据的发送,先发送地址,再发送数据,我想利用unsigned long类型,做对应与运算取出对应的字节,一次发送24bit数据,但是我用的这个4011单片机不支持我的写法,改成我先把发送的数据24bit分割成3个8bit,然后分开发送,就成功了。
初始化这块是没有问题的,对读取到的寄存器存储数值做进制转换就得到真实的有效值了。
看过了很多的帖子和用法,最终还是在官网的应用心得里得到了启发。

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /2 下一条

在线客服 快速回复 返回顶部 返回列表