ADS1248/1247介绍:

ADS1248是TI的一款 24位delta-sigma(ΔΣ) 、2KSPS、8通道(4通道差分)ADC芯片,通讯协议为SPI。可编程数据速率高达2ksps。低噪声PGA:48nVRMS在PGA=128。低漂移内部2.048-V参考值:10ppm/°C(最大值)。模拟电源:单极(2.7V至5.25V)和双极(±2.5V)工作。


ADS1248/1247寄存器讲解

提示:在配置寄存器前,默认已经配置好了硬件SPI,SPI的配置为主模式、全双工、数据位8位、CPOL = 0、CPHA为数据线的第一个变化沿、软件控制NSS、256分频、最高位先发送、TIMODE模式关闭、CRC关闭。作者使用的是STM32L433单片机,使用HAL库来编写,本文将详细阐述ADS1248各个寄存器以及注意事项。

ADS1248/1247一共有15个寄存器,寄存器列表如下:


提示:图上可以看到,寄存器的地址为0x00 - 0x0e,每个寄存器都是一个字节八位分别去配置ADC的功能。

  1. MUX0寄存器:此寄存器的[7:6]位为BSC位,此位用于配置输入电流的限位值,手册上说是烧毁检测电流源的设置,一般设置为00,[5:3]位为MUX_SP位,此位用于设置ADC的输入正通道,000-111分别对应AIN0-AIN7,默认为AIN0。[2:0]位为输入的负通道,此位也是000-111对应AIN0-AIN7通道。
  2. VBIAS寄存器:此寄存器用于配置ADC在通道上施加的偏置电压,偏置电压计算是 (AVDD + AVSS) / 2,默认此位不做配置
  3. MUX1寄存器:7位为CLKSTAT位,此位为只读,用于读取当前ADC使用的是外部还是内部振荡器,0为内部,1为外部。[6:5]此位用于是否打开内部参考,如果使用内部基准,此位需要打开设置为01.[4:3]此位用于选择内部引用还是外部引用,我们用的是内部,所以设置为10.[2:0]此位为一个监视器,用于将输入端在内部直接连接内部基准源或者温度测量单元上,我们没有使用监视器,设置为000.
  4. SYS0寄存器(此位非常重要!):[7]此位必须始终设置为0,手册上这样说,[6:4]此位用于设置内部增益PGA,000-111分别对应放大倍数1、2、4、8、16、32、64、128倍。[3:0]此位用于设置ADC的输出速率,0000-1000分别对应5、10、20、40、80、160、320、640、1000SPS,1001-1111对应2000SPS,一般我们如果要输出速率为2000SPS时设置为1111,当然1001也是可以的。
  5. OFC1/OFC1/OFC2寄存器:三个寄存器组成了ADC24位偏移校准字。24位字是两种补体格式,内部向左移以与ADC24位转换结果对齐。ADC在全比例操作前从转换结果中减去寄存器值。默认此位不做配置
  6. FSC0/FSC1/FSC2寄存器:三个寄存器组成了ADC24位全标度校准字。这个24位的字是直接的二进制字。ADC将寄存器值除以FSC寄存器400000h,得到校准的比例因子。在偏移校准后,ADC将比例因子乘以转换结果。当PGA设置改变时,经过后的FSC重置值自动加载。此位需要配置为0x400000,此位需要注意,要记得配置
  7. IDAC0寄存器:[7:4]此位只读,TI编程的位,用于版本标识。[3]此位用于设置DRDY/DOUT仅作为输出功能或时作为数据准备和数据输出功能。[2:0]此位用于使能两个励磁电流源(IDACs),可用于传感器激励,默认此位不做配置
  8. IDAC1寄存器:[7:4]此位为选择了第一励磁电流源的输出引脚,[3:0]此位为选择了第二励磁电流源的输出引脚,默认此位不做配置
  9. GPIOCFG/GPIODIR/GPIODAT寄存器:用于IO口扩展,因为此器件时SPI传输,可以通过单片机配置寄存器直接操作ADC上的IO口,用作IO口的扩展,默认此位不做配置

