coolala584520 发表于 2011-3-31 17:35:41

ADE7758读不到电压数据!!!

我用LPC2378的SSP接口控制ADE7758,SSP配置为SPI帧格式,读8位寄存器的默认值都是正确的,如:操作模式,测量模式等寄存器。可是读16位或24位的寄存器时,出来的数据不对,如:过零超时寄存器(16 bit)、周期循环寄存器(16 bit),默认值都是0xfff,可读出来就是0xff。对于电压有效值寄存器,读出来的数都小于255,一会一个样,没有规律,请大虾们帮忙分析一下是什么问题!谢谢!

代码如下:

/*
*******************************************************************************
**函数名称:                void SSP1_Init( void )                     **
**函数描述:        SSP1接口初始化程序,SSP1用作SPI主机                  **
**参    数:                无                                        **
**返    回:                无                                      **
*******************************************************************************
*/
void SSP1_Init( void )
{

    PCONP   |= (1 << 10);                       // 在外设功率控制寄存器里使能SSP外设1,默认情况下,该外设已被使能.       
    // 初始化P0.7、P0.8、P0.9为SSP1接口引脚SCK1、MISO1、MOSI1
    PINSEL0 |=( (0x02 << 14) | (0x02 << 16) | (0x02 << 18) );   

    // SPI的位频率为:f=PCLK /(CPSDVSR×), PCLK=28.8M
    SSP1CR0= 0x0087;                     // 选择SPI帧格式,8位,CPOL=0,CPHA=1 (针对ADE7758时序),位速率为默认值. SCR=0x00;
    SSP1CR1= 0X02;                           // 设置SSP1为主机模式,不使用回写模式,并使能SSP1.
    SSP1CPSR = 0x80;                        // 设置SSP从PCLK获得的分频值,主模式下有效, CPSDVSR范围:2~254间的偶数.                                                          
}

/*
*******************************************************************************
**函数名称:                void SSP1_Send( uint8 data )                   **
**函数描述:        SSP1接口发送单字节函数                            **
**参    数:                data---待发送数据                             **
**返    回:                无                                  **
*******************************************************************************
*/
void SSP1_Send( uint8 data )
{
uint i;

    for(i=0;i<50000;i++)                                        // 防止死循环
            {
            if(SSP1SR & 0x01){break;}                                // 等待发送FIFO为空(TFE=1,FIFO为空; 原为TNF=1,0x02,FIFO不满.)
            }      
        SSP1DR = data;                                       // 发送数据
   
        for(i=0;i<50000;i++)                                        // 防止死循环
            {
            if( !(SSP1SR & 0x10) ){break;}                                 // 等待数据发送完成(BSY=0,不忙).
            }          
}

/*
*******************************************************************************
**函数名称:                uint8 SSP1_Recv( void )                   **
**函数描述:        SSP1接口接收单字节函数                          **
**参    数:                无                                            **
**返    回:                SSP1DR---接收到的数据                          **
*******************************************************************************
*/
uint8 SSP1_Recv( void )
{
uint i,data_temp;;

        for(i=0;i<50000;i++)                                        // 防止死循环
            {
            data_temp = SSP1DR;                                        // 首先清空接收FIFO.
       if(!(SSP1SR & 0x04)){break;}                                     // 等待接收FIFO为空(RNE=0,FIFO为空,没有数据).
            }   
        ////////
         SSP1DR = 0xff;                                        // 发送该数据用以产生时钟,数据本身没有用处!
        for(i=0;i<50000;i++)                                        // 防止死循环
            {
            if( !(SSP1SR & 0x10) ){break;}                                     // 等待数据发送完成(BSY=0,不忙).
            }
        for(i=0;i<50000;i++)                                        // 防止死循环
            {
            if(SSP1SR & 0x04){break;}                                // 等待接收FIFO不为空(RNE=1,FIFO不空,已接收到数据).
            }
        data_temp = SSP1DR;                                        // 读取接收FIFO中的数据.
        ////////
        for(i=0;i<50000;i++)                                        // 防止死循环
            {
            if(!(SSP1SR & 0x04)){break;}                                    // 等待接收FIFO为空(RNE=0,FIFO为空,读操作结束).
            }

        return (uint8)(data_temp);                                               // 返回接收到的数据.
}

