TI中文支持网
TI专业的中文技术问题搜集分享网站

stm32f103RDT6+SPI+ADS1256单通道连续采集配置PGA失败

stm32f103RDT6+SPI+ADS1256 连续采集电压,无论是设置PGA为1或者其他倍数,采集到的的数据一直是一样的,并且传感器变化数据也随之变化,采用单次采集电压PGA设置为32倍采集数据没问题。

部分代码

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++;
 }
}
 

Amy Luo:

您好,

ADS1256默认PGA为1,采用PGA默认值,单通道连续采集时,采集的数据是正确的吗,如果是正确的,可能是在连续采集模式下,PGA配置问题;如果不正确,请用示波器查看连续采集时通信波形,看下是否存在时序问题。

Kailyn Chen:

您好,您的问题我已经提交到英文E2E上由美国工程师来帮您解答。e2e.ti.com/…/864976

Jianlong Li:

回复 Amy Luo:

单通道数据采用单次采集模式,数据正确,连续采集数据采集异常,异常现象就是PGA为1,是不是连续采集的配置过程与单次采集配置过程不同(除了最后的多次或连续采集命令)

Amy Luo:

回复 Jianlong Li:

配置应该是一样的,我感觉应该是连续采集数据时序问题,可以用示波器看下连续采集数据时信号波形吗

赞(0)
未经允许不得转载:TI中文支持网 » stm32f103RDT6+SPI+ADS1256单通道连续采集配置PGA失败
分享到: 更多 (0)