ADS1248/1247程序编写

写寄存器:


提示:手册说的很清楚,第一个命令字节:0100 rrrr,其中rrrr是要写入的第一个寄存器的地址。第二个命令字节:0000 nnnn,其中nnnn是要写入的字节数-1。字节(s):要写入寄存器的数据。
所以我们按照手册的方法来写:

static void ADS1248_WriteReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length)
{   uint8_t Cmd[2];  ADS1248_CLR_CS;ADS1248_SET_START;HAL_Delay(20);/*ADS1248芯片手册规定的发送数据格式*//*First Command Byte: 0100 rrrrwhere rrrr is the address of the first register to be written.*/Cmd[0] = ADS1248_CMD_WREG | (RegAddr & 0x0F);  /*Second Command Byte: 0000 nnnn, where nnnn is the number of bytes to be written – 1*/Cmd[1] = (Length - 1) & 0x0F;/*指定向指定寄存器写入指定字节数据*/HAL_SPI_Transmit(&hspi3, Cmd, 2,HAL_MAX_DELAY);/*Byte(s): data to be written to the registers.*/HAL_SPI_Transmit(&hspi3, Buffer, Length,HAL_MAX_DELAY);HAL_Delay(20);ADS1248_SET_CS;ADS1248_CLR_START;
}

我们先定义一个cmd的数组,然后将CS片选拉低,START置高,然后进行数据的拼接,在第一个字节里发送0x04然后将要写的寄存器进行或操作,这样就完成了手册中说的前四个位是写命令,后四个位是要写的寄存器,后面跟着要给这个寄存器写的数据。

读寄存器:


提示:还是按照手册来,先进行数据拼接然后读出要的数据,这里TI给出的是:在读取寄存器数据时,不可能使用串行接口的全双工特性。例如,在读取VBIAS和MUX1数据时,不能发出SYNC命令,如图84所示。在读出寄存器数据期间发送的任何命令都将被忽略。因此,TI建议在读出寄存器数据时通过DIN发送nop。

void ADS1248_ReadReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length)
{uint8_t Cmd[2];ADS1248_CLR_CS;ADS1248_SET_START;/*ADS1248芯片手册规定的发送数据格式*//*First Command Byte: 0010 rrrr, where rrrr is the address of the first register to read.*/Cmd[0] = ADS1248_CMD_RREG | (RegAddr & 0x0f);  /*Second Command Byte: 0000 nnnn, where nnnn is the number of bytes to read –1*/Cmd[1] = (Length - 1) & 0x0f;/*发送读取指令*/HAL_SPI_Transmit(&hspi3,Cmd,2,HAL_MAX_DELAY);   /*接收数据*/    HAL_SPI_Receive(&hspi3, Buffer, Length, HAL_MAX_DELAY);     Cmd[0] = ADS1248_CMD_NOP;  /*接受数据时不能使用SPI的全双工,要发送nop,此为手册原句*//*It is not possible to use the full-duplex nature of the serial interface when reading out the register data. Forexample, a SYNC command cannot be issued when reading out the VBIAS and MUX1 data, as shown inFigure 84. Any command sent during the readout of the registerdata is ignored. Thus, TI recommends sendingNOPs through DIN when reading out the register data.*/HAL_SPI_Transmit(&hspi3, Cmd,1,HAL_MAX_DELAY); HAL_Delay(20);ADS1248_SET_CS;
}

还是和写寄存器一样,先进行指令的拼接,然后通过SPI直接将数据读出来,读数据的时候持续发送nop,因为TI说了在读数据的时候不能进行写操作,否则命令将会被忽略。