/*
*******************************************************************************
**函数名称:                void ADE_IO_Init( void )                **
**函数描述:        初始化控制电量芯片的IO口                        **
**参    数:                无                                     **
**返    回:                无                               **
*******************************************************************************
*/
void ADE_IO_Init( void )
{
//引脚配置---CS1、CS2、CS3、CS4
        PINSEL3 &=0xFFFC03FF;                                                                                        //全局I/O初始化时已为0.故此处可省.
        FIO1DIR |=( CS1|CS2|CS3|CS4 );                                    //方向均设置为输出引脚.
   
//外部中断端口配置---IRQ1=P2.10、IRQ2=P2.11、IRQ3=P2.12、IRQ4=P2.13(EINT0、EINT1、EINT2、EINT3)
        /*
        PINSEL4 |=( (0x01<<20) | (0x01<<22) | (0x01<<24) | (0x01<<26) );    //均为0x01功能.            
        EXTMODE= 0x0f;                                                    //边沿触发.
        EXTPOLAR = 0x00;                                          //下降沿触发.               
        */
//所有CS置高(无效).
    ADE_CS1(1);
    ADE_CS2(1);
    ADE_CS3(1);
    ADE_CS4(1);
}

/*
*******************************************************************************
**函数名称: void ADE7758_WR( uint8 REG_ADDR,uint32 data,uint8 cnt )        **
**函数描述:ADE7758写操作                                             **
**参    数:        REG_ADDR---寄存器地址                                **
**          data-------待写入的数据                                        **
**          cnt--------寄存器宽度(字节数)                                  **
**返    回:        无                                        **
*******************************************************************************
*/
void ADE7758_WR( uint8 REG_ADDR,uint32 data,uint8 cnt )
{

SSP1_Send(REG_ADDR|0x80);       //写地址

switch(cnt)                     //写数据
    {
    case 1: SSP1_Send( (uint8)(data) );         //发送一个字节数据
            break;
    case 2: SSP1_Send( (uint8)(data>>8) );      //发送两个字节数据,高节字在前
       SSP1_Send( (uint8)(data) );
            break;
    case 3: SSP1_Send( (uint8)(data>>16) );   //发送三个字节数据,高节字在前
       SSP1_Send( (uint8)(data>>8) );
       SSP1_Send( (uint8)(data) );
            break;

    default:break;
    }
}

/*
*******************************************************************************
**函数名称: uint32 ADE7758_WR( uint8 REG_ADDR,uint8 cnt )                 **
**函数描述:ADE7758读操作                                            **
**参    数:        REG_ADDR---寄存器地址                               **
**          cnt--------寄存器宽度(字节数)                                 **
**返    回:        data-------寄存器的值                                  **
*******************************************************************************
*/
uint32 ADE7758_RD( uint8 REG_ADDR,uint8 cnt )
{
uint32 data;

SSP1_Send(REG_ADDR);                //读地址

switch(cnt)                         //读数据
    {
    case 1: data=SSP1_Recv();       //接收一个字节数据
            break;
    case 2: data=SSP1_Recv();       //接收两个字节数据,高节字在前
            data<<=8;
       data=SSP1_Recv();
            break;
    case 3: data=SSP1_Recv();       //接收三个字节数据,高节字在前
            data<<=8;
       data=SSP1_Recv();
       data<<=8;
            data=SSP1_Recv();
            break;

    default:break;
    }
return data;
}

/*
*******************************************************************************
**函数名称: void ADE7758_CFG( uint8 CSn )                                      **
**函数描述: ADE7758初始化程序                                             **
**参    数:        CSn--------芯片选择:选择4个芯片中的某一个(1,2,3,4).    **
**返    回:        无                                                     **
*******************************************************************************
*/
void ADE7758_CFG( uint8 CSn )
{
ADE_IO_Init();                      //IO口初始化

switch(CSn)                         //芯片选择
    {
    case 1: ADE_CS1(0); break;      //选择芯片1
    case 2: ADE_CS2(0); break;      //选择芯片2
    case 3: ADE_CS3(0); break;      //选择芯片3
    case 4: ADE_CS4(0); break;      //选择芯片4
    default:break;
    }
/////////////////////////////
//寄存器初始化配置代码
   
    ADE7758_WR(OPMODE,0x40,1);      //软件复位
    Delay(1000);                  //大于18us的延时

    ADE7758_WR(OPMODE,0x04,1);          //写操作模式寄存器          13H为0x04
    ADE7758_WR(LCYCMODE,0x78,1);    //写周期循模式寄存器      17H为0x78
    ADE7758_WR(GAIN,0x00,1);          //写PGA增益寄存器         23H为0x00

    ADE7758_WR(AVRMSGAIN,0x00,2);   //写相位A的电压增益寄存器   24H为0x00
    ADE7758_WR(BVRMSGAIN,0x00,2);   //写相位B的电压增益寄存器   25H为0x00
    ADE7758_WR(CVRMSGAIN,0x00,2);   //写相位C的电压增益寄存器   26H为0x00

    ADE7758_WR(AIGAIN,0x00,2);          //写相位A的电流增益寄存器   27H为0x00
    ADE7758_WR(BIGAIN,0x00,2);          //写相位B的电流增益寄存器   28H为0x00
    ADE7758_WR(CIGAIN,0x00,2);          //写相位C的电流增益寄存器   29H为0x00

    ADE7758_WR(AVRMSOS,0x00,2);          //写A相电压有效值校正寄存器 33H为0x00
    ADE7758_WR(BVRMSOS,0x00,2);          //写B相电压有效值校正寄存器 34H为0x00
    ADE7758_WR(CVRMSOS,0x00,2);          //写C相电压有效值校正寄存器 35H为0x00

    ADE7758_WR(AIRMSOS,0x00,2);          //写A相电流有效值校正寄存器 36H为0x00
    ADE7758_WR(BIRMSOS,0x00,2);          //写B相电流有效值校正寄存器 37H为0x00
    ADE7758_WR(CIRMSOS,0x00,2);          //写C相电流有效值校正寄存器 38H为0x00

    ADE7758_WR(APHCAL,0x00,1);          //写A相相位校准寄存器       3FH为0x00
    ADE7758_WR(BPHCAL,0x00,1);          //写B相相位校准寄存器       40H为0x00
    ADE7758_WR(CPHCAL,0x00,1);          //写C相相位校准寄存器       41H为0x00

/////////////////////////////
switch(CSn)                         //禁止使能芯片
    {
    case 1: ADE_CS1(1); break;      //禁止使能芯片1
    case 2: ADE_CS2(1); break;      //禁止使能芯片2
    case 3: ADE_CS3(1); break;      //禁止使能芯片3
    case 4: ADE_CS4(1); break;      //禁止使能芯片4
    default:break;                                          
    }
}

