微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI模拟硬件电路设计 > ADS1247 热电偶信号采集 数据不稳

ADS1247 热电偶信号采集 数据不稳

时间:10-02 整理:3721RD 点击:

ADS1247采集热电偶信号数据不稳,现象如下,请大家帮帮忙解决下,急啊!

   热电偶信号需要精确到1℃以内,要求1S中至少要出30个数,现在把采样速率设定在320SPS  ,软件10个数求平均一次,误差在0.2mV左右,远远不能满足要求。

把采样速率降到40SPS,滤波数量改为40个,精度能达到20uV,这样能满足精度要求,但是又不能满足一秒钟出30个数,请大家帮帮忙,谢了!

你好!

请楼主上传原理图,另外,PGA设置大小是多少?

程序如下:

void ADS1247Wakeup(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x00); //reg    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

void ADS1247Sleep(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x02); //reg    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

void ADS1247Sync(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x04);    ADS1247TxRxByte(0x04);    ADS1247PinCs(1);   } /********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

 void ADS1247Reset(void) {     uint16 i;             ADS1247PinCs(0);  ADS1247TxRxByte(0x06);     ADS1247PinCs(1);     for (i=60000; i!=0; i--);     ADS1247PinReset(0);     for (i=60000; i!=0; i--);     ADS1247PinReset(1);     for (i=60000; i!=0; i--); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

uint32 ADS1247RData(void) {  uint32 res = 0;    ADS1247PinCs(0);

 ADS1247TxRxByte(0x12);    res = ADS1247TxRxByte(0);  res <<= 8;  res |= ADS1247TxRxByte(0);  res <<= 8;  res |= ADS1247TxRxByte(0);    ADS1247PinCs(1);    return res; }

uint32 ADS1247ReadADC(void) {     uint32 res = 0;    ADS1247PinCs(0);       res = ADS1247TxRxByte(0);  res <<= 8;  res |= ADS1247TxRxByte(0);  res <<= 8;  res |= ADS1247TxRxByte(0);         ADS1247PinCs(1);    return res; }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

void ADS1247RDataC(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x14);    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

 void ADS1247SDataC(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x17);    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/

 void ADS1247SysOCal(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x60);    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************

/ void ADS1247SysGCal(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x61);    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ void ADS1247SelfOCal(void) {  ADS1247PinCs(0);    ADS1247TxRxByte(0x62);    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ void ADS1247ReadReg(uint8 reg, uint8 *pcmd, uint8 len) {  ADS1247PinCs(0);    ADS1247TxRxByte(reg | 0x20); //reg    ADS1247TxRxByte(len - 1);   //len    while (len != 0)  {   *pcmd = ADS1247TxRxByte(0x00);   pcmd++;   len--;  }    ADS1247PinCs(1); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ void ADS1247WriteReg(uint8 reg, uint8 *pcmd, uint8 len) {  ADS1247PinCs(0);    ADS1247TxRxByte(reg | 0x40); //reg    ADS1247TxRxByte(len - 1);   //len    while (len != 0)  {   ADS1247TxRxByte(*pcmd);   pcmd++;   len--;  }    ADS1247PinCs(1); }

 

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static uint8 ADS1247TxRxByte(uint8 dt) {  uint8 res = 0;  uint8 i;    for (i=8; i!=0; i--)  {   ADS1247PinSdi(((dt & 0x80) != 0) ? 1 : 0);   ADS1247PinSclk(1);   res <<= 1;   if (ADS1247PinSdo() != 0)    res |= 0x01;   ADS1247PinSclk(0);         dt <<= 1;  }    return res; }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static void AD1247IOInit(void) {  GPIO_InitTypeDef GPIO_InitStructure;    /* GPIO 定义 */  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //===========  // GPIOA  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 |  // ADS1247 SCLK            GPIO_Pin_7;   // ADS1247 SDI            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_Init(GPIOA, &GPIO_InitStructure);    // IN  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   // ADS1247 SDO   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_Init(GPIOA, &GPIO_InitStructure);    //===========  // GPIOB  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |   // ADS1247 RESET                GPIO_Pin_0;   // ADS1247 START  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_Init(GPIOB, &GPIO_InitStructure);  

 //===========  // GPIOC  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  // ADS1247 CS  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  GPIO_Init(GPIOC, &GPIO_InitStructure);    //IN  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;   // ADS1247 DRDY   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  GPIO_Init(GPIOC, &GPIO_InitStructure);         ADS1247PinReset(1);     ADS1247PinCs(1);     ADS1247PinStart(1);     ADS1247PinSclk(0); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static void ADS1247PinSclk(uint8 st) {  GPIO_WriteBit(GPIOA, GPIO_Pin_5, (st == 0) ? Bit_RESET : Bit_SET); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static void ADS1247PinSdi(uint8 st) {  GPIO_WriteBit(GPIOA, GPIO_Pin_7, (st == 0) ? Bit_RESET : Bit_SET); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static uint8 ADS1247PinSdo(void) {     uint8 res;      res = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);     return res; }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static void ADS1247PinReset(uint8 st) {  GPIO_WriteBit(GPIOB, GPIO_Pin_1, (st == 0) ? Bit_RESET : Bit_SET); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ void ADS1247PinStart(uint8 st) {  GPIO_WriteBit(GPIOB, GPIO_Pin_0, (st == 0) ? Bit_RESET : Bit_SET); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ static void ADS1247PinCs(uint8 st) {  GPIO_WriteBit(GPIOC, GPIO_Pin_5, (st == 0) ? Bit_RESET : Bit_SET); }