配置ADS1248/1247寄存器:

    uint8_t Cmd = 0; /*对ADC进行复位*/ADS1248_Reset();                                                                        HAL_Delay(20);       /*配置MUX0寄存器AIN0为正输入,AIN1为负输入*/Cmd = 0x08;/*0000 0001*/                    ADS1248_WriteReg(ADS1248_MUX0,&Cmd,1);      /*配置MUX1使用内部2.048基准、打开内部基准源*/Cmd=0x30 ;/*0 01 00 000*/ADS1248_WriteReg(ADS1248_MUX1,&Cmd,1);                                                                                                           /*配置SYS0寄存器PGA为放大64倍,输出速率为20SPS*/Cmd=0x62;/*0 110 0010*/ADS1248_WriteReg(ADS1248_SYS0,&Cmd,1); /*配置IDAC0不使能DRDY、关闭激励*/Cmd=0x00 ;/*0000 0000*/ADS1248_WriteReg(ADS1248_IDAC0,&Cmd,1);                   /*配置IDAC1寄存器不选择励磁电流源引脚、不使能引脚*/Cmd=0xFF;/*1111 1111*/   ADS1248_WriteReg(ADS1248_IDAC1,&Cmd,1);         /*配置FSC0为00*/Cmd=0x00;/*0010 0000*/        ADS1248_WriteReg(ADS1248_FSC0,&Cmd,1); /*配置FSC1为00*/Cmd=0x00;/*0000 0000*/     ADS1248_WriteReg(ADS1248_FSC1,&Cmd,1); /*配置FSC2为40,在公式中需要除以常数0x400000*/Cmd=0x40;/*0000 0100*/       ADS1248_WriteReg(ADS1248_FSC2,&Cmd,1);     HAL_Delay(20);    /*拉高START准备ADC转换*/ ADS1248_CLR_START;

上面的代码是上电对ADS1248/1247进行一个寄存器的配置,配置完之后选择持续转换,这样就可以一直获取到数据了。

读数据:

提示:因为此ADC是24位的ADC,最高位是符号位,所以有23位的分辨率,最大值是8388608,24位的数据我们用数据进行移位拼接,将最高位左移16位,第二位左移8位,最后一个直接获取,之后将数据相加即可得到我们要的最终数据,手册上写了内置滤波器,所以我们不需要在用软件滤波,直接读取数字量即可。

int32_t ADS1248_Read(void)
{/*定义发送的读取指令,后面三个是空操作等待ADC相应*/uint8_t  Cmd[4]={ADS1248_CMD_RDATAC,ADS1248_CMD_NOP,ADS1248_CMD_NOP,ADS1248_CMD_NOP};int32_t  i32Data = 0;int32_t  i32Data0 = 0;int32_t  i32Data1 = 0;int32_t  i32Data2 = 0;uint8_t  Buf[4] = {0};/*开启转换*/   ADS1248_SET_START;/*等待转换结束*/if(ADS1248_Wait() == 0){ADS1248_CLR_CS;/*读取ADC数据保存在BUF中*/HAL_SPI_TransmitReceive(&hspi3,Cmd,Buf,4,HAL_MAX_DELAY);     ADS1248_SET_CS;     ADS1248_CLR_START;  /*24位ADC数据进行拼接*/i32Data0 = Buf[0];i32Data0 = i32Data0 << 16;i32Data1 = Buf[1];i32Data1 = i32Data1 << 8;        i32Data2 = Buf[2];     i32Data = i32Data0 + i32Data1 + i32Data2;return i32Data;      }else{return 0;}
}

这样的写法我也知道很蠢,但是比较直观,也可以将buf0直接左移,将buf1直接左移之后直接进行或操作也可以实现数据获取,也不用定义这么多变量,即下面这样写。

i32Data=Buf[0]<<16|Buf[1]<<8|Buf[2];

开启转换

开启转换很简单,只需要将START引脚拉高即可,关闭转换也只需要把START引脚拉低即可。

GPIO初始化

