|
各位大侠好,我在用AD7656采集交流电压和电流信号,但是在用并口模式下读转换数据时遇到了一个很奇怪的问题,就是:输入为正电压时转换结果为该电压的负值,比如接+3.3v,转换结果为-20982,而接负电压时,转换结果完全是错的,同时还有一个问题是两次读取的之间要很长的延时,要不然读到的第二个数据是错的,datasheet上说的20ns,可是延时了接近800us才读到正常点的值,这是为什么呢?
请大家帮帮忙! 非常感谢!
硬件上是完全按照datasheet上的搭建的,使用了内部2.5V基准电压, 同时将RESET脚接到了一个IO口控制复位。
硬件原理图 (原文件名:diagram.jpg)
软件代码如下:
#define BUSY GpioDataRegs.GPADAT.bit.GPIOA0
#define RD GpioDataRegs.GPADAT.bit.GPIOA1
#define CS GpioDataRegs.GPADAT.bit.GPIOA2
#define CONA GpioDataRegs.GPADAT.bit.GPIOA3 //V1 V2的转换控制
#define RST GpioDataRegs.GPADAT.bit.GPIOA4 //RESET
void ResetAD(void)
{
RST=1;
delay(10);
RST=0;
CS=0;
CONA=1;
delay(5);
CONA=0;
delay(5);
CONA=1;
}
Uint16 ReadResult(void)
{
Uint16 temp;
RD=0;
temp=GpioDataRegs.GPBDAT.all;
while(GpioDataRegs.GPBDAT.all-temp);//等待数据稳定
temp=GpioDataRegs.GPBDAT.all;
RD=1;
return temp;
}
通过定时器启动转换,然后等待BUSY信号下降沿开始读取转换结果。
完整的程序如下:
/****************************************************************
**描述:利用GP定时器1在GPIOF8引脚上产生方波,令一个贴片LED闪烁**
**系统时钟150M,高速外设时钟25M,128分频后定时器周期为5.12us****
****************************************************************/
#include "DSP28_Device.h"
interrupt void eva_timer1_isr(void);
#define BUSY GpioDataRegs.GPADAT.bit.GPIOA0
#define RD GpioDataRegs.GPADAT.bit.GPIOA1
#define CS GpioDataRegs.GPADAT.bit.GPIOA2
#define CONA GpioDataRegs.GPADAT.bit.GPIOA3
#define RST GpioDataRegs.GPADAT.bit.GPIOA4
Uint16 Result1,Result2,a=0,b=0;
unsigned char started=0,count=0;
float a1[128],a2[128];
void delay( int time)
{
int i;
for(i=0;i<time;i++);
}
void IOinit()
{
EALLOW;
GpioMuxRegs.GPBMUX.all = 0x0000;
GpioMuxRegs.GPBDIR.all = 0x0000;
GpioMuxRegs.GPAMUX.all = 0xFFE0;
GpioMuxRegs.GPADIR.all = 0x001E;
EDIS;
}
void ResetAD(void)
{
RST=1;
delay(10);
RST=0;
CS=0;
CONA=1;
delay(5);
CONA=0;
delay(5);
// asm("NOP");
CONA=1;
}
void InitAD(void)
{
CS=0;
CONA=0;
// asm("NOP");
CONA=1;
}
Uint16 ReadResult(void)
{
Uint16 temp;
// RD=1;
RD=0;
// delay(10);
temp=GpioDataRegs.GPBDAT.all;
while(GpioDataRegs.GPBDAT.all-temp);
temp=GpioDataRegs.GPBDAT.all;
RD=1;
return temp;
}
void EVA_Timer1()
{
EvaRegs.GPTCONA.all = 0; // 初始化 EVA Timer 1
EvaRegs.T1PR = 0x003F; //1D // 定时周期为5.12us*(T1PR+1)=0.2s
EvaRegs.EVAIMRA.bit.T1PINT = 1; //使能定时器1的周期中断
EvaRegs.EVAIFRA.bit.T1PINT = 1; //写1清除定时器1的周期中断标志
EvaRegs.T1CNT = 0x0000;
EvaRegs.T1CON.all = 0x1740; //连续增计数,128分频,打开定时器
}
void main(void)
{
InitSysCtrl(); //初始化系统控制寄存器, 时钟频率150M
EALLOW;
SysCtrlRegs.HISPCP.all = 0x0003;//高速时钟的工作频率=25M
EDIS;
DINT; //关闭总中断,清除中断标志
IER = 0x0000; //关7闭外围中断
IFR = 0x0000; //清中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable();
EVA_Timer1();
IOinit();
EALLOW;
PieVectTable.T1PINT = &eva_timer1_isr; //中断服务程序入口地址放入中断向量表
EDIS;
//依次使能各级中断:外设中相应中断位->PIE控制器->CPU
PieCtrlRegs.PIEIER2.all = M_INT4; //GP定时器1使能位于PIE第2组第4个,将其使能
IER |= M_INT2; //PIE第2组对应于CPU的可屏蔽中断2(INT2),将其使能
EINT; //开总中断
for(;;)
{
if(started)
{
started=0;
while(BUSY);
Result1=ReadResult();
delay(1000);
Result2=ReadResult();// & 0x7fff;
if((Result1 & 0x8000) != 0x8000)
{
a1[a++]=(float)(Result1)/(float)(0x7fff)*(5.0);
}else
a1[a++]=((float)(0xffff-Result1))/(float)(0x7fff)*(-5.0);
if((Result2 & 0x8000) != 0x8000)
{
a2[b++]=(float)(Result2)/(float)(0x7fff)*5.0;
}else
a2[b++]=((float)(0xffff-Result2))/(float)(0x7fff)*(-5.0);
CS=1;
}
if(count==128)
{
a=0;
b=0;
count=0;
}
}
}
interrupt void eva_timer1_isr(void)
{
//GpioDataRegs.GPADAT.bit.GPIOA4=GpioDataRegs.GPADAT.bit.GPIOA4^1; //产生方波
ResetAD();
started=1;
if(count<128) count++;
EvaRegs.EVAIMRA.bit.T1PINT = 1; //使能定时器1的周期中断
EvaRegs.EVAIFRA.bit.T1PINT = 1; //写1清除定时器1的周期中断标志
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2; //清零 PIEACK中的第2组中断对应位
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|