This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1256: ADS 1256

Part Number: ADS1256

Hello,

Our customer who use stm32f103RDT6+SPI+ADS1256 to acquire voltage signal with multi-cycles sample, but the acquire data is not change  whenever the PGA gain is 1 or other gain data. But if  using one cycle mode and PGA gain=32, the acquire data has no problem.

Below is some of the codes for reference, could you please help to analysis? 

  

ADS1256配置代码

#include "ADS1256.h"
#include "sys.h"
#include "delay.h"

void SPI2_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  /****Initial SPI2******************/
 
  /* Enable SPI2 and GPIOB clocks */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);        //PORTB时钟使能
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);         //SPI2时钟使能
 
  /* Configure SPI2 pins: NSS, SCK, MISO and MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; //PB131415 输入输出时钟
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);
 
  // SPI2 configuration
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   //SPI2设置为双线全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                       //设置SPI2为主模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                     //SPI发送接收8位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                        //串行时钟在不操作时,时钟为低电平
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;                      //第一个时钟沿开始采样数据
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                        //NSS信号由软件(使用SSI位)管理
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;  //定义波特率预分频:预分频值为8
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;              //数据传输从MSB位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;                     //CRC值计算的多项式
  SPI_Init(SPI2, &SPI_InitStructure);
  // Enable SPI2 
  SPI_Cmd(SPI2, ENABLE);
  
  //片选初始化PB12
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  PBout(12)=0;
  

//初始化ADS1256 GPIO
   void Init_ADS1256_GPIO(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_ADS1256Reset | RCC_ADS1256DRDY, ENABLE); //复位等待IO时钟使能

   GPIO_InitStructure.GPIO_Pin = GPIO_RCC_ADS1256Reset;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
   GPIO_Init(GPIO_RCC_ADS1256Reset_PORT, &GPIO_InitStructure); 
   GPIO_ResetBits(GPIO_RCC_ADS1256Reset_PORT, GPIO_RCC_ADS1256Reset );

  GPIO_InitStructure.GPIO_Pin = GPIO_ADS1256DRDY;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 
   GPIO_Init(GPIO_ADS1256DRDY_PORT, &GPIO_InitStructure); 
  SPI2_Init();
}


//-----------------------------------------------------------------//
// 功    能:  模拟SPI通信
// 入口参数:  发送的SPI数据一个字节
// 出口参数:  接受的SPI数据一个字节
// 全局变量:  无
// 备    注:  发送接收一个字节数据
//-----------------------------------------------------------------//
unsigned char SPI_WriteByte(unsigned char TxData)
{
  unsigned char RxData=0;

  while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET); //                                                  
  SPI_I2S_SendData(SPI2,TxData);

   while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)==RESET);

   RxData=SPI_I2S_ReceiveData(SPI2);

    return RxData;
}

//-----------------------------------------------------------------//
// 功    能:ADS1256写数据
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 向ADS1256中地址为regaddr的寄存器写入一个字街databyte
//-----------------------------------------------------------------//
void ADS1256WREG(unsigned char regaddr,unsigned char databyte)
{
  while(ADS1256_DRRY);     //当ADS1256_DRDY为低的时候才能写寄存器
    SPI_WriteByte(ADS1256_CMD_WREG | (regaddr & 0x0F));//向寄存器写入数据地址
    SPI_WriteByte(0x00);//写入数据的个数n-1
    SPI_WriteByte(databyte);//向regaddr地址指向的寄存器写入数据databyte
}

//初始化ADS1256
void ADS1256_Init(void)
{
 ADS1256WREG(ADS1256_STATUS,0x06);               //高位在前、校准、使用缓冲
 ADS1256WREG(ADS1256_MUX,0x01);                 //初始化端口A0为“+”,AINCOM位为“-”    龙修改
 ADS1256WREG(ADS1256_ADCON,0x05);                //放大倍数32
 ADS1256WREG(ADS1256_DRATE,ADS1256_DRATE_2000SPS);         //数据7500sps
 ADS1256WREG(ADS1256_IO,0x00);          //  
 
 ADS1256_SELFCAL();
 //SPI_WriteByte(ADS1256_CMD_SYNC);
 
  ADS1256_RDATAC();
 
}

//读取AD值
 unsigned int ADS1256ReadData() 
{
  unsigned int sum=0;
 while(ADS1256_DRRY);                 //当ADS1256_DRDY为低时才能写寄存器
 //SPI_WriteByte(ADS1256_CMD_SYNC);
  sum |= (SPI_WriteByte(0xff) << 16);
 sum |= (SPI_WriteByte(0xff) << 8);
 sum |= SPI_WriteByte(0xff);
  return sum;
}


//-----------------------------------------------------------------//
// 功    能:读取ADS1256单路数据
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: /
//-----------------------------------------------------------------//
unsigned int ADS_sum(unsigned char channel)
{
 //ADS1256WREG(ADS1256_MUX,channel);  //设置通道
 return ADS1256ReadData();      //读取AD值,返回24位数据
}
//-----------------------------------------------------------------//
// 功    能:ADS1256唤醒
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 唤醒待机和同步
//-----------------------------------------------------------------//
void ADS1256_WAKEUP(void)
{
 SPI_WriteByte(ADS1256_CMD_WAKEUP);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256读一次数据命令
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: /在DRDY为低是读出一个数据
//-----------------------------------------------------------------//
void ADS1256_RDATA(void)
{
 SPI_WriteByte(ADS1256_CMD_RDATA);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256连续读取数据命令
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: /在DRDY为低时连续读出数据
//-----------------------------------------------------------------//

void ADS1256_RDATAC(void)
{
 SPI_WriteByte(ADS1256_CMD_RDATAC);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256停止连续读取数据命令
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 在ADS1256连续读取24位数据当中的任何八位时写入,停止连续读取数据命令
//-----------------------------------------------------------------//

void ADS1256_SDATAC(void)
{
 SPI_WriteByte(ADS1256_CMD_SDATAC);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256偏移和增益自校准
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 偏移和增益自校准,也可以用STATUS寄存器中的ACAL来自校准
//-----------------------------------------------------------------//
void ADS1256_SELFCAL(void)
{
 SPI_WriteByte(ADS1256_CMD_SELFCAL);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256同步
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 同步用在命令的开始快速执行,紧接着用WAKEUP命令进行同步
//-----------------------------------------------------------------//
void ADS1256_SYNC(void)
{
 SPI_WriteByte(ADS1256_CMD_SYNC);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256复位
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 复位后不管ACAL位如何都执行一个自校准
//-----------------------------------------------------------------//
void ADS1256_RESET(void)
{
 SPI_WriteByte(ADS1256_CMD_REST);
}
//-----------------------------------------------------------------//
// 功    能:ADS1256第一路采集数据
// 入口参数: /
// 出口参数: /
// 全局变量: /
// 备    注: 单路采集功能
//-----------------------------------------------------------------//
  unsigned int GetADS1256_0(void)
{
 long ulResult;
 int nVolutage;
 ulResult = ADS1256ReadData(); 
 if(ulResult & 0x800000 )
 {
   ulResult = ~(unsigned long)ulResult;
   ulResult &= 0x7fffff;
   ulResult += 1;
   ulResult = -ulResult;
 };
 nVolutage=ulResult/10;
 return nVolutage+2000;
}

主程序

int main(void)
 {
 SystemInit();      //系统时钟初始化
 delay_init();         //延时函数初始化 
 NVIC_Configuration();   //NVIC 
 __enable_irq();     //开启总中断
 uart_init(BAUDRATE);   //串口初始化为19200
 LED_Init();        //初始化与LED连接的硬件接口
 KEY_Init();       //按键初始化    
 Init_ADS1256_GPIO();  //初始ADS1256IO
 PCout(7)=1;       //复位拉高
 ADS1256_Init();
 
 while(1)
 {
  if(KEY1==0)
  {
   if(nCounter!=nDynamicCountFlag)               //如果 动态测量的计数器标志 不等于 计数器 说明上一次是静态称重,将计数器与标志全部置0
   {
    nCounter=0;
    nDynamicCountFlag=0;
   }
  }
  else if(KEY1==1)
  {
   if(nCounter!=nStaticCountFlag)               //如果静态测量的计数器标志 不等于 计数器说明上一次是动态称重,将计数器与标志全部置0
   {
    nStaticSum=0;                       //累加器置0;
    nCounter=0;
    nStaticCountFlag=0;
   }
   nStaticSum+=GetADS1256_0();                 //累加采集到的的数据
   nStaticCalculationTimes++;                 //累加 静态状态下已经累加计算值的个数
   if(nCounter>=10000)                     //如果计数器超过10000计数器置0
    nCounter=0;
    if(nStaticCalculationTimes==nLoopNum)           //判断如果静态状态下已经累加计算值的个数等于设定的静态状态下的累加计算循环的次数,进入循环进行计算发送数据
    {
     ZeroPiont1 = nStaticSum/nLoopNum;            //全局变量,零点码值
     nStaticSum=0;                       //累加器置0;
     nStaticCalculationTimes=0;               //静态状态下已经累加计算值的个数置0,因为已经够数了,下次重新开始
     PackMySend(LOCALXINDAO1,CMDZEROPOINT,0,ZeroPiont1);   //按照协议发送动态数据
    }
    if(nStaticCountFlag==0)                  //判断如果静态测量的计数器标志为0,清空动态测量的计数器标志为0,说明动态测量已经结束必须进入静态测量了。
     nDynamicCountFlag=0;                  //将动态测量的计数器标志置0
    nStaticCountFlag=nCounter+1;               //将静态测量的计数器标志更改为总计数器+1
  }
  nCounter++;
 }
}

Best regards

Kailyn

  • Hi Kailyn,

    Can you tell me what the master clock frequency that is being used with the ADS1256, and also verify the SCLK frequency used?  Can you share any oscilloscope or logic analyzer plots of the communication?

    The function to read the data uses the RDATA command, but it is not clear as to how the end of conversion is being determined to know when a new result is available.  Normally DRDY is monitored for a falling edge of the DRDY signal to determine if a new conversion result is ready to be read from the device.  The C code appears to just repeatedly read the result which could be many times with the same value until a new conversion completes.  There needs to be either a time delay for the conversion period length or DRDY must be monitored to determine when a new result is ready.

    Best regards,

    Bob B