这部分不用说了,凡是看这篇文章的肯定都会,只是配置IO推挽输出和输入,DRDY为输入,CS和START为推挽输出,可以根据需要修改IO的宏定义。

void Ads1248Init(void)
{/*初始化各个引脚*/GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = ADS1248_CS_PIN | ADS1248_START_PIN | ADS1248_RST_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);    __HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = ADS1248_DRDY_PIN;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_9;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
}}

H文件的定义如下:

/*RST复位引脚*/
#define ADS1248_RST_PIN         GPIO_PIN_9
#define ADS1248_RST_GPIO        GPIOA
#define ADS1248_SET_RESET       HAL_GPIO_WritePin(ADS1248_RST_GPIO, ADS1248_RST_PIN, GPIO_PIN_SET)
#define ADS1248_CLR_RESET       HAL_GPIO_WritePin(ADS1248_RST_GPIO, ADS1248_RST_PIN, GPIO_PIN_RESET)
/*开始使能引脚*/
#define ADS1248_START_PIN       GPIO_PIN_10
#define ADS1248_START_GPIO      GPIOA
#define ADS1248_SET_START       HAL_GPIO_WritePin(ADS1248_START_GPIO, ADS1248_START_PIN, GPIO_PIN_SET)
#define ADS1248_CLR_START       HAL_GPIO_WritePin(ADS1248_START_GPIO, ADS1248_START_PIN, GPIO_PIN_RESET)
/*DRDY引脚*/
#define ADS1248_DRDY_PIN        GPIO_PIN_11
#define ADS1248_DRDY_GPIO       GPIOA
#define ADS1248_DRDY_READY      HAL_GPIO_ReadPin(ADS1248_DRDY_GPIO,ADS1248_DRDY_PIN)
/*CS片选引脚*/
#define ADS1248_CS_PIN          GPIO_PIN_15
#define ADS1248_CS_GPIO         GPIOA
#define ADS1248_SET_CS          HAL_GPIO_WritePin(ADS1248_CS_GPIO, ADS1248_CS_PIN, GPIO_PIN_SET)
#define ADS1248_CLR_CS          HAL_GPIO_WritePin(ADS1248_CS_GPIO, ADS1248_CS_PIN, GPIO_PIN_RESET)

注意事项


手册写的很清楚,差分输入的电压正负都需要计算,差模输入,意味着负输入端不可直接接地,接地会引发不可预知的错误。我遇到的错误是AD值不准,PGA = 16以上会引发线性度畸变。

下面贴出实测的线性度和数据

应用电路

