十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ADS1118实战:基于SPI的16位ADC与温度传感器驱动开发指南

ADS1118实战:基于SPI的16位ADC与温度传感器驱动开发指南 简介面向STM32嵌入式开发者这份源码包以STM32F407为主控实现了ADS1118高精度16位ADC的完整驱动覆盖PGA增益配置、SPI/I²C接口通信、转换数据读取与中断处理等关键环节可直接参考或移植到工业采集、传感器接口等场景。包体共174个文件、3.83MB以C源文件46个与头文件47个为核心同时包含Keil工程配置uvprojx、编译生成的axf/hex及map等文件便于在MDK环境中直接查看构建结果。已有472人学习使用。资料内除ADS1118驱动外还保留了基于STM32F407的LED、定时器、LCD等相关基础工程源码适合需要对照学习寄存器配置和驱动框架的开发者能有效缩短外设驱动开发与调试时间。1. ADS1118 是什么一个带温度传感器的 16 位 SPI ADC第一次接触 ADS1118 的人通常会把它和 ADS1115 搞混毕竟型号只差一位功能也都是 16 位 ADC。但真正用起来你会发现这两个芯片的脾气完全不同ADS1115 走 I2C而 ADS1118 走 SPIADS1115 没有内置温度传感器ADS1118 却有而且精度相当不错。如果你正在设计的板子上已经没有多余的 I2C 总线或者你需要顺带监测板温ADS1118 几乎是天然的选择。这颗芯片的核心价值在于一颗 2mm×1.25mm 的 VSSOP 封装里集成了 4 路模拟输入可配置为 2 路差分或 4 路单端、可编程增益放大器PGA、内部基准、温度传感器、振荡器和 SPI 接口。你不需要外接基准源——虽然也可以外接。功耗在关断模式下只有 0.2µA 左右非常适合电池供电的采集节点。我们团队之前在做一个多通道环境监测终端时用一片 ADS1118 替代了原有的“I2C ADC 分立温度传感器”方案BOM 成本降了约 30%PCB 面积省了 40% 以上。当然代价是 SPI 的时序调试比 I2C 略费一些功夫尤其是连续读取模式下帧边界容易出错后面我会详细讲。2. 理解 ADS1118 的配置寄存器三种模式和数据速率的选择逻辑2.1 16 位配置字的位段拆解ADS1118 的配置寄存器只有 16 位通过 SPI 写入。和大多数 ADC 不同它的读写机制是“先写后读”你先写入一个 16 位配置字然后下一次 CS 低电平期间芯片返回上一次写入配置字所对应的转换结果。也就是说每次 SPI 事务同时完成“发起下一次转换”和“读取上一次结果”两个动作。配置字的位段如下位号名称功能说明15SS启动/停止转换单次模式下置 1 启动14:12MUX[2:0]输入多路选择AINP/AINN 配对11:9PGA[2:0]增益设置F SR 从 ±6.144V 到 ±0.256V8MODE1单次模式0连续模式7:5DR[2:0]数据速率8 SPS 到 860 SPS4TS_MODE0ADC 模式1温度传感器模式3PULL_UP_EN内部上拉电阻使能用于热电偶检测2NOP必须写 01:0保留写 0这里最容易出错的位是位 15。在数据手册中它写作 SS (Start/Start Conversion)但实际作用是在单次模式下写入 1 启动一次转换转换完成后该位自动清零。很多初学者直接把这个位当作“使能位”连续写 1 在单次模式下反而会导致转换还没完成就开始下一次写入时序上可能触发错误读取。我一般建议如果采样率不超过 100 SPS就用单次模式每次读取前重新写入配置字如果需要更高吞吐量再切换连续模式。2.2 单次模式与连续模式时序差异和适用场景单次模式的好处显而易见每次转换都是电源上电后触发的工作序列ADC 内部在转换间隙完全关断功耗极低。对于电池供电的无线传感器节点100 SPS 以内的采集频率用单次模式就够了。而连续模式意味着芯片始终保持内部时钟振荡器运行转换以固定节拍进行此时你只需要在首次写入配置字后持续读取数据即可不需要反复写配置字——但要注意每次读取仍然需要写入一个 16 位字来维持 SPI 时钟通常写全 0 即可。这两种模式对应的代码逻辑差异其实不大区别在于你主控侧的状态机。单次模式是“写配置→等转换完成→读结果→再写配置”连续模式是“写配置→循环读结果→读结果→读结果”。在等转换完成时可以拉高 DOUT/DRDY 引脚来检测转换完成事件也可以直接延时等待延时时间按数据速率表估算比如 128 SPS 时单次转换需约 9ms。我建议用 DOUT/DRDY 引脚触发中断或轮询因为 ADS1118 的转换完成信号是一个下降沿挂一个 GPIO 中断比盲目 sleep 可靠得多。2.3 数据速率选择8 SPS 到 860 SPS 的实际取舍ADS1118 的 PGA 和 DR数据速率是相互影响的。数据速率高内部滤波器带宽就宽噪声也相应增大数据速率低数字滤波器抑制噪声的能力强有效分辨率更接近 16 位无噪声。这个规律在数据手册的“Noise Performance”表里有详细数据但在工程上我总结的经验是测量电池电压、温度这类缓变信号选 8 SPS 或 16 SPSPGA 设置为 ±4.096V 或 ±2.048V可以发挥出接近 16 位的有效分辨率ENOB 约 15 位左右。监测电源纹波或电机电流波形至少需要 128 SPS 以上此时有效位数大约在 1314 位不要期待 16 位精度。高于 475 SPS 的档位只适合用来观察信号粗略波形不适合做精确计量。温度传感器模式下的数据速率固定为 8 SPS 内部时钟写 DR 位不影响温度转换速率但会影响后续切回 ADC 模式后的行为。所以如果你在温度模式和 ADC 模式之间来回切换最好每次切换时都显式设置完整的配置字不要依赖上一次写入的残留值。3. 最小系统搭建从原理图到 STM32 上的 SPI 驱动代码3.1 硬件连接和去耦设计ADS1118 的前端是开关电容输入结构驱动它的信号源需要有足够的电流输出能力。如果你直接用高阻抗分压电阻比如 100kΩ 级别的分压网络接 AIN0会发现读数跳得厉害——这是因为采样电容充放电引起的电荷注入。手册上建议信号源阻抗不超过 1kΩ但实际做产品时10kΩ 以内的源阻抗只要采样率不高816 SPS也能接受超过这个范围就需要加一个 100nF 的旁路电容到地或者在信号链路上加运放缓冲。去耦电容方面AVDD 和 DVDD 在 ADS1118 内部是连在一起的VSSOP 封装只有一个电源引脚所以只需在电源引脚对地放置一个 1µF 陶瓷电容同时尽量靠近引脚放一个 100nF 高频去耦电容。如果电路板上有数字电路或开关电源建议加一个 10Ω 串联电阻做电源滤波防止纹波串进基准源。SPI 连接上注意速度上限数据手册写的是 SCLK 最高 4MHzVDD3.3V 时。实际测试表明2MHz 以下最稳妥超过 2MHz 后 DOUT 数据在上升沿采样时建立时间偏低尤其使用杜邦线连接时容易读到错位数据。我一般把所有 ADS1118 挂到 SPI12MHz 时钟板内走线短时跑 4MHz 没问题但外接传感器板就降回 1MHz。3.2 单次模式读取的完整驱动代码以 STM32 HAL 库为例下面是一段经过验证的单次模式读取函数。这段代码的核心逻辑是写配置字到 TX 缓冲同时从 RX 缓冲读取上一次转换结果。注意 SPI 是全双工所以读和写同时发生千万不能用“先发后收”的方式去等。// 读取单次转换结果ADC 模式 // 参数: mux_ch 通道选择0~3 对应 AIN0/AIN1/AIN0~AIN3 // pga_gain 增益档位0~5 对应 ±6.144V ~ ±0.256V uint16_t ADS1118_ReadSingle(uint8_t mux_ch, uint8_t pga_gain) { uint16_t config 0; uint16_t rx_data 0; uint16_t tx_data 0; uint8_t tx_buf[2] {0}; uint8_t rx_buf[2] {0}; // 组装配置字 (16 位) config | (1 15); // SS1: 启动单次转换 config | (mux_ch 12); // MUX 选择输入通道 config | (pga_gain 9); // PGA 增益 config | (1 8); // MODE1: 单次模式 config | (0b011 5); // DR011: 64 SPS数据速率位 config | (0 4); // TS_MODE0: ADC 模式 tx_buf[0] (config 8) 0xFF; tx_buf[1] config 0xFF; // CS 拉低启动 SPI 传输 HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_RESET); // 写配置字同时接收上一次转换结果无效数据丢弃 HAL_SPI_TransmitReceive(hspi1, tx_buf, rx_buf, 2, 100); // 等待转换完成轮询 DOUT/DRDY 引脚变低 // 在 STM32 上也可以用 EXTI 中断等待这里用超时轮询实现 uint32_t timeout 0; while (HAL_GPIO_ReadPin(ADS1118_DRDY_GPIO_Port, ADS1118_DRDY_Pin) ! GPIO_PIN_RESET) { HAL_Delay(1); timeout; if (timeout 100) break; // 超时保护100ms 足够 64SPS 转换 } // 再次发起 SPI 事务写任意值(全0)读取转换结果 tx_buf[0] 0x00; tx_buf[1] 0x00; HAL_SPI_TransmitReceive(hspi1, tx_buf, rx_buf, 2, 100); // CS 拉高结束事务 HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_SET); // 合成 16 位结果高字节在前 rx_data (rx_buf[0] 8) | rx_buf[1]; return rx_data; }代码逻辑说明第一次HAL_SPI_TransmitReceive把配置字发出去SPI 同时会收到旧数据这个数据没有意义直接丢弃。然后等待 DRDY 引脚变低表示转换完成。第二次 SPI 事务写入两个字节的 0任意值皆可因为此时不关心写入内容同时读取的就是刚才完成的那次转换结果。整个流程中 CS 全程拉低中间不释放这是 ADS1118 的正常操作方式。数据转换公式需要额外补充一句返回值是 16 位有符号数如果是双极性输入比如 PGA 允许负电压你需要把它转成int16_t再参与运算。转电压的公式是// 将原始码转换为实际电压值单位 mV // fsr 对应 PGA 档位的满量程mV比如 PGA0 时 fsr6144 float ads1118_calc_voltage(uint16_t raw, float fsr_mv) { int16_t signed_raw (int16_t)raw; return ((float)signed_raw * fsr_mv) / 32768.0f; }注意这里除以 32768 而不是 65535因为 ADS1118 的输出格式是二进制补码满量程对应 ±FS0x7FFF 表示正满量程0x8000 表示负满量程。很多第一次接触的人容易踩这个坑直接用 65535 或 32767 做分母导致满量程附近有几毫伏的误差。3.3 温度传感器模式的切换技巧ADS1118 内置的温度传感器是一个二极管结压降型温感精度在 ±1°C 量级出厂校准后。读取它的方法是把 TS_MODE 位置 1其余位不变发起转换后读取结果。温度数据的解析公式不同14 位分辨率符号扩展后每 LSB 代表 0.03125°C。float ADS1118_ReadTempCelsius(void) { uint16_t config 0; uint8_t tx_buf[2] {0}; uint8_t rx_buf[2] {0}; uint16_t raw 0; float temp 0.0f; config | (1 15); // SS1 config | (0b100 12); // MUX100: AINPAIN0, AINNAIN1温度模式固定 config | (0b001 9); // PGA±4.096V温度模式此位忽略但保持合法值 config | (1 8); // MODE1 config | (0b011 5); // DR011温度转换始终为 8SPSDR 位影响后续 ADC 模式 config | (1 4); // TS_MODE1: 温度传感器模式 tx_buf[0] (config 8) 0xFF; tx_buf[1] config 0xFF; HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hspi1, tx_buf, rx_buf, 2, 100); // 等待 DRDY 变低温度转换时间约 125ms8 SPS 内部时钟 uint32_t timeout 0; while (HAL_GPIO_ReadPin(ADS1118_DRDY_GPIO_Port, ADS1118_DRDY_Pin) ! GPIO_PIN_RESET) { HAL_Delay(1); timeout; if (timeout 200) break; } tx_buf[0] 0x00; tx_buf[1] 0x00; HAL_SPI_TransmitReceive(hspi1, tx_buf, rx_buf, 2, 100); HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_SET); raw (rx_buf[0] 8) | rx_buf[1]; // 14 位有效高 14 位含符号右移 2 位后符号扩展到 16 位 int16_t temp_raw (int16_t)(raw 2); temp (float)temp_raw * 0.03125f; return temp; }代码中右移 2 位是关键——温度结果只有 14 位处于 16 位结果的高 14 位低 2 位是未知值。右移 2 位后得到的是带符号的 14 位整数转换为 float 后乘以 0.03125即 1/32就得到摄氏度。实测室温下的读数去掉最后半位跳动后和精密温度计对比差值通常在 0.3°C 以内。3.4 SPI 数据读取错误排查表现象可能原因排查方法结果固定为 0x8000 左右配置字没有正确写入MUX 通道配置错误检查配置字位序逐位对照手册表结果跳变剧烈像是随机数DOUT/DRDY 引脚悬空或未正确连接用示波器抓 SCLK 和 DOUT确认数据在 SCLK 下降沿稳定读到的数据总是上一次的旧值单次模式下没有等待转换完成就读取确认 DRDY 拉低后再发起第二次 SPI 事务结果全为 0xFFFFSPI 时钟极性/相位设置错误ADS1118 要求 CPOL0、CPHA1SPI Mode 1或 CPOL1、CPHA1Mode 3都支持确认与主控匹配极少数情况下读到错位数据SPI 时钟超过 4MHz或走线过长降低 SPI 时钟到 1~2MHz 再测试这个排查表是从多个项目里总结出来的高频问题。最隐蔽的是第四条——SPI 模式配置错误因为有些 ADC 只支持 Mode 3 而 ADS1118 同时支持两种但如果你初始化成 Mode 0CPOL0, CPHA0结果就是稳定的错误数据。建议调试时先用逻辑分析仪抓一次完整 SPI 事务和手册时序图比对。4. 校准与精度优化热电偶测量的补偿路径和数字滤波4.1 使用 ADS1118 做热电偶测量的完整方案ADS1118 的一个典型用途是直接接热电偶因为芯片内部的温度传感器正好可以做冷端补偿。热电偶的信号非常微弱K 型热电偶大约 40µV/°C所以必须用最高增益档 PGA±0.256V此时 LSB 约为 7.8µV对应 0.2°C 左右的分辨率这在工业测温领域是足够用的。接线方式上ADS1118 数据手册推荐的差分接法是热电偶正极接 AIN0负极接 AIN1并且在 AIN0 和 AIN1 之间接一个 10nF 的差分电容同时每个输入端对地接 10nF 电容构成共模滤波。这个滤波器的截止频率较高几十 kHz但主要目的是滤除射频干扰。热电偶引线较长时超过 1 米建议用双绞线并把屏蔽层单端接地。冷端补偿的数学处理是这样的实际温度 K 型热电偶电压对应的温度 冷端温度由内部传感器读取难点在于热电偶的电压-温度关系是非线性的查表法需要较大的存储空间而多项式拟合则需要计算开销。一个折中方案是只做分段线性插值把 -40°C 到 350°C 分为 7 段每段两端点处用一个比例系数近似。这样既保证 0.5°C 内的最大误差又不需要大表格。如果你需要更精确的补偿可以参考 NIST ITS-90 多项式但注意 ARM Cortex-M0 级别的 MCU 上计算复杂度会偏高。4.2 内部基准的温漂特性校准到底校准什么ADS1118 的内部基准在 0°C 到 65°C 范围内典型温漂系数为 10ppm/°C最大 30ppm/°C。这个参数意味着如果你不做校准在 -20°C 到 60°C 的工业环境里满量程误差可能达到 0.25%按最大温漂估算。对 14 位有效精度的应用来说这个误差是能够容忍的但如果你需要 16 位测量精度对应 0.0015% 级别的误差则必须做系统校准。校准方案有两种思路第一种是最常用的两点校准。在正式测量前用精密电压源输入两个已知电压比如满量程的 25% 和 75%测量实际输出码然后计算出增益误差和偏移误差在软件中补偿。这个方案操作简单一次校准终身使用只要你不对同一颗芯片的 PGA 档位做更改就有效。第二种是温度点校准在多个温度下记录偏移和增益插值出温漂曲线。这种方法适合高精度计量仪器但对生产过程要求高一般消费级产品用不到。在实际项目中我更倾向于第一种方案外加“开机自校准”在每次系统启动时把输入切换到内部 GND通过 MUX 配置为 AINPAIN3, AINNAIN3测出偏移量并存入 RAM。如果每次上电温度差异不大这种做法能显著提升长期稳定性。4.3 数字滤波的实用策略滑动平均和去极值ADS1118 自身有数字滤波器但它的滤波器特性更像一个 Sinc 低通滤波器主要作用带外噪声抑制对脉冲干扰无能为力。在工控现场电机启停、继电器动作产生的尖峰脉冲会直接耦合到输入端表现为读数突然跳到远超信号范围的值。此时软件滤波是必须的。我常用的滤波器是“滑动窗口中值滤波 滑动平均”的组合分两步走#define FILTER_WINDOW 5 float ADS1118_FilteredRead(int channel, int pga) { int16_t samples[FILTER_WINDOW]; int16_t tmp[FILTER_WINDOW]; int i, j; int32_t sum 0; // 连续读取 FILTER_WINDOW 次原始值 for (i 0; i FILTER_WINDOW; i) { uint16_t raw ADS1118_ReadSingle(channel, pga); samples[i] (int16_t)raw; // 每次读取间隔至少让 DRDY 完成一次转换 HAL_Delay(20); // 50 SPS 等效速率 } // 拷贝并排序 memcpy(tmp, samples, sizeof(tmp)); for (i 0; i FILTER_WINDOW - 1; i) { for (j i 1; j FILTER_WINDOW; j) { if (tmp[j] tmp[i]) { int16_t t tmp[i]; tmp[i] tmp[j]; tmp[j] t; } } } // 去掉最大值和最小值剩余三个取平均 for (i 1; i FILTER_WINDOW - 1; i) { sum tmp[i]; } return (float)sum / (FILTER_WINDOW - 2); }这段代码的思路很直白采集 5 个样本排序后去掉最小和最大剩下的取平均。这样既消除了脉冲尖峰因为尖峰必定是排序后的极值又保留了滑动平均的平滑效果。窗口大小可以按需调整——窗口越大滤波越强但响应变慢。要注意的是每次ADS1118_ReadSingle之间必须留足转换完成的时间我上面用 20ms 延时适配 64 SPS 设置如果改变 DR 位延时也要改。这种组合滤波的代价是采样实时性降低——取 5 个样本意味着最终的输出延迟约 5 个转换周期。在 64 SPS 下大约 80ms对温度、压力等工业过程量完全没问题。如果你做的是高速动态信号采集比如振动分析就不应该用这个滤波方案而是直接采用更高采样率的后续数字滤波。一个常见的误用是把滑动平均窗口设置得特别大比如 50 以上试图把噪声完全压平。这样做的问题在于系统对真实信号变化的响应也会变得很迟钝PID 控制器会因此出现振荡甚至不稳定。我见过有人在温度控制回路里把滤波窗口设成 100结果温度超调了 15°C 还收不回来。记住底线滤波窗口所带来的延迟不应该超过你对信号响应时间要求的 1/5。5. 时钟极性与连续读取SPI 帧边界最容易翻车的三个细节很多人在单次读取成功后以为万事大吉一切换到连续模式就出问题。ADS1118 在连续模式下每个转换结果在 DOUT/DRDY 引脚上以一个下降沿指示这个下降沿同时也是 SPI 读取的同步信号。正确的读取流程是等待下降沿→发起一次 SPI 读取→得到上一次转换结果→等待下一轮下降沿。这里最大的坑是如果主控 SPI 时钟比转换速率快很多你怎么知道当前读的是哪一次转换的数据答案是你需要跟踪 DRDY 引脚的状态。关键细节一DRDY 会保持低电平直到 SPI 事务开始。也就是说如果你在下一次转换完成前有几次 SPI 时钟看到的是 DRDY 一直为低但这段时间里的数据其实是无效的——因为 MUX 和 PGA 没有更新。这和一个 GPIO 中断低电平触发脉冲不同它是电平信号。所以轮询时必须检查“从高电平变成低电平”这个边沿而不是单纯判断引脚为低。关键细节二SPI 事务的帧边界问题。CS 引脚的每次拉低/拉高定义了一个 SPI 帧。ADS1118 允许 16 位或 32 位帧——32 位意味着你可以同时读取上一次结果和写入下一次配置。如果你使用 16 位帧每次 CS 拉低后只传输 2 字节则需要严格保证“写配置→等待 DRDY→读结果”这个顺序否则读到的结果和配置不匹配。我在一个项目中发现同事把 CS 设为低电平后睡了 10ms 再读数据结果每次都会把配置字当成数据读回来整条曲线错位了一个周期。关键细节三MODE 位在连续模式下读到的第一个数据是“垃圾”。切换到连续模式后第一次转换完成前的任何读取操作返回的都是旧数据有时甚至是上一次单次模式的结果。所以连续模式启动后建议先做一次“虚拟读取”丢弃再从第二次转换结果开始使用。下面是我在 STM32 上验证过的连续模式核心代码段你可以对照检查自己的状态机void ADS1118_ContinuousStart(void) { uint16_t config 0; config | (0 15); // SS 位在连续模式下无效不需要置 1 config | (0b000 12); // MUX: AIN0 vs AIN1 config | (0b001 9); // PGA: ±4.096V config | (0 8); // MODE0: 连续模式 config | (0b111 5); // DR111: 860 SPS config | (0 4); // ADC 模式 // 写配置 uint8_t tx_buf[2] {(config 8) 0xFF, config 0xFF}; uint8_t rx_buf[2] {0}; HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_RESET); HAL_SPI_TransmitReceive(hspi1, tx_buf, rx_buf, 2, 100); HAL_GPIO_WritePin(ADS1118_CS_GPIO_Port, ADS1118_CS_Pin, GPIO_PIN_SET); // 丢弃第一次数据 ReadRawData(); } int16_t ADS1118_ContinuousRead(void) { // 等待 DRDY 下降沿从高到低 GPIO_PinState prev HAL_GPIO_ReadPin(ADS1118_DRDY_GPIO_Port, ADS1118_DRDY_Pin); GPIO_PinState curr prev; while (1) { curr HAL_GPIO_ReadPin(ADS1118_DRDY_GPIO_Port, ADS1118_DRDY_Pin); if (prev GPIO_PIN_SET curr GPIO_PIN_RESET) { break; // 检测到下降沿 } prev curr; } return ReadRawData(); }值得留意的是 SS 位在连续模式下的行为数据手册上说 SS 位在连续模式下会被忽略但实际上第一次写入时把它置 1 或置 0 都不影响启动关键是 MODE 位必须是 0。有些资料里声称“连续模式需要先写 SS1 再写 SS0 来启动”我们实测不必这么做——MODE0 本身就启动了连续转换不需要 SS 位参与。如果你在连续模式下发现数据始终是同一个值不更新先检查 DRDY 引脚是不是接了上拉电阻。ADS1118 的 DRDY 是开漏输出必须外接一个 10kΩ 上拉到 VDD否则电平永远为低你的“下降沿检测”永远无法触发。这是硬件上最容易忽略的一个元件。6. 用内部温度传感器做冷端补偿的实用标定方法最后聊一个能把 ADS1118 用得比数据手册更进阶的技巧不依赖外部基准来标定内部温感。ADS1118 的温度传感器虽然出厂校准过但仍存在个体偏差。如果你直接用它测热电偶冷端温度最终测温误差可能在 2~3°C。一个低成本标定方法是用冰水混合物作为 0°C 基准把热电偶的冷端和参考温度计放在一起读取芯片内部温度传感器的原始输出计算误差然后在固件中修正一个偏移量。具体操作是先读取一次温度原始值14 位右移 2 位后的整数然后用精密温度计记录实际冷端温度精度 0.1°C 即可算出offset 实际温度 - 原始温度值 × 0.03125。在后续代码中每次计算温度都加上这个 offset。实测 10 颗芯片的 offset 离散度大约在 ±0.8°C 以内单点标定后可以把误差压进 ±0.5°C。如果你的应用场景是宽温域比如 -20°C 到 85°C单一偏移量就不够了此时需要在两个温度点分别标定拟合成线性方程T_real k × T_raw bk 通常在 0.98 到 1.02 之间。这个校正方程可以放在 I2C EEPROM 或 MCU Flash 的配置区生产校准工位把 k 和 b 写入设备号对应的记录里组装时刷入。最后一个应用建议如果你不仅仅要测温度还要同时用 4 个模拟通道做数据采集建议把温度传感器模式安排在采集间隙执行比如每 10 次 ADC 采集穿插一次温度读取。ADS1118 的模拟开关不会因为切换模式而中断当前转换你只需要在读取结束后重新写回 ADC 模式的配置字即可。这种时分复用策略可以在一颗芯片上同时完成 4 通道模拟采集和板温监测把硬件成本压到最低。本文还有配套的精品资源点击获取
返回列表