/********************************************************************************** ** 函数名称: ** 功    能: ** 输入参数: ** 输出参数: ** 返    回: ***********************************************************************************/ uint8 ADS1247PinDRdy(void) {     uint8 res;      res = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4);     return res; }

程序中调用的是ADS1247ReadADC() 函数读取数据,调用ADS1247RData(void)函数与调用ADS1247RData()函数现象一样

PGA设置为32,与设置成1没有什么明显的改善。原理图上的RDT   RDW   Rb没有焊接,AIN2,AIN3没有使用

  

 

补充一点:采用的是内部基准

初始化程序如下:

void ADS1247Init(void) {  uint8 buf[3];  uint8 i;

 AD1247IOInit();

    //     ADS1247Reset();

    //Stopreading datacontinuously     ADS1247SDataC();         ADS1247Wakeup();  ADS1247SysOCal() ;         // MUX0     buf[0] = 0x01| 1<<6;       //buf[0]=   0<<5 | 0<<3 | 1<<0 ;     ADS1247WriteReg(0x00, buf, 1);

 // VBIAS     switch( SENSOR_MODE  )  {   case   PT_100:   case    PT_500:      case    PT_1000:    case    PT_10:       case    BA1:         case    BA2:         case    Cu:          case    Cu_50:       case    Cu_100:                 buf[0] = 0x00;     break;   default:     buf[0] = 0x02;      break;  }     //  buf[0] = 0x02;  ADS1247WriteReg(0x01, buf, 1);        switch( SENSOR_MODE  )    {   case   PT_100:   case    PT_500:      case    PT_1000:    case    PT_10:       case    BA1:         case    BA2:         case    Cu:          case    Cu_50:       case    Cu_100:    // MUX1       buf[0] =     (0 << 7) |              //internal oscillator                    (1 << 5) |  //Internal referenceis alwayson           (0 << 3) |  //REF0input pairselected           (0 << 0);     break;   default:     // MUX1       buf[0] =     (0 << 7) |              //internal oscillator                    (1 << 5) |  //Internal referenceis alwayson           (2 << 3) |  //REF0input pairselected           (0 << 0);      break;   } /*        buf[0] = (1 << 5) |  //Internal referenceis alwayson        (2 << 3) |  //REF0input pairselected        (0 << 0); */    ADS1247WriteReg(0x02, buf, 1);         // SYS0   switch(SENSOR_MODE )  {   case PT_100:     buf[0] = (Pt100_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS           break;   case PT_1000:    buf[0] = (Pt1000_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS        break;   case PT_500:    buf[0] = (Pt500_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS        break;   case PT_10:    buf[0] = (Pt10_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS       break;   case BA1:    buf[0] = (Ba1_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS      break;   case BA2:    buf[0] = (Ba2_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS    break;   case Cu_50:    buf[0] = (Gu50_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS         break;   case Cu_100:    buf[0] = (Gu100_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS          break;   case Cu:    buf[0] = (Gu_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS         break;   default:       buf[0] = (k_PGA << 4) |  //PGA: These bit sdetermine the gain of the PGA                 (6 << 0);  //DOR: 320SPS    break;  }  /*         // SYS0     buf[0] = (0 << 4) |  //PGA: These bit sdetermine the gain of the PGA             (6 << 0);  //DOR: 320SPS  */     ADS1247WriteReg(0x03, buf, 1);

  switch(SENSOR_MODE )  {   case PT_100:     buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (Pt100_SET << 0);  //IMAG           break;   case PT_1000:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (Pt1000_SET << 0);  //IMAG        break;   case PT_500:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (Pt500_SET << 0);  //IMAG        break;   case PT_10:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (7 << 0);  //IMAG       break;   case BA1:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (Ba1_SET << 0);  //IMAG      break;   case BA2:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            (Ba2_SET << 0);  //IMAG    break;   case Cu_50:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            ( Gu50_SET << 0);  //IMAG         break;   case Cu_100:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            ( Gu100_SET << 0);  //IMAG          break;   case Cu:    buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut            ( Gu_SET << 0);  //IMAG         break;   default:       buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut                (0 << 0);  //IMAG    break;  } /*      // IDAC0     buf[0] = (0 << 3) |  //DRDY MODE: DOUT/DRDYpinfunctions onlyasDataOut        (0 << 0);  //IMAG   */  ADS1247WriteReg(0x0a, buf, 1);        // IDAC1  switch( SENSOR_MODE  )  {   case    PT_100:   case    PT_500:      case    PT_1000:    case    PT_10:       case    BA1:         case    BA2:         case    Cu:          case    Cu_50:       case    Cu_100:                 buf[0] = (0 << 4) |  //I1DIR           (1 << 0);  //I2DIR     break;   default:     buf[0] = (0 << 4) |  //I1DIR           (0xc << 0);  //I2DIR      break;  } /*             // IDAC1     buf[0] = (0x0 << 4) |  //I1DIR        (0xc << 0);  //I2DIR   */  ADS1247WriteReg(0x0b, buf, 1);    

    ADS1247RDataC();     ADS1247PinStart(1);

Hi

  从你描述的现象看应该是ADC转换的精度偏低导致的,很程序没有关系。

  你可以参考一下datasheet有效位的参数表:   http://www.ti.com.cn/cn/lit/ds/symlink/ads1247.pdf  第十二、十三页。

  采样率越低,有效位越高;PGA的设置也是越小,有效位越高。 所以理论上较小PGA是可以降低误差,但是这个取决于你的模拟输入,不易改变。

  建议你采用外部参考电压看看,内部参考源的精度是0.5%, 如果选择外部参考电压精度可以是0.1%甚至更高。另外注意一下供电的Noise,以及数模隔离的问题。

谢谢您的回复

现在我把输入端用线短接,稳定性还不错,加上信号源之后数据有跳变现象,但是信号源应该没有问题,打电话问信号源厂家,精度能达到1uV,是不是由于引线把噪声给引入了啊。还有,就是如果把先双绞处理下会好一些,但是,如果用手握住双绞线数据变化很剧烈。现在这环境干扰都这么大,到现场估计都不能用了,请大虾支支招,我实在没有招了。

我的模拟地与数字地是单点接地,怎么处理更好一些呢?

Hi

  从你描述的现象看确实可能是输入部分有noise导致的。

   关于RTD的应用,或许你可以参考这个文档: http://proddms.itg.ti.com/stage/lit/an/sbaa201/sbaa201.pdf   关于输入部分的。

   另外数字GND,模拟GND确实是需要端点接各自的GND Plane.

试了一天,没有什么改善,我看ADS1247内部有滤波器,这个滤波器怎么样啊,这个片子能不嫩做到一秒钟出40个数,精度在10uV以内啊?

Delta-Sigma型的ADC采样率越低精越高,如果你把采样率降为40sps。就没必要再用软件滤波了,因为这个工作,ADC内部的滤波器已经帮你实现了。

Delta-Sigma型的ADC的内部就是有两部分组成,一个是Delta-Sigma调制器,后面就是滤波器。这个原理就决定了,采样速率越低,精度越高。没必要再进行软件10个求平均滤波了。

谢谢回答,采样速率设定为40SPS以后,好了很多,短接输入时比较稳定,上下波动也就10uV左右,但是用信号源加信号时,波动还是比较大,有时能达到400uV,信号源输出线一米左右,还有一个现象,我输入端短接线使用一根20cm的双绞线做的,当用手触摸双绞线时,信号飘的也很离谱,这种问题怎么解决啊?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top