MAX6675的SPI通信必须用硬件SPI且禁用DMA,因其为纯硬件从设备,仅支持CS拉低后严格时序下轮询读取16位数据;软件模拟或DMA易因边沿偏差导致全0或异常值,且须检查D15(开路)和D2(冷端就绪)位以避免温度突跳。

MAX6675的SPI通信必须用硬件SPI且禁用DMA
MAX6675是纯硬件SPI从设备,没有寄存器、不支持读写地址,只靠CS拉低后连续读取16位数据。很多开发者尝试用软件模拟SPI(bit-banging)或启用DMA传输,结果读出全0或固定值0x0000或0xFFFF——这是因为芯片要求SCK边沿严格对齐,且CS下降沿到第一个SCK上升沿延迟不能超过100ns。Arduino Uno的SPI.beginTransaction()配合digitalWrite手动控CS是最稳妥方案;STM32上务必关闭DMA,改用轮询式HAL_SPI_Receive(),并确保CLKPolarity=SPI_POLARITY_LOW、CLKPhase=SPI_PHASE_1EDGE。
16位数据解析时必须检查D15和D2位
读回的16位中,D15是热电偶开路标志,D2是内部基准电压就绪标志。忽略这两者会导致温度突跳到-100℃或+1024℃等明显异常值。典型误码场景:热电偶未拧紧→D15=1→(raw & 0x8000) != 0;冷端补偿未稳定→D2=0→(raw & 0x0004) == 0。正确解析逻辑应为:
uint16_t raw = spi_read_16bit(); if (raw & 0x8000) return NAN; // 开路 if (!(raw & 0x0004)) return NAN; // 冷端未就绪 float temp = (raw >> 3) * 0.25f; // D14~D3共12位,0.25℃/LSB
冷端补偿误差主要来自PCB铜箔温升
MAX6675片内测的是芯片本体温度,但实际冷端是热电偶焊点所在PCB铜皮。若芯片贴在大铜面上且附近有DC-DC发热器件,实测冷端温度可能比环境高5~15℃,导致整体读数偏低。实测发现:将MAX6675焊接在独立小焊盘上、周围2mm内不铺铜、芯片正上方不放散热器件,可使冷端误差从±8℃收敛到±1.5℃。必要时可用NTC贴片电阻靠近MAX6675测量真实PCB温度,软件校准补偿,但注意NTC响应慢,仅适用于稳态场景。
Arduino库常见陷阱:millis()阻塞与CS时序冲突
某些第三方MAX6675库在readCelsius()里调用delay(1)或依赖millis()做超时判断,而MAX6675要求CS低电平持续时间≤10ms(否则自动复位),一旦主循环被其他任务拖慢,CS拉高不及时就会锁死总线。更糟的是,若SPI中断被禁用(如在noInterrupts()块中),整个读取会失败。建议直接裸写SPI操作,去掉所有延时和中断依赖,用如下模式:
立即学习“C++免费学习笔记(深入)”;
digitalWrite(cs_pin, LOW); SPI.transfer(0x00); // dummy uint8_t hi = SPI.transfer(0x00); uint8_t lo = SPI.transfer(0x00); digitalWrite(cs_pin, HIGH); // 必须在此处立刻拉高
真正难处理的是热电偶引线引入的共模噪声——长于10cm的双绞线未接地屏蔽时,读数会随开关电源负载跳变,这个得靠硬件滤波,软件无解。


