ADS1248/1247(TI) 24位ADC详细配置说明相关推荐

  1. 开源:ADS1255+STM32G0,24位adc,五位半电压表

    1.项目背景 2015年5月份评估完十几种24位ADC后就从第一份工作岗位上离职了,做的24位AD都没有达到实际的效果,一直耽搁困扰了好久.是硬件设计的问题?还是软件开发的问题?还是24位ADC真的不 ...

  2. 称重传感器及HX711 24位ADC的重量参数检测

    一.HX711 24位ADC HX711采用了海芯科技集成电路专利技术,是一款专为高精度电子秤而设计的24位A/D转换器芯片.与同类型其它芯片相比,该芯片集成了包括稳压电源.片内时钟振荡器等其它同类型 ...

  3. 蓝牙芯片|伦茨科技全新24位ADC蓝牙芯片-ST17H69

    不同类型的医疗产品,血氧仪.血压计.红外体温计.呼吸机.核磁共振仪.超声仪.CT扫描仪等,每个产品内都有ADC芯片.ADC芯片好比人脑,能将各类传感器(好比手眼口鼻)感知和采集的电气信号转化成数字信号 ...

  4. TI的ADS1299国产替换方案 - ADSD1299(24位ADC芯片)

    各位网友人们好,这两年席卷全球的"缺芯潮"相信大家都记忆尤新,虽说目前情况略微有些好转,但整体市场呈现出的现状是芯片还是非常紧缺,尤其是对于一些高端的和特殊行业的模拟芯片,像用在医 ...

  5. ES8218E低功耗24位ADC芯片 可直接接麦克风

    苏州顺芯ES8218 24位8-96KHZ采样率,单通道,I2s / pcm 主 / 从串行数据端口,低功耗,立体声,音频ADC模拟转数字芯片!总谐波失真加噪声为-85dB,信噪比为95dB! 1.8 ...

  6. 24位ADC数据转换,保存为hex文件,并利用python解析hex文件画图

     目前有许多ADC芯片都是24位精度的,这个位数稍显尴尬,因为在常用的变量类型中,有8bit.16bit.32bit,唯独没有24bit,这就导致我们在很多情况下,需要自己敲代码去处理这个24bit的 ...

  7. 基于24位Δ-ΣADC和FPGA的高精度数据采集系统开发

    欢迎订阅<FPGA学习入门100例教程>.<MATLAB学习入门100例教程> 目录 一.理论基础 二.核心程序 三.测试结果 一.理论基础

  8. DIY仪表24位ADC,锂电池供电可充电,变态级精度、线性度和...

    先来说下板子功能,所有参数精度绝对实打实的和DMM7510仪表对照过,有图有真相的 主控STM32L,显示OLED 0.96英寸,电压都是用三点校准的方法用STM32L自带EEPROM保存参数,电流是 ...

  9. STM32 MCO+SPI获取24位模数转换(24bit ADC)高速芯片ADS1271采样数据

    STM32 MCO+SPI获取24位模数转换(24bit ADC)高速芯片ADS1271采样数据 STM32大部分芯片只有12位的ADC采样性能,如果要实现更高精度的模数转换如24位ADC采样,则需要 ...

最新文章

  1. Paging of Large Resultsets in ASP.NET中介绍的SET ROWCOUNT方式存储过程的问题
  2. 2020-11-23(Windows系统的dll注入 )
  3. awk -f 分隔符 命令_千面 awk
  4. SAP Spartacus delivery mode页面Cannot find control with的错误消息
  5. android显示布局边界的边距_Android设计规范 Material Design-Layout(2 度量与边框)
  6. Oracle加密解密
  7. 北林oj-算法设计与分析-Line up in the canteen(两种解法,附思路)
  8. 检查点和oracle数据库的恢复(一)SCN
  9. 面试官:Java 线程如何启动的?
  10. MySQL基础 - 注意事项
  11. php 同步退出,phpcms phpsso不能同步退出怎么办
  12. OC字符串相加,结果按照字符串形式输出
  13. 安装程序无法验证产品密钥解决方案
  14. 07 -MATLAB数值微积分与方程求解
  15. php 身份证格式校验,年龄计算
  16. 目标检测系列——Faster R-CNN原理详解
  17. 朋友圈集赞万能截图生成器威信小程序源码下载
  18. 360与百度研发工程师的待遇,工作环境全面对比
  19. IDEA新建本地项目关联远程本地仓库和git仓库详细步骤
  20. linux 恢复 raid5数据,Raid5数据恢复案例(raid阵列数据恢复方法)

热门文章

  1. 第一个页面作品--个人网页导航
  2. java格式化星期是什么意思_用Java的EEEE格式格式化星期几
  3. Java //PP2.6 编写一个应用程序,将英里转换为千米(1英里等于1.60935千米)。以浮点数类型读取用户输入的英里数
  4. 微信jssdk分享开发经验
  5. 电源、信号完整性与高速电路
  6. Win7配置修改neighbor
  7. wps姓名隐藏为星号_在wps表格中如何将数字设置为星号显示
  8. 计算机毕业设计Java大学校友信息管理系统(源码+系统+mysql数据库+lw文档)
  9. ES-查询相关和IK分词器
  10. 洛谷1498 南蛮图腾