搜索
bottom↓
回复: 10

ADE7758读不到电压数据!!!

[复制链接]

出0入0汤圆

发表于 2011-3-31 17:35:41 | 显示全部楼层 |阅读模式
我用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×[SCR+1]), 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[3]=ADE7758_RD(AVRMS,3);                        // A相电压
        UART_Printf(0,"---ADE_Va=%5d",ADE_Va[3]);
        ADE_Vb[3]=ADE7758_RD(BVRMS,3);                        // B相电压
        UART_Printf(0,"---ADE_Vb=%5d",ADE_Vb[3]);
        ADE_Vc[3]=ADE7758_RD(CVRMS,3);                        // C相电压
        UART_Printf(0,"---ADE_Vc=%5d",ADE_Vc[3]);
        ADE_freq[3]=ADE7758_RD(FREQ,2);                        // 频率
        UART_Printf(0,"---ADE_f=%5d\n",ADE_freq[3]);
        */
        Delay_MS(10);
        ADE_CS4(1);
         }

}

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

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

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

出0入0汤圆

 楼主| 发表于 2011-3-31 17:57:10 | 显示全部楼层
问题已解决!

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

出0入0汤圆

 楼主| 发表于 2011-3-31 17:57:26 | 显示全部楼层
问题已解决!

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

出0入85汤圆

发表于 2012-6-4 08:58:11 | 显示全部楼层
coolala584520 发表于 2011-3-31 17:57
问题已解决!

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

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

出0入0汤圆

发表于 2012-6-11 15:55:41 | 显示全部楼层
你好在吗?
你的那个ADE7758读取在哪里加“或”
不是太懂。
忘不吝赐教。呵呵

出0入0汤圆

发表于 2012-12-24 12:33:08 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2013-2-19 16:58:42 | 显示全部楼层
你好,在了吗,我想向你请教一下ADE7758的程序书写,我用的stm32f103VET6的片子,我是新手,不怎么写过程序,可以把你的工程分享给我一份吗?非常感谢  邮箱qp20081001@gmail.com

出0入0汤圆

发表于 2013-4-24 22:48:01 | 显示全部楼层
你好 ,我也在做这个芯片的编程,希望不吝赐教,我把手册都看完了还是不怎么懂操作。邮箱597837757@qq.com

出0入0汤圆

发表于 2013-4-27 20:57:01 | 显示全部楼层
哥们,我也碰到此问题了,痛苦啊

出0入0汤圆

发表于 2013-12-18 09:47:07 | 显示全部楼层
我也碰到这个问题了  可以给我发一下 吗 610290429@qq.com

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-23 09:08

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

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