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总线了! 问题已解决!
在ADE7758_RD()函数中,接收字节处漏了一个“或”! 问题已解决!
在ADE7758_RD()函数中,接收字节处漏了一个“或”! coolala584520 发表于 2011-3-31 17:57 static/image/common/back.gif
问题已解决!
在ADE7758_RD()函数中,接收字节处漏了一个“或”!
哥么,能把工程包给我一下吗 你好在吗?
你的那个ADE7758读取在哪里加“或”
不是太懂。
忘不吝赐教。呵呵 MARK!{:smile:} 你好,在了吗,我想向你请教一下ADE7758的程序书写,我用的stm32f103VET6的片子,我是新手,不怎么写过程序,可以把你的工程分享给我一份吗?非常感谢邮箱qp20081001@gmail.com 你好 ,我也在做这个芯片的编程,希望不吝赐教,我把手册都看完了还是不怎么懂操作。邮箱597837757@qq.com 哥们,我也碰到此问题了,痛苦啊{:cry:} 我也碰到这个问题了可以给我发一下 吗 610290429@qq.com 谢谢分享,,”或“加在哪里?
页:
[1]