///////////////////////////////////主函数/////////////////////////////////////////////
void main()
{
uint32 j;

SSP1_Init();
ADE7758_CFG(4);

while(1)
        {
       
        ADE_CS4(0);
        /*
        j=ADE7758_RD(MMODE,1);
        UART_Printf(0,"---MMODE=0x%0x\n",j);
        j=ADE7758_RD(VERSION,1);
        UART_Printf(0,"---VERSION=0x%0x\n",j);
        j=ADE7758_RD(VPEAK,1);
        UART_Printf(0,"---VPEAK=0x%0x\n",j);
        */

        j=ADE7758_RD(ZXTOUT,2);
        UART_Printf(0,"---ZXTOUT=0x%0x\n",j);
        j=ADE7758_RD(LINECYC,2);
        UART_Printf(0,"---LINECYC=0x%0x\n",j);

        /*
        ADE_Va=ADE7758_RD(AVRMS,3);                        // A相电压
        UART_Printf(0,"---ADE_Va=%5d",ADE_Va);
        ADE_Vb=ADE7758_RD(BVRMS,3);                        // B相电压
        UART_Printf(0,"---ADE_Vb=%5d",ADE_Vb);
        ADE_Vc=ADE7758_RD(CVRMS,3);                        // C相电压
        UART_Printf(0,"---ADE_Vc=%5d",ADE_Vc);
        ADE_freq=ADE7758_RD(FREQ,2);                        // 频率
        UART_Printf(0,"---ADE_f=%5d\n",ADE_freq);
        */
        Delay_MS(10);
        ADE_CS4(1);
         }

}

注:我的板子上有4片ADE7758,我现在只调试第4片,其他3片全断开SPI总线了!

coolala584520 发表于 2011-3-31 17:57:10

问题已解决!

在ADE7758_RD()函数中,接收字节处漏了一个“或”!

coolala584520 发表于 2011-3-31 17:57:26

问题已解决!

在ADE7758_RD()函数中,接收字节处漏了一个“或”!

CK345 发表于 2012-6-4 08:58:11

coolala584520 发表于 2011-3-31 17:57 static/image/common/back.gif
问题已解决!

在ADE7758_RD()函数中,接收字节处漏了一个“或”!

哥么,能把工程包给我一下吗

314296761 发表于 2012-6-11 15:55:41

你好在吗?
你的那个ADE7758读取在哪里加“或”
不是太懂。
忘不吝赐教。呵呵

richwen 发表于 2012-12-24 12:33:08

MARK!{:smile:}

huaer2012ibm 发表于 2013-2-19 16:58:42

你好,在了吗,我想向你请教一下ADE7758的程序书写,我用的stm32f103VET6的片子,我是新手,不怎么写过程序,可以把你的工程分享给我一份吗?非常感谢邮箱qp20081001@gmail.com

Mr.luke2012 发表于 2013-4-24 22:48:01

你好 ,我也在做这个芯片的编程,希望不吝赐教,我把手册都看完了还是不怎么懂操作。邮箱597837757@qq.com

wiisir 发表于 2013-4-27 20:57:01

哥们,我也碰到此问题了,痛苦啊{:cry:}

wsws1057 发表于 2013-12-18 09:47:07

我也碰到这个问题了可以给我发一下 吗 610290429@qq.com

ywq 发表于 2014-5-4 17:08:28

谢谢分享,,”或“加在哪里?
页: [1]
查看完整版本: ADE7758读不到电压数据!!!