ads1256数据采集电压不正确与实际电压有400毫伏的偏差
我用的是DSP28355SPI模块进行的读写,能读出数据,数据的变化趋势也是争取的,就是读出的电压偏差较大
这个问题困扰好多天了,我的程序如下:
/*端口定义*/
#define ADS_DRDY GpioDataRegs.GPADAT.bit.GPIO0
#define ADS_CS GpioDataRegs.GPADAT.bit.GPIO1
#define ADS_REST GpioDataRegs.GPADAT.bit.GPIO2
/*命令定义*/
#define ADS1256_CMD_WAKEUP 0x00
#define ADS1256_CMD_RDATA 0x01
#define ADS1256_CMD_RDATAC 0x03
#define ADS1256_CMD_SDATAC 0x0f
#define ADS1256_CMD_RREG 0x10
#define ADS1256_CMD_WREG 0x50
#define ADS1256_CMD_SELFCAL 0xf0
#define ADS1256_CMD_SELFOCAL 0xf1
#define ADS1256_CMD_SELFGCAL 0xf2
#define ADS1256_CMD_SYSOCAL 0xf3
#define ADS1256_CMD_SYSGCAL 0xf4
#define ADS1256_CMD_SYNC 0xfc
#define ADS1256_CMD_STANDBY 0xfd
#define ADS1256_CMD_REST 0xfe
/*寄存器地址定义*/
#define ADS1256_STATUS 0x00
#define ADS1256_MUX 0x01
#define ADS1256_ADCON 0x02
#define ADS1256_DRATE 0x03
#define ADS1256_IO 0x04
#define ADS1256_OFC0 0x05
#define ADS1256_OFC1 0x06
#define ADS1256_OFC2 0x07
#define ADS1256_FSC0 0x08
#define ADS1256_FSC1 0x09
#define ADS1256_FSC2 0x0A
/*通道选择定义*/
#define ADS1256_MUXP_AIN0 0x00
#define ADS1256_MUXP_AIN1 0x10
#define ADS1256_MUXP_AIN2 0x20
#define ADS1256_MUXP_AIN3 0x30
#define ADS1256_MUXP_AIN4 0x40
#define ADS1256_MUXP_AIN5 0x50
#define ADS1256_MUXP_AIN6 0x60
#define ADS1256_MUXP_AIN7 0x70
#define ADS1256_MUXP_AINCOM 0x80
#define ADS1256_MUXN_AIN0 0x00
#define ADS1256_MUXN_AIN1 0x01
#define ADS1256_MUXN_AIN2 0x02
#define ADS1256_MUXN_AIN3 0x03
#define ADS1256_MUXN_AIN4 0x04
#define ADS1256_MUXN_AIN5 0x05
#define ADS1256_MUXN_AIN6 0x06
#define ADS1256_MUXN_AIN7 0x07
#define ADS1256_MUXN_AINCOM 0x08
/*增益定义*/
// define gain codes
#define ADS1256_GAIN_1 0x00
#define ADS1256_GAIN_2 0x01
#define ADS1256_GAIN_4 0x02
#define ADS1256_GAIN_8 0x03
#define ADS1256_GAIN_16 0x04
#define ADS1256_GAIN_32 0x05
#define ADS1256_GAIN_64 0x06
//#define ADS1256_GAIN_64 0x07
/*采样速率定义*/
#define ADS1256_DRATE_30000SPS 0xF0
#define ADS1256_DRATE_15000SPS 0xE0
#define ADS1256_DRATE_7500SPS 0xD0
#define ADS1256_DRATE_3750SPS 0xC0
#define ADS1256_DRATE_2000SPS 0xB0
#define ADS1256_DRATE_1000SPS 0xA1
#define ADS1256_DRATE_500SPS 0x92
#define ADS1256_DRATE_100SPS 0x82
#define ADS1256_DRATE_60SPS 0x72
#define ADS1256_DRATE_50SPS 0x63
#define ADS1256_DRATE_30SPS 0x53
#define ADS1256_DRATE_25SPS 0x43
#define ADS1256_DRATE_15SPS 0x33
#define ADS1256_DRATE_10SPS 0x23
#define ADS1256_DRATE_5SPS 0x13
#define ADS1256_DRATE_2.5SPS 0x03
void ADS1256_Init(void);
void ADS1256WREG(unsigned char regaddr,unsigned char databyte);
void spiwr(unsigned int data);
unsigned long adread(void);
//unsigned char spir(void);
void ADS_sum(unsigned char road);
void spint16(void);
void spint8(void);
unsigned long Result_sum=0;
int h=7;
/////////////////////////////////////////////////////
unsigned int Spi_TxReady(void)
{
unsigned int i;
if(SpiaRegs.SPISTS.bit.BUFFULL_FLAG == 1)
{
i = 0;
}
else
{
i = 1;
}
return(i);
}
void main(void)
{
// Step 1. Initialize System Control:
InitSysCtrl();
// Step 2. Initalize GPIO:
InitXintf();
InitSpiGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
DINT;
// Initialize PIE control registers to their default state.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
InitPieVectTable();
// Step 4. Initialize all the Device Peripherals:
ADS1256_Init();
while (1)
{
ADS_sum(ADS1256_MUXP_AIN0 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN1 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN2 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN3 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN4 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN5 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN6 | ADS1256_MUXN_AINCOM);
ADS_sum(ADS1256_MUXP_AIN7 | ADS1256_MUXN_AINCOM);
}
}
/////////////////////////////////////////////////////////////
void ADS1256_Init(void)
{
ADS_CS = 0;
// 发送复位命令
ADS_REST = 0;
// Delay(DELAY_10ms);
DELAY_US(2000);
ADS_REST = 1;
ADS1256WREG(ADS1256_STATUS,0x00); // 高位在前、不校准、不使用缓冲
ADS1256WREG(ADS1256_MUX,0x08); // 初始化端口A0为‘+’,AINCOM位‘-’
ADS1256WREG(ADS1256_ADCON,0x00); // 放大倍数1
ADS1256WREG(ADS1256_DRATE,ADS1256_DRATE_100SPS); // 数据5sps
ADS1256WREG(ADS1256_IO,0x00); // IO状态输入
ADS_CS = 1;
}
void ADS1256WREG(unsigned char regaddr,unsigned char databyte)
{
ADS_CS = 0;
while(ADS_DRDY); //当ADS1256_DRDY为低时才能写寄存器
spiwr(ADS1256_CMD_WREG | (regaddr & 0xF)); //向寄存器写入数据地址
spiwr(0); //写入数据的个数n-1
spiwr(databyte); //向regaddr地址指向的寄存器写入数据databyte
ADS_CS = 1;
}
void spiwr(unsigned int data)
{
unsigned int b=0;
b=data<<8;
if(Spi_TxReady() == 1)
SpiaRegs.SPITXBUF = b ;
DELAY_US(150);
}
unsigned long adread(void)
{
unsigned char i=0;
unsigned long sum=0;
unsigned int r=0;
ADS_CS = 0;
while(ADS_DRDY); //当ADS1256_DRDY为低时才能写寄存器
spiwr(ADS1256_CMD_SYNC);
DELAY_US(1); //t11 >4/7.68 us
spiwr(ADS1256_CMD_WAKEUP);
while(ADS_DRDY);
spiwr(ADS1256_CMD_RDATA);
DELAY_US(7); //根据手册时间t6>50tclkin=6.5us
// for(i=0;i<2;i++)
for(i=0;i<3;i++)
{
// spint16();
sum = sum << 8;
spiwr(0x0000); // 触发读书时钟
// DELAY_US(120);
while(SpiaRegs.SPISTS.bit.INT_FLAG !=1); // 收到八个数就读取
// if(Spi_RxReady() == 1)
r = SpiaRegs.SPIRXBUF;
r = r & 0x00FF;
sum |= r;
}
ADS_CS = 1;
// spint8();
return sum;
}
void ADS_sum(unsigned char road)
{
unsigned long results=0;
unsigned long fVoltage;
unsigned char buf[10],rod;
ADS1256WREG(ADS1256_MUX,road); //设置通道
DELAY_US(1);
spiwr(ADS1256_CMD_SELFCAL); //偏移和增益自动校准
DELAY_US(5000);
Result_sum=0;
if(road/16 == 0) //根据手册P21 本次读取的数据是上一次转换的?
rod = (7 + 0x30); //进行通道-1计算
else
rod = ((road/16 + 0x30) -1);
// sendStr("第");
// sendChar(rod);
// sendStr("路:");
results= adread(); //读取AD值,返回24位数据
/*********发送AD转换后实际电压值到串口,因为计算精度问题,电压值有小的偏差*************/
Result_sum = results >> 4;
if(Result_sum<0x80000) //测得电压值为正的情况
{
fVoltage=Result_sum*954; //954=2*2.5/2^19*100000000 2.5为基准电压 100000000为为了计算的准确性转换为整形计算
buf[0]=(unsigned char)(fVoltage/100000000);
buf[0]=buf[0]+0x30;
buf[1]='.';
buf[2]=(unsigned char)((fVoltage%100000000)/10000000);
buf[2]=buf[2]+0x30;
buf[3]=(unsigned char)((fVoltage%10000000)/1000000);
buf[3]=buf[3]+0x30;
buf[4]=(unsigned char)(fVoltage%1000000/100000);
buf[4]=buf[4]+0x30;
buf[5]=(unsigned char)(fVoltage%100000/10000);
buf[5]=buf[5]+0x30;
buf[6]=(unsigned char)(fVoltage%10000/1000);
buf[6]=buf[6]+0x30;
buf[7]=(unsigned char)(fVoltage%1000/100);
buf[7]=buf[7]+0x30;
buf[8]='V'; //V
buf[9]=0x20;
}
else //测得电压值为负的情况
{
Result_sum=0xfffff-Result_sum; //取反运算
fVoltage=Result_sum*954; //954=2*2.5/2^19*100000000 2.5为基准电压 100000000为为了计算的准确性转换为整形计算
buf[0]=(unsigned char)(fVoltage/100000000);
buf[0]=buf[0]+0x30;
buf[1]='.';
buf[2]=(unsigned char)((fVoltage%100000000)/10000000);
buf[2]=buf[2]+0x30;
buf[3]=(unsigned char)((fVoltage%10000000)/1000000);
buf[3]=buf[3]+0x30;
buf[4]=(unsigned char)(fVoltage%1000000/100000);
buf[4]=buf[4]+0x30;
buf[5]=(unsigned char)(fVoltage%100000/10000);
buf[5]=buf[5]+0x30;
buf[6]=(unsigned char)(fVoltage%10000/1000);
buf[6]=buf[6]+0x30;
buf[7]=(unsigned char)(fVoltage%1000/100);
buf[7]=buf[7]+0x30;
buf[8]='V'; //V
buf[9]='-';
}
}
你好,给你个例程参考一下,你也可以把你的电路贴上看看有没有什么硬件问题8715.ADS1256-C5509A-CCS3v1.zip
昨天,我又调了一天,我发现我的程序,如果把采集速率,改到7500hz时,我的ADS1256的采集偏差在10mv以内,小电压时几乎没有偏差,在2v以上估计就有10mv左右的偏差。。。。。。。。。。。。。。请给点建议,谢谢,附件有我的电路图
你好,想咨询下,你之前的问题是怎么解决的?我的电路也出现了测量值不准的情况!该怎么办呢?
数字量最大8388607,一般情况下只有高四位8388是稳定,后面的607都不稳定,乱跳
我的设置是PGA=1,基准2V,不使用缓冲,启用自动校正
你好,我现在也在写DSP28335控制ADS1256来采集数据,单通道,单端采集,但是踩不到值,想想你请教一下,我的QQ:975954022,看到请回复下,谢谢