资讯动态

ADS1256高精度ADC开发实战:从SPI时序到数据滤波

发布时间:2026/9/15 5:20:18 来源:尧图企业网站定制
简介这份RAR压缩包汇集了ADS1256模块V0.3的完整开发资料定位清晰面向嵌入式开发者、电子工程师以及需要高分辨率数据采集的项目实践者。资源共433个文件压缩包大小约12.41MB主要包含C语言源文件、头文件、编译中间文件、PDF数据手册、Keil工程、Hex烧录文件、批处理脚本以及基于STM32的例程代码覆盖从源码编写到编译烧录的完整链路。已有535人参与学习说明内容具备实际参考价值。ADS1256是一款二十四位低噪声的Σ-Δ型模数转换器资料不仅演示了SPI总线连接方式、可编程增益放大器配置、DRDY引脚检测等关键操作还提供了寄存器配置思路与调试方法方便快速上手并处理数据读取问题随附的工程模板和说明文档可直接用于移植适合医疗设备、环境监测、工业控制等对精度和噪声要求较高的测量场景。1. ADS1256 模块资料里的“DS1256”到底是什么搜索引擎里搜“DS1256”会返回大量ADS1256模块资料这个DS多半是资料整理时的笔误正主是TI的ADS1256。它是一颗24位Δ-Σ型模数转换器集成8路模拟输入、可编程增益放大器和SPI接口低速高精度场景下的噪声性能远好于普通SAR型ADC。称重、温度、压力、应变信号采集里都能看到它。模块资料包里的“例程”大多基于STM32或51平台真正吃透之后换到GD32、ESP32甚至树莓派都只是改底层SPI读写的问题。这篇文章把硬件接法、寄存器配置、数据换算、滤波逻辑串成一条完整链路新手可以按步骤跑通老手也能看到容易忽略的时序边界。2. 硬件连接与 SPI 时序让 ADS1256 跑起来的 4 个关键点2.1 引脚定义与最小系统接线ADS1256的供电分模拟和数字两路模块板通常把AVDD接5V、DVDD接3.3V这样在2.5V参考下模拟输入范围能达到±5V。VREF引脚是内部转换的参考输入模块自带2.5V基准时把它和基准输出直接相连。如果自己画板或做高精度应用外部基准芯片比直接用电源更稳。布局阶段就要把模拟地和数字地分开在电源入口单点汇合别等画完板再飞线。功能模块引脚接到MCUSPI时钟SCLKSPI_SCKSPI数据输入DINSPI_MOSISPI数据输出DOUTSPI_MISO片选CS任意GPIO数据就绪DRDY外部中断或GPIO复位RESET任意GPIO同步SYNC任意GPIOAGND和DGND在模块上通常已经连通自己画板时两个地只在电源入口汇合避免数字开关噪声通过地平面耦合进模拟回路。模拟电源AVDD建议放10μF钽电容和0.1μF陶瓷电容并联去耦离引脚越近越好。VREF引脚对去耦更敏感加一个0.1μF电容且走线短粗因为参考电压上的任何纹波都会直接进转换结果的最低位。模块资料里的PDF原理图要先看电源网络命名再看VREF生成电路最后确认DRDY是否直接引出这三处决定后续接线方式。2.2 SPI 模式与 3 个容易踩的时序坑ADS1256使用SPI模式1CPOL0CPHA1SCLK空闲为低电平数据在第二个边沿采样。STM32 HAL库的初始化参数如下// SPI 初始化以 STM32 HAL 库为例 SPI_InitTypeDef spi {0}; spi.Mode SPI_MODE_MASTER; spi.Direction SPI_DIRECTION_2LINES; spi.DataSize SPI_DATASIZE_8BIT; spi.CLKPolarity SPI_POLARITY_LOW; // CPOL 0 spi.CLKPhase SPI_PHASE_2EDGE; // CPHA 1SPI 模式 1 spi.NSS SPI_NSS_SOFT; spi.BaudRatePrescaler SPI_BAUDRATEPRESCALER_32; // 先跑低速率跑通后再提高CLKPolarity若改成SPI_POLARITY_HIGH就是模式3协议对不上读回的数据全是0xFF。模式1和模式3的差别只在SCLK空闲电平数据采样边沿其实一样所以问题比想象中隐蔽用示波器不一定看得出来要配合逻辑分析仪按字节解析。第一个坑是DIN和DOUT方向。模块丝印一般标DINMOSI、DOUTMISO但个别板子会反先量一下这两个引脚在通信期间有没有电平翻转别急着改代码。第二个坑是SCLK频率。ADS1256的SCLK上限按数据手册典型值是1.92MHz与主时钟有关STM32上应选择预分频后明显低于上限的档位不要一上来就开几千兆赫兹的高速跑通功能后再逐步提高。第三个坑是复位时间。RESET拉低再拉高后要让内部振荡器稳定一般等50μs再发RESET命令后又等25μs之后DRDY才会给出正确信号。把顺序倒过来芯片可能还在复位状态读到的STATUS全是0xFF。快速验证SPI时序是否正常用逻辑分析仪抓一次写DRATE寄存器的波形CS拉低后应该依次出现0x53、0x00、速率值再CS拉高。如果0x53变成0x54说明地址位错位如果后面没有数据字节说明第二个字节被当成了数据。这个过程比反复改代码高效得多。2.3 上电复位与 DRDY 引脚的信号意义DRDY是推挽输出平时高电平每完成一次转换拉低一段时间。它也是自校准完成和复位完成的信号标志因此在下落沿中断里置位的“数据就绪”标志不能假设只代表转换结束。多片ADS1256共用SPI时每片DRDY独立主控用中断加查询分别等待。提示CS拉高后芯片内部转换继续运行DRDY照常拉低。要暂停数据流用SYNC引脚或WAKEUP命令不能靠CS。我把DRDY接到MCU的外部中断引脚下降沿触发中断里只置一个标志位主循环处理。这样在30kSPS下也不会阻塞SPI通信。如果不方便用中断轮询DRDY也可以但要注意轮询间隔必须小于一个转换周期否则会漏掉标志。3. 寄存器初始化与自校准写驱动前必须懂的 8 个寄存器3.1 8 个关键寄存器的功能与复位值寄存器操作通过WREG和RREG命令完成。WREG命令第一字节是0x50加寄存器地址第二字节是寄存器数量减一之后是待写数据。RREG命令第一字节是0x20加寄存器地址第二字节同样是数量减一随后读回数据。8个关键寄存器如下寄存器地址复位值作用STATUS0x000x01DRDY镜像、复位标志MUX0x010x01正负输入通道选择ADCON0x020x20时钟倍率、PGA增益DRATE0x030xF0输出数据速率IO0x040x00GPIO方向与输出OFC0..OFC20x05..0x070x000000偏移校准系数FSC0..FSC20x08..0x0A0x800000满量程校准系数STATUS寄存器的bit0是DRDY实时状态镜像有些例程不读DRDY引脚而靠读STATUS轮询省GPIO但多SPI开销。MUX寄存器高4位选正输入、低4位选负输入单端模式的负输入固定为AINCOM。ADCON寄存器里D6:D4是时钟倍率选择位D2:D0是PGA增益位DRATE寄存器直接决定输出速率具体速率与主时钟频率强相关。读寄存器验证配置是排查问题的惯用手段uint8_t ADS1256_ReadReg(uint8_t addr) { CS_LOW(); SPI_Byte(0x20 | addr); // RREG 命令带寄存器地址 SPI_Byte(0x00); // 读 1 个寄存器 uint8_t val SPI_Byte(0xFF); CS_HIGH(); return val; }3.2 初始化流程从复位到 SELFCAL 的完整序列芯片上电后默认处于RDATAC连续输出模式此时直接写寄存器无效。先发SDATAC再写配置。完整顺序为拉高CSRESET拉低10μs再拉高等待50μs拉低CS发送RESET命令0xFE等待25μs发送SDATAC命令0x0F退出连续输出模式依次写入MUX、ADCON、DRATE寄存器发送SELFCAL命令0xF0等待自校准完成static void ADS1256_Reset(void) { CS_HIGH(); RESET_LOW(); delay_us(10); RESET_HIGH(); delay_us(50); CS_LOW(); SPI_Byte(ADS1256_CMD_RESET); // 0xFE硬件复位命令 delay_us(25); SPI_Byte(ADS1256_CMD_SDATAC); // 0x0F退出连续输出模式 CS_HIGH(); } static void ADS1256_WriteReg(uint8_t addr, uint8_t data) { CS_LOW(); SPI_Byte(0x50 | addr); // WREG 命令带寄存器地址 SPI_Byte(0x00); // 后续写 1 个寄存器 SPI_Byte(data); CS_HIGH(); }SELFCAL自校准包含偏移校准和增益校准耗时随DRATE设置而变化高速率档位下只有几十毫秒最低速率档位下可能超过一秒。等待期间不要发起其他SPI操作。等待完成的可靠方式不是固定延时而是轮询DRDY引脚见下面的代码void ADS1256_SelfCal(void) { CS_LOW(); SPI_Byte(ADS1256_CMD_SELFCAL); // 0xF0 CS_HIGH(); uint32_t timeout 1000000; while (DRDY_READ() ! 0 timeout--); // 等待自校准完成 }自校准完成后DRDY会拉低一次但复位完成后它也可能拉低所以发送SELFCAL前应先确认前一个DRDY周期已经结束或者给一个较长超时。这个方式比固定延时更可靠也是很多例程里唯一缺失的细节。3.3 初始化代码与参数选择ADCON寄存器里时钟倍率位和PGA位都要正确设置。PGA16时低三位为100时钟位保持复位值不变这样输出速率不受影响。改增益时只动低三位时钟位最好别动否则速率跟着变滤波参数也要重调。DRATE档位参考输出速率(kSPS)适用场景30高频快速扫描25通用默认10常规数据采集2.5低噪声测量0.125极低速高分辨率这些速率以7.68MHz主时钟为基础换用其他晶振时输出速率按比例折算。直接抄别人代码里的DRATE值硬件晶振不同实际速率会差一截这是很多“例程能用、自己写就不对”的根源。速率越低内置数字滤波器带宽越窄、有效分辨率越高但建立时间变长。多通道扫描时切换后必须等至少一个完整的转换周期再读数否则混入上一通道的残余信号。4. 数据读取与数字滤波从原始码到工程值的完整链路4.1 DRDY 下降沿与 RDATA 命令读取数据的标准姿势是等DRDY变低CS拉低发RDATA命令0x01连续读三字节CS拉高。RDATAC连续模式则不需要发RDATADRDY低电平时直接读三个字节。下面这段单次读取代码在低速档位没问题在30kSPS下会把主循环阻塞几十微秒uint32_t ADS1256_ReadData(void) { while (DRDY_READ() ! 0); // 等待DRDY变低 CS_LOW(); SPI_Byte(ADS1256_CMD_RDATA); // 0x01 uint8_t h SPI_Byte(0xFF); uint8_t m SPI_Byte(0xFF); uint8_t l SPI_Byte(0xFF); CS_HIGH(); return ((uint32_t)h 16) | ((uint32_t)m 8) | l; }如果需要高吞吐建议把读取放进状态机或改用DMA在DRDY中断里读三字节到缓冲区主循环只做换算和滤波。中断里只置标志位具体读写放到主循环volatile uint8_t drdy_flag 0; void DRDY_EXTI_IRQHandler(void) { drdy_flag 1; // 置位后主循环统一处理 }RDATAC模式适合固定通道连续采样但进入后只有SYNC、SDATAC等少数命令可用重新配置寄存器前必须先SDATAC退出否则后续指令会被当成数据。读回的三字节是24位数据高位在前。拼接时注意先把最高字节左移16位不要把字节顺序搞反。很多“数值跳变”的故障其实是字节序错了而不是ADC本身有问题。4.2 原始码到电压的换算公式ADS1256输出是24位二进制补码正满量程0x7FFFFF负满量程0x800000。换算公式V_in (raw_signed / 2^23) * V_ref / PGA其中raw_signed是补码转换后的有符号整数。如果直接把uint32_t强转成float去乘负电压会算出一个接近满量程的大数。补码转换在C里可以这样写int32_t raw_signed; if (raw 0x800000) { raw_signed (int32_t)(raw - 0x1000000); } else { raw_signed (int32_t)(raw); }参考电压V_ref一定要用实测值。模块上的2.5V基准实际输出可能是2.499V或2.501V在24位分辨率下按2.5V算出来的误差会积累成几十个LSB。PGA增益也有同样问题传感器输出50mV、PGA32输入范围约±156mVVREF5V时如果换算时忘记除32电压值会放大32倍。这个错误在接线正确、读数稳定的情况下最隐蔽排查时可以切换PGA1看读数是否等比变化。举个例子VREF2.5V、PGA1时raw41943040x400000即2^22实际电压是1.25V。如果raw0x800000负满量程补码转换后是-8388608电压为-2.5V。差分模式下符号还与MUX的正负接法有关接反时读数整体取反在软件里统一翻转比在硬件上交叉线更省事。4.3 均值滤波与中值滤波的取舍芯片内置数字滤波器已经滤掉大部分带外噪声但在有工频干扰或开关电源的现场软件滤波仍能提升稳定性。三种常见方法的选型参考滤波方式适用信号常用参数延迟滑动平均温度、压力等缓变信号16~32点窗口/2个采样周期中值滤波带尖峰脉冲的称重信号3~5点约窗口/2个采样周期一阶低通需要平滑显示的趋势α0.1~0.31~3个采样周期滑动平均用环形缓冲区实现窗口长度取16时右移4位代替除法减少MCU指令开销// 16 点滑动平均环形缓冲区实现 static int32_t buf[16]; static uint8_t idx 0; static int64_t sum 0; int32_t Filter_AddSample(int32_t sample) { sum - buf[idx]; buf[idx] sample; sum sample; idx (idx 1) 0x0F; return (int32_t)(sum 4); }缓冲区不用清零因为热启动时sum的初值会随着新样本逐渐覆盖旧值跑几百个采样点后误差自然消除。中值滤波对野值更鲁棒但输出有延迟不适合快速变化的信号。两者串联时先做中值剔除野值、再做滑动平均比反过来效果好。实际项目中先用上位机记录原始码画出波形再选滤波参数不要一上来就上重滤波。5. 多通道扫描与 PGA 增益高精度采集的 3 个实用技巧5.1 MUX 配置与通道切换时序MUX寄存器高4位是正输入低4位是负输入。以单端通道为例正输入从AIN0到AIN7负输入固定为AINCOM寄存器值统一写成(channel 4) | 0x08。切换通道后不能立即读数芯片内部输入滤波电容需要重新建立电压经验做法是丢第一次读取结果或者等两个DRDY周期。高速扫描时若只关心部分通道把不用的通道统一接到同一个固定电位可以缩短输入回路的建立时间。5.2 PGA 增益与有效分辨率的关系PGA不是越大越好。PGA1时输入范围最大PGA64时最小增益提升会同时放大信号和噪声。增益过高后输入放大器的噪声和失调占据主导有效分辨率反而下降。选增益的出发点是传感器满量程输出让最大信号经过PGA后接近ADC满量程而不是削峰。例如传感器满量程40mVPGA32、VREF2.5V时最大输入约78mV保留约一倍裕量既不用PGA64冒险也能拿到足够分辨率。5.3 用 SYNC 引脚做同步采样多片ADS1256或与外部ADC同步启动时把SYNC引脚连到同一GPIO配置好所有芯片后给SYNC一个下降沿再拉高所有芯片同时开始转换。SYNC保持低电平时转换暂停拉高后恢复。单芯片多通道扫描时也可以靠SYNC消除通道切换毛刺先写MUX再给SYNC脉冲等DRDY后读到的就是新通道数据。void ADS1256_SyncStart(void) { SYNC_HIGH(); delay_us(1); SYNC_LOW(); delay_us(1); SYNC_HIGH(); }脉冲宽度超过一个SCLK周期即可1μs延时足够覆盖常见SPI频率。多片级联时先分别完成复位和寄存器配置再统一触发。用逻辑分析仪同时抓SYNC和DRDY确认所有芯片在同一时刻开始转换DRDY下降沿也应该对齐偏差在微秒级以内。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价