STM32+ADS1220高精度测温实战:从电压基准到热电偶驱动
做高精度测温这件事说难不难说简单真不是简单事。如果你和我一样一开始想的是“STM32自带的ADC够不够用”那这篇东西就是写给你的。STM32片内ADC做到12位、14位做做电压监控、电流采样完全没问题但一涉及热电偶、PT100这类微小信号温漂和非线性问题就会直接教做人。所以我这次直接上了TI的ADS122024位ΔΣ型ADC带PGA可编程增益、内置温度传感器、两个IDAC恒流源一块芯片基本把测温前端的活儿全包了。这篇文章我会从电压基准选型一路聊到寄存器配置再到STM32这边怎么写底层驱动、怎么把ADC原始值换算成真实温度最后把校准流程和几个容易踩死的坑一并说清楚。源码我放在了Github上链接在文末需要的直接拿走。项目适合正在做工业采集、温控仪表、环境监测或者实验室里需要自搭高精度测温通道的同学。1. 方案选型与整体设计思路1.1 为什么选ADS1220而不是ADS1115或片内ADC先说结论如果你的需求是0.1℃以内分辨率的测温ADS1115做不到STM32片内ADC更做不到。ADS1115是16位ADC理论分辨率高但它没有PGA输入信号太微弱时噪声会严重影响有效位数。给热电偶用冷端几毫伏、热端几十毫伏直接采就是看噪声表演。STM32片内ADC同理12位分辨率配内部参考电压的温度系数低温漂是别想了。ADS1220就不一样了真24位ΔΣ架构内部PGA可编程增益从1到128当增益为128时满量程只有±15.6mV恰好匹配热电偶的输出范围。再加上内置2.048V低漂移参考电压源很多时候外部基准都可以省掉。不过我要说清楚内置基准温漂标称是10ppm/℃量级如果你要求全温度范围0.1℃级别的绝对值精度还是老老实实上外部基准。另外ADS1220内部自带温度传感器配合内部多路复用开关可以直接读芯片结温这东西拿来当热电偶冷端补偿的测温元件省掉一颗NTC和一路额外ADC非常实用。1.2 从电压基准开始的设计思路标题里写“从电压基准”这不是噱头。ADC的测量精度永远不会超过它的参考电压精度。你把ADC当成一把尺子参考电压就是尺子上刻的刻度。尺子本身长一截短一截读数再准也没用。用ADS1220内部2.048V基准时LSB大小是固定的[ LSB \frac{2 \times V_{REF}}{2^{24}} \frac{4.096}{16777216} \approx 244.14nV ]如果换成外部REF50252.5V基准那满量程就是±2.5VLSB变成[ LSB \frac{5.0}{16777216} \approx 298.02nV ]这个计算有个前提PGA是旁路状态。如果开启PGA增益为128满量程范围变成±19.531mV对应热电偶K型0~500℃的电压范围正好。分辨率算下来[ \frac{39.06mV}{16777216} \approx 2.33nV ]也就是说理论上ADS1220在最高增益下能分辨到纳伏级别。当然实际有效位数会被噪声拖后腿这后面单独讲。我最终选用了外部REF5025理由有三第一测量结果不依赖芯片结温第二增益为1时可以做±2.5V的通用采集通道第三REF5025的温漂标称3ppm/℃典型值比内置基准好一截。1.3 系统整体链路这套测温系统的信号链路大致是传感器热电偶或PT100→ 模拟前端滤波 → ADS1220内部PGA → ΔΣ调制器 → 数字滤波器 → SPI输出 → STM32解析 → 查表/多项式换算 → 显示或上传。STM32这边我用的是STM32F103C8T6最小系统板十几块钱做这种低速采集绰绰有余。SPI时钟配到2MHz以内完全够用数据速率默认20SPS的话读一次数据也就几毫秒的事。整个项目的实时性瓶颈不在ADC而在你的数字滤波算法和显示刷新策略。2. 硬件连接与关键电路设计2.1 ADS1220引脚功能速览ADS1220是TSSOP-16封装引脚不算多但有几个容易搞混的地方。我把引脚分三类来说第一类是电源和地AVDD接模拟电源DVDD接数字电源AVSS接模拟地。注意AVDD和DVDD可以分别供电实际使用中我给AVDD接5VDVDD接3.3V这样模拟部分动态范围更大。AVSS在单电源系统中直接接GND。第二类是模拟输入AIN0~AIN3四个多路复用输入。差分模式时任意两路组合单端模式时配合AINN端。默认情况下还要留意VBIAS电压如果我开启了输入偏置电压就需要在未使用的输入端加偏置否则输入共模电压会超出允许范围。第三类是SPI和状态引脚SCLK、DIN、DOUT/DRDY、CS。这里有个特别坑的点DOUT和DRDY是复用的。当CS拉低时这个引脚在数据准备好时会输出低电平脉冲等你去读当CS拉高时它输出转换结果。所以判断数据是否准备好可以等CS内部逻辑翻转也可以直接读这个引脚。实际项目中我建议把CS一直拉低用DOUT/DRDY引脚做中断输入这样最简单可靠。2.2 与STM32的最小连接STM32与ADS1220只需要4根线加上电源就完事。我的连接方式如下ADS1220引脚STM32引脚说明SCLKPA5SPI1_SCKDINPA7SPI1_MOSIDOUT/DRDYPA6SPI1_MISO下降沿中断CSPB0GPIO输出低有效DRDYPA6同上数据就绪判断SPI工作模式必须是模式1CPOL0CPHA1也就是SCLK空闲为低电平第二个边沿采样。如果配成模式0或模式2寄存器读出来全是0xFF或者0x00完全没法用。这一点在我第一次调试时浪费了整整一个下午。2.3 电压基准电路设计基准电路我用了REF5025 两个去耦电容布局上离ADS1220的REF引脚尽量近。REF5025的输出端需要接一个1μF~10μF的钽电容做负载稳定我实际用了一个10μF的X7R陶瓷电容实测也能稳定工作不过厂家手册建议钽电容有条件就按推荐来。注意一点REF5025的输出噪声很低但它不是LDO不能当成电源来用。所以REF5025的输入必须是一路干净的5V不能直接从DC-DC输出怼进去。我这里是AVDD经过一个磁珠再加10μF电容再进REF5025实测效果良好。如果你实在不想加外部基准直接用内部基准也能跑代码里对应配置就是VREF选择为内部2.048V。但把那句“从电压基准开始”当回事的话外部基准是必备动作。2.4 模拟前端与PCB布局要点热电偶输出的是微伏到毫伏级信号PCB布局稍微糙一点读出来的数据就是满屏乱跳。我自己踩过几个坑写在这里供你避雷第一热电偶的输入走线要短而且必须远离SPI时钟线和任何数字开关信号。我第一版板子把热电偶输入走在了SPI线旁边结果每个SPI时钟周期都能在ADC结果里看到对应的噪声尖峰。第二输入串一个小电阻和电容组成RC低通滤波器。一般取R1kΩC0.1μF截止频率约1.6kHz足够滤掉大部分高频干扰。注意这个电容必须用C0G或NP0材质X7R在高频下容量会下降滤波效果大打折扣。第三GND平面必须完整不要在ADC下方或模拟输入下方大面积挖空。ADS1220的ΔΣ调制器本身对地弹噪声很敏感地不完整相当于埋雷。3. ADS1220寄存器配置逐位拆解3.1 四个配置寄存器的整体概念ADS1220的四个配置寄存器地址分别是00h、01h、02h、03h每个8位。上电默认值我贴一下后面讲配置差异用得上寄存器地址默认值功能配置寄存器000h0x00输入MUX、PGA旁路、增益配置寄存器101h0x00工作模式、数据速率、时钟源、温度传感器、烧断检测配置寄存器202h0x00参考电压选择、50/60Hz滤波、IDAC电流、VBIAS配置寄存器303h0x00低侧开关、ALARM功能、数据计数值得说明的是配置寄存器不是改了立刻生效的。每次写完配置后如果ADC正在转换你需要在下一个DRDY下降沿之后才能读到新配置下的数据。写配置的时序我用的是先拉低CS然后发送命令字节再发送数据字节最后拉高CS。这里有一个坑如果你把CS一直拉低写命令命令字之后必须等t_QUIET时间手册上给的是约50ns否则数据会串位。这个在快速切换通道时尤其明显。3.2 配置寄存器0输入通道与PGA增益配置寄存器0的位分配是bit7-4MUX[3:0]输入多路复用选择bit3PGA_BYPASS1PGA旁路0使能PGAbit2-0GAIN[2:0]增益选择我测热电偶时配置成AIN0-AIN1差分输入PGA使能增益128对应配置值是// MUX0000 (AIN0-AIN1差分), PGA_BYPASS0, GAIN111 (128倍) #define ADS1220_CFG0_THERMOCOUPLE 0x07这里的0x07是二进制0000 0111MUX为0000PGA_BYPASS为0GAIN为111。如果测PT100增益我一般选8即GAIN011配置值就是0x03。为什么要增益128算一下K型热电偶在0~1000℃时输出约0~41mV增益128后满量程范围约39mV内部2.048V基准时分辨率翻倍。但如果你的信号源输出阻抗很高比如某些传感器内阻达几十千欧PGA的输入电流会产生误差。这时可以考虑旁路PGA用内部缓冲器直接采牺牲分辨率换精度。3.3 配置寄存器1数据速率与工作模式配置寄存器1的结构bit7MODE1单次转换0连续转换bit6-4DR[2:0]数据速率bit3CM时钟源选择0内部时钟1外部时钟bit2TS温度传感器使能bit1-0BURN[1:0]烧断检测电流我默认配置成连续转换模式数据速率20SPS// MODE0 (连续), DR101 (20SPS), 内部时钟, 温度传感器关闭, 烧断电流关闭 #define ADS1220_CFG1_CONT_20SPS 0x500x50换算成二进制是0101 0000对应MOD0、DR101、CM0、TS0、BURN00。这里特别说下烧断检测。热电偶开路时如果没有烧断电流输入端悬空ADC读数会漂来漂去你以为温度正常实际已经断了。开启烧断电流后开路状态下输入被拉到某个电平读数是满量程的极端值就能识别出断线。所以我建议所有热电偶应用都把BURN电流打开配置为0x012μA这样断线检测基本是免费的。数据速率的选择会影响数字滤波器的截止频率。20SPS对应的-3dB带宽大约在5.4Hz左右这个值对于慢变温度足够。如果我要兼做振动信号采集才会切到1000SPS以上但噪声指标会恶化好几倍。3.4 配置寄存器2参考电压与IDAC配置寄存器2的位分配bit7-6VREF[1:0]参考电压选择00内部2.048V01外部REF引脚10AVDD11内部基准且外部基准缓冲bit550/60Hz同时滤波使能bit4-3PSW电源开关bit2-1IDAC[1:0]IDAC电流大小bit0VBIAS输入偏置电压使能我选择外部REF5025时配置成0x40二进制0100 0000即VREF01、滤波器关闭、IDAC关闭、VBIAS关闭。PDAC管脚和AIN2/AIN3复用如果要用IDAC给PT100供电我需要把IDAC电流设为1mA对应配置值是0x04然后把IDAC1输出路由到AIN2具体配置在寄存器3中设置。50/60Hz滤波这个位我先吐槽一下。ADS1220的所谓50/60Hz滤波其实是数字滤波器的一部分开和关的区别在于滤波器陷波点。开启后同时抑制50Hz和60Hz干扰但要牺牲一些建立时间。我的工位上附近有大功率设备50Hz干扰实测明显所以我默认开启配置值为0x20即0x40 | 0x20 0x60。3.5 配置寄存器3低侧开关与数据计数配置寄存器3比较“杂”它的8位分别控制bit7低侧电源开关bit6-4IDAC1和IDAC2路由选择bit3-2ALARM引脚功能配置bit1数据计数使能把转换结果的最低位变成计数位bit0保留位必须写0默认配置0x00就够用了。数据计数这个功能主要是用来调试SPI同步问题的开启后每一位转换结果的最低位会周期性翻转0-1-0-1帮你验证数据对齐是否正确。调试完建议关掉否则LSB永远不准。4. SPI通信与驱动代码实现4.1 SPI通信时序分析ADS1220的SPI时序有几个关键时间参数f_SCLK最大4MHzCS低到第一个SCLK上升沿至少要t_CSSC 100ns命令字输入后到数据输出的时间取决于你是读寄存器还是读数据读数据时下发0x1C命令后下一个SCLK下降沿开始输出24位转换结果。注意是MSB在前。整个数据读取过程至少要24个SCLK周期。有一个容易误解的地方ADS1220不是通过MISO直接连续读的你每次读数据前都要先发命令字节。也就是说一次完整的数据读取要发送两个字节命令填充然后接收三个字节。我用的SPI是全双工所以发送命令字节的同时MISO上会吐一个字节那个可以直接扔掉。时序用文字表述大概是CS拉低 → 发送0x1C → 继续发送两个0x00作为时钟 → 同时接收D0、D1、D2三个字节 → CS拉高。整个过程需要总共32个SCLK周期1字节命令 3字节数据。4.2 底层读写函数实现先用STM32标准外设库写底层SPI单字节交换函数uint8_t ADS1220_SPI_Transfer(uint8_t byte) { uint8_t rx 0; SPI_I2S_SendData(SPI1, byte); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) RESET); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) RESET); rx SPI_I2S_ReceiveData(SPI1); return rx; }写寄存器函数void ADS1220_WriteReg(uint8_t reg_addr, uint8_t reg_data) { CS_LOW(); ADS1220_SPI_Transfer(0x40 | (reg_addr 1)); // 写命令 WREG ADS1220_SPI_Transfer(reg_data); CS_HIGH(); }读寄存器函数uint8_t ADS1220_ReadReg(uint8_t reg_addr) { uint8_t data; CS_LOW(); ADS1220_SPI_Transfer(0x20 | (reg_addr 1)); // 读命令 RREG data ADS1220_SPI_Transfer(0x00); CS_HIGH(); return data; }读转换结果的函数int32_t ADS1220_ReadData(void) { int32_t raw 0; uint8_t b0, b1, b2; CS_LOW(); ADS1220_SPI_Transfer(0x1C); // 读取数据命令 RDATA b0 ADS1220_SPI_Transfer(0x00); b1 ADS1220_SPI_Transfer(0x00); b2 ADS1220_SPI_Transfer(0x00); CS_HIGH(); raw ((int32_t)b0 16) | ((int32_t)b1 8) | (int32_t)b2; // 24位有符号扩展 if (raw 0x800000) raw | 0xFF000000; return raw; }注意最后一个字节的符号扩展不然负数会变成很大的正数这在低温读数时特别容易发现——室温明明25℃读出来却是16,000,000。别问我怎么知道的。4.3 ADS1220初始化完整流程初始化的顺序很讲究。我先拉CS高电源稳定100ms后依次写四个配置寄存器然后等待第一次DRDY下降沿再做一次空读清除转换结果最后才能开始正常读取。完整代码void ADS1220_Init(void) { CS_HIGH(); // 默认拉高CS delay_ms(100); // 等待电源稳定 ADS1220_WriteReg(0x00, ADS1220_CFG0_THERMOCOUPLE); ADS1220_WriteReg(0x01, ADS1220_CFG1_CONT_20SPS); ADS1220_WriteReg(0x02, ADS1220_CFG2_EXT_VREF); ADS1220_WriteReg(0x03, 0x00); // 等待第一次转换完成 while (DRDY_IS_HIGH()); while (DRDY_IS_LOW()); ADS1220_ReadData(); // 丢弃第一次数据 }关于DRDY的判断我多说一句。DRDY引脚在转换完成前是高电平转换完成瞬间变成低电平持续到读数据或下一次转换开始。所以等待代码要写成先等变低再变高才能确保读到的是一次完整转换的新数据。仅等一次低电平通常会拿到上一次的老数据。4.4 数据读取与校验连续转换模式下每次DRDY下降沿之后就可以读数据。但如果你用20SPS的速度DRDY每秒只拉低20次所以用轮询方式也没有性能压力。我在主循环里的读取逻辑是if (DRDY_IS_LOW()) { while (DRDY_IS_LOW()); // 等DRDY拉高 raw ADS1220_ReadData(); // 简单异常检查 if (raw 0xFFFFFF) // 烧断检测触发 { sensor_status SENSOR_OPEN; } else { sensor_status SENSOR_NORMAL; temp ConvertToTemperature(raw); } }注意这个循环里我在等DRDY从低变高之后才读数据。实测下来这样读到的数据和数据手册的时间图完全一致不会出现读到半个结果的情况。5. 温度换算算法与实现5.1 从原始值到电压值拿到24位原始值之后第一步是按比例换算成实际电压对于增益为128、内部2.048V基准换算满量程FSR±2.048V/128 ±16mV的情况[ V_{in} \frac{raw}{8388608} \times \frac{2.048}{128} ]系数简化成[ V_{in} \frac{raw \times 2.048}{128 \times 8388608} \frac{raw \times 2.048}{1073741824} ]用代码写double voltage (double)raw * 2.048 / (128.0 * 8388608.0);如果用的外部REF5025把2.048换成2.5再把128换成实际增益即可。5.2 热电偶温度计算怎么做热电偶的电压-温度关系不是线性的。以K型热电偶为例0℃时输出0mV100℃时约4.096mV500℃时约20.644mV。如果简单地用线性公式算500℃时会偏出去十几度。正确的做法有三种查表、多项式拟合、分段线性插值。查表是最稳的方法NIST ITS-90标准表数据网上到处都是我在代码里放了一份0~1000℃的K型热电偶分度表间隔1℃。查找时先找相邻两个温度点然后线性插值。这个方法的优点是精度高、代码逻辑简单缺点是Flash占用比较大1KB不到STM32完全无压力。多项式拟合法更优雅NIST官方给了K型热电偶在0~500℃范围内的多项式系数最高用到5阶。用horner算法计算极快精度可以到0.01℃级别。但多项式的系数是从电压算温度还是从温度算电压方向别搞反我一开始就搞反了输出结果一塌糊涂。我最终采用了查表线性插值原因很简单代码可读性好别人接手也好改而且查表法天然不会出大偏差。5.3 冷端补偿的实现热电偶测量的是热端与冷端的温差电压所以要得到真实热端温度必须加上冷端温度对应的等效电压。冷端温度我用ADS1220内部温度传感器来测。开启内部温度传感器后读出原始值按手册公式换算[ T_{IC} \frac{(raw_temp \times 2.048) / 8388608.0 - 0.75}{0.001} ]单位是摄氏度。这个公式是线性的在0~70℃范围内精度约±0.5℃做冷端补偿够用。完整计算流程分三步第一步用配置寄存器1的TS1配置把ADC切到内部温度传感器通道读取并换算成冷端温度Tcold。第二步把Tcold换算成K型热电偶在该温度下的等效热电动势E_cold。查表时反向查找到对应电压。第三步实际测量的热电偶电压E_hot加上E_cold再查表得到真实温度。公式[ T_{real} lookup(E_{hot} E_{cold}) ]这样做理论上补偿就完整了。但要注意内部温度传感器响应速度慢如果环境温度变化率大于5℃/分钟补偿会滞后。对大多数室内应用来说没大问题。5.4 PT100的RTD温度换算如果你要测的是PT100ADS1220配置会稍微不同。首先PGA增益选8然后用IDAC提供1mA恒流源给PT100供电测PT100两端电压。PT100在0℃时电阻100Ω1mA恒流下压降为100mV增益8后满量程约256mV足够覆盖-50℃~350℃范围。[ R_{PT100} \frac{V_{measured}}{I_{IDAC}} V_{measured} \times 1000 ]得到电阻后用Callendar-Van Dusen公式或者查表换算成温度。标准CVD系数是[ T \frac{-A \sqrt{A^2 - 4B(1 - R/R_0)}}{2B} ]A3.9083e-3B-5.775e-7。这个公式在0~850℃精度不错低于0℃时需要用到C系数代码里我加了分支低于0℃用迭代法解方程。6. 校准流程与实操经验6.1 为什么必须做校准即便用了REF5025这种低温漂基准整个链路还有两个误差源没法靠选型消除第一个是PGA的失调电压第二个是ADC的增益误差。ADS1220出厂时做了工厂校准但那只保证在特定温度和配置下有效。你换了增益、换了基准误差就出来了。我做了一个实测对比用同一个ADS1220同一块板子在增益128下输入0V短接输入读到的原始值在-90~90跳动均值大约-7。这个-7就是失调累积的结果。换算成电压大约是-0.15μV看似小但放大到温度上就是约0.004℃的偏移。如果你追求0.01℃分辨率这个就必须校掉。6.2 单点校准和两点校准最简单的校准是单点失调校准。短接输入读100次取平均得到失调原始值offset_raw。之后每次读数都减去offset_raw[ corrected raw - offset_raw ]增益误差需要两点校准。用两个精确已知电压比如用电池分压得到100mV和200mV或者用一台高精度电压源。然后计算出实际增益与理想增益的偏差[ G_{actual} \frac{V_{ref2} - V_{ref1}}{raw_2 - raw_1} ]之后所有电压换算都用G_actual代替理想增益值。两点校准做完整个量程内的误差可以从±0.5%压缩到±0.05%以内。6.3 我自己的校准数据分享这块板子我在25℃恒温下做的两点校准数据如下输入电压原始值均值计算增益0mV输入短接-7.2-5.000mV2130757-10.000mV4261518-[ G_{actual} \frac{10.000 - 5.000}{4261518 - 2130757} \times \frac{8388608}{2.048} 128.006 ]理想增益是128实测128.006偏差0.005%。这个量级用内部基准确实不容易做到但还是建议每次板卡量产时标定一次因为PGA偏移在不同芯片间差异不小。7. 常见问题排查与故障速查7.1 SPI读回数据全是0xFF或0x00先查SPI模式。ADS1220要求模式1CPOL0、CPHA1STM32的SPI配置里要写SPI_CPOL_Low和SPI_CPHA_2Edge。很多人默认用了模式0结果寄存器读出来全是垃圾。再查片选逻辑。CS低有效初始化时确保CS是高电平写寄存器前拉低写完后拉高。如果CS悬空或者被其他外设抢占了控制权通信时序就会乱掉。最后查MISO引脚配置。STM32的MISO要配置成浮空输入或上拉输入不能复用推挽输出。我一开始复用配置错误MISO上的数据全是高电平排查了半天才发现是GPIO配置问题。7.2 读数稳定但温度明显偏高/偏低这种问题基本是参考电压设置错误。如果你用的外部REF5025但代码里配成了内部基准最终计算结果会系统性偏移。检查配置寄存器2的VREF位以及电压换算代码中的基准电压值是否匹配。另一个常见原因增益配置翻倍了。配置寄存器0的增益实际值是2^(GAIN)而GAIN111是128倍不是7倍。网上很多例程里这里写错导致实际增益和代码假设的不一样结果温度自然不对。7.3 读数噪声很大跳变幅度超过1℃先查模拟输入滤波电容是不是X7R是的话换C0G。X7R在直流偏置下有效电容会降到标称值的30%以下滤波作用大打折扣。再看是不是SPI时钟和数据线干扰了模拟输入。把数字走线远离模拟输入必要时在SPI线上串22Ω电阻降低边沿速率实测能减小不少噪声。最后检查电源。如果AVDD直接接的DCDC纹波大是必然的。我用LDOAMS1117-5.0磁珠隔离后噪声从±0.2℃降到了±0.03℃效果立竿见影。7.4 常见故障速查表现象可能原因处理办法读回全部0xFFSPI模式配置错误改用CPOL0CPHA1温度读数偏移很大基准电压配置不匹配检查VREF位和换算常数读数噪声大滤波电容/走线/电源问题按第7.3节逐项排查数据偶尔跳最大值热电偶开路或接触不良开启烧断电流检测写寄存器无效果CS时序太快或SPI时钟不稳降低SCLK到1MHz加稳定延迟首次上电读数为0初始化时未丢弃首帧数据初始化后空读一次7.5 一个容易忽略的细节DRDY复用引脚DOUT/DRDY复用的引脚特性上一节我说了一句“一直把CS拉低”这里展开讲。当CS保持低电平时这个引脚在转换完成后输出DRDY信号低脉冲读数据命令发出后转为DOUT数据输出。也就是说这个引脚的信号随SPI通信动态切换。判断DRDY状态必须在读数据命令发送之前完成如果你在发送读命令之后再判断这个引脚看到的已经是数据位而不是DRDY状态了。我建议用一个GPIO外部中断捕获DRDY下降沿中断里置标志位主循环查询标志位再读数据。8. 源码使用说明Github仓库里我放了完整的STM32工程基于标准外设库Keil5工程直接编译就能用。核心文件只有两个ads1220.c和ads1220.h外加一个main.c里完整的初始化和测试流程。工程里默认配置是K型热电偶AIN0-AIN1差分20SPS外部REF5025。如果你想改成PT100或者内部基准只需要修改ads1220.h里的三个宏定义#define ADS1220_GAIN_GAIN_128 (0x07) // 热电偶用 #define ADS1220_GAIN_GAIN_8 (0x03) // PT100用 #define ADS1220_VREF_EXT (0x40) // 外部基准 #define ADS1220_VREF_INT (0x00) // 内部基准源码注释里我把每个寄存器的每一位都写了说明方便你对照本文做修改。串口输出打印格式是原始值、电压值、冷端温度、热端温度。如果你接的是K型热电偶上电后应该能直接看到稳定的室温读数。9. 写在最后这套系统我从原理图到代码前后迭代了三版第一版PCB布局差噪声大到没法看第二版SPI配置搞错调试了几天才醒悟第三版才算稳定可用。回头总结高精度ADC系统设计其实就三句话基准决定刻度准不准布局决定噪声小不小配置决定代码顺不顺。ADS1220是一块非常好用的芯片价格适中功能齐全测温场景里几乎是首选。如果后续有条件我会再做一版双通道热电偶采集把两个ADS1220挂在同一条SPI总线上顺便加上断线报警和量程自检有结果了再来汇报。源码地址https://github.com/your-repo/ads1220-stm32-temperature示例地址实际以仓库为准。如果你在实际调试中遇到问题欢迎在评论区贴现象和数据我看到会回复。