You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派基于pigpio SPI的MAX31865 C++类测温异常排查求助

MAX31865树莓派Qt项目集成问题

我需要将一块MAX31865扩展板集成到带Qt前端的树莓派项目中,特此寻求指导。该扩展板搭载4片带独立CS引脚的MAX31865芯片,我已确认芯片/RTD在Arduino和STM32平台上均可正常工作,但在树莓派上无法得到正确输出。我怀疑异常输出与pigpio的spiWrite/spiRead/spiXfer函数使用char *类型作为rx/tx缓冲区有关,其他大部分同类库均使用uint8_t类型。

  • 异常现象:接有RTD的芯片输出约92.5(约92.406),未接RTD的芯片输出-403.636,无论如何操作,传感器的阻值均无变化。

我正在将STM32平台使用过的代码适配为C++类,代码看起来逻辑正常,希望能得到大家的校验。

代码内容

max31865.cpp文件

(为简化演示,此处将#define定义直接放在cpp文件中,未放在头文件内)

#include "math.h"
#include "rpigpio.h"
#define MAX31865_CONFIG_REG             0x00
#define MAX31865_CONFIG_BIAS            0x80
#define MAX31865_CONFIG_MODEAUTO        0x40
#define MAX31865_CONFIG_MODEOFF         0x00
#define MAX31865_CONFIG_1SHOT           0x20
#define MAX31865_CONFIG_3WIRE           0x10
#define MAX31865_CONFIG_24WIRE          0x00
#define MAX31865_CONFIG_FAULTSTAT       0x02
#define MAX31865_CONFIG_FILT50HZ        0x01
#define MAX31865_CONFIG_FILT60HZ        0x00
#define MAX31865_RTDMSB_REG             0x01
#define MAX31865_RTDLSB_REG             0x02
#define MAX31865_HFAULTMSB_REG          0x03
#define MAX31865_HFAULTLSB_REG          0x04
#define MAX31865_LFAULTMSB_REG          0x05
#define MAX31865_LFAULTLSB_REG          0x06
#define MAX31865_FAULTSTAT_REG          0x07
#define MAX31865_FAULT_HIGHTHRESH       0x80
#define MAX31865_FAULT_LOWTHRESH        0x40
#define MAX31865_FAULT_REFINLOW         0x20
#define MAX31865_FAULT_REFINHIGH        0x10
#define MAX31865_FAULT_RTDINLOW         0x08
#define MAX31865_FAULT_OVUV             0x04
#define MAX31865_FAULT_NONE             0x00
#define RTD_A                           3.9083e-3
#define RTD_B                           -5.775e-7
#define _MAX31865_RREF                  402.0f
#define _MAX31865_RNOMINAL              100.0f
#define MAX31865_WIRES                  3
#define MAX31865_FILTERHZ               50

MAX31865::MAX31865(uint8_t spiHandle, uint8_t cs_pin){
    this->_spiHandle = spiHandle;
    this->_cs_pin = cs_pin;
    gpioSetMode(this->_cs_pin, PI_OUTPUT);
    gpioWrite(this->_cs_pin, PI_HIGH);
    MAX31865_setWires(MAX31865_WIRES);
    MAX31865_enableBias(false);
    MAX31865_autoConvert(false);
    MAX31865_clearFault();
    MAX31865_setFilter(MAX31865_FILTERHZ);
}

void MAX31865::MAX31865_readRegisterN(uint8_t address, uint8_t *buffer, uint8_t n) {
    uint8_t tmp = 0xFF;
    address &= 0x7F;
    gpioWrite(this->_cs_pin, PI_LOW);
    spiWrite(this->_spiHandle, (char *) &address, 1);
    while (n--) {
        spiXfer(this->_spiHandle, (char*) &tmp, (char *) buffer, 1);
        buffer++;
    }
    gpioWrite(this->_cs_pin, PI_HIGH);
}

uint8_t MAX31865::MAX31865_readRegister8(uint8_t address) {
        uint8_t ret = 0;
        MAX31865_readRegisterN(address, &ret, 1);
        return ret;
}

uint16_t MAX31865::MAX31865_readRegister16(uint8_t address) {
    uint8_t buffer[2] = {0, 0};
    MAX31865_readRegisterN(address, buffer, 2);
    uint16_t ret = buffer[0];
    ret <<= 8;
    ret |= buffer[1];
    return ret;
}

void MAX31865::MAX31865_writeRegister8(uint8_t address, uint8_t data) {
    gpioWrite(this->_cs_pin, PI_LOW);
    address |= 0x80;
    spiWrite(this->_spiHandle, (char*) &address, 1);
    spiWrite(this->_spiHandle, (char*) &data, 1);
    gpioWrite(this->_cs_pin, PI_HIGH);
}

void MAX31865::MAX31865_readFault(){
    this->_fault = MAX31865_readRegister8(MAX31865_FAULTSTAT_REG);
}

void MAX31865::MAX31865_clearFault() {
        uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
        t &= ~0x2C;
        t |= MAX31865_CONFIG_FAULTSTAT;
        MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}

void MAX31865::MAX31865_enableBias(bool enable) {
    uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
    if (enable) {
        t |= MAX31865_CONFIG_BIAS;
    }
    else {
        t &= ~MAX31865_CONFIG_BIAS;
    }
    MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}

void MAX31865::MAX31865_autoConvert(bool enable) {
        uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
        if (enable) {
            t |= MAX31865_CONFIG_MODEAUTO;
        }
        else {
            t &= ~MAX31865_CONFIG_MODEAUTO;
        }
        MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}

void MAX31865::MAX31865_setWires(uint8_t numWires) {
    uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
    if (numWires == 3) {
        t |= MAX31865_CONFIG_3WIRE;
    }
    else {
        t &= ~MAX31865_CONFIG_3WIRE;
    }
    MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}

void MAX31865::MAX31865_setFilter(uint8_t filterHz) {
    uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
    if (filterHz == 50) {
        t |= MAX31865_CONFIG_FILT50HZ;
    }
    else {
        t &= ~MAX31865_CONFIG_FILT50HZ;
    }
    MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}

uint16_t MAX31865::MAX31865_readRTD() {
    MAX31865_clearFault();
    MAX31865_enableBias(true);
    std::this_thread::sleep_for (std::chrono::milliseconds(10));
    uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
    t |= MAX31865_CONFIG_1SHOT;
    MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
    std::this_thread::sleep_for (std::chrono::milliseconds(10));
    uint16_t rtd = MAX31865_readRegister16(MAX31865_RTDMSB_REG);
    MAX31865_enableBias(false);
    rtd >>= 1;
    return rtd;
}

void MAX31865::MAX31865_readTemp() {
    float Z1, Z2, Z3, Z4, Rt, temp;
    Rt = MAX31865_readRTD();
    Rt /= 32768;
    Rt *= _MAX31865_RREF;
    Z1 = -RTD_A;
    Z2 = RTD_A * RTD_A - (4 * RTD_B);
    Z3 = (4 * RTD_B) / _MAX31865_RNOMINAL;
    Z4 = 2 * RTD_B;
    temp = Z2 + (Z3 * Rt);
    temp = (sqrtf(temp) + Z1) / Z4;
    if (temp >= 0) {
        MAX31865_readFault();
        MAX31865_compareFault();
        // Assume the temperature is correct
        this->_MAX31865_tempC = temp;
        this->_MAX31865_tempF = (this->_MAX31865_tempC * 9.0f / 5.0f) + 32.0f;
    }
    else {
        Rt /= _MAX31865_RNOMINAL;
        Rt *= 100;
        float rpoly = Rt;
        temp = -242.02;
        temp += 2.2228 * rpoly;
        rpoly *= Rt;  // square
        temp += 2.5859e-3 * rpoly;
        rpoly *= Rt;  // ^3
        temp -= 4.8260e-6 * rpoly;
        rpoly *= Rt;  // ^4
        temp -= 2.8183e-8 * rpoly;
        rpoly *= Rt;  // ^5
        temp += 1.5243e-10 * rpoly;
        MAX31865_readFault();
        MAX31865_compareFault();
        this->_MAX31865_tempC = temp;
        this->_MAX31865_tempF = (this->_MAX31865_tempC * 9.0f / 5.0f) + 32.0f;
    }
}

void MAX31865::MAX31865_compareFault() {
    this->_faultText = "Unknown error has occured. Refer to the MAX31865 datasheet.";
    if (this->_fault == MAX31865_FAULT_NONE)
        this->_faultText = "No errors detected";
    if (this->_fault == MAX31865_FAULT_HIGHTHRESH)
        this->_faultText = "Measured resistance greater than High Fault Threshold value.";
    if (this->_fault == MAX31865_FAULT_LOWTHRESH)
       this->_faultText = "Measured resistance less than Low Fault Threshold value.";
    if (this->_fault == MAX31865_FAULT_REFINLOW)
        this->_faultText = "vREFIN > 0.85 x vBIAS.";
    if (this->_fault == MAX31865_FAULT_REFINHIGH)
        this->_faultText = "vRERFIN < 0.85 X vBIAS (FORCE - open).";
    if (this->_fault == MAX31865_FAULT_RTDINLOW)
        this->_faultText = "vRTRIN- < 0.85 X vBIAS (FORCE - open).";
    if (this->_fault == MAX31865_FAULT_OVUV)
        this->_faultText = "Any protected input voltage > vDD or < GND1.";
}

初始化与温度读取代码

int spiHandle = 0;
spiHandle = spiOpen(SPI_CHANNEL, SPI_SPEED, 0);
qDebug() << "[DEBUG] SPI Handle Open. Handle: " << spiHandle;
MAX31865 MAX31865_1(spiHandle, MAX31865_1_GPIO);
qDebug() << "[DEBUG] MAX31865 Initialized.";
volatile float _temp1_F = 0.0f;
MAX31865_1.MAX31865_readTemp();
qDebug() << "[DEBUG] 1 Temp F: " << MAX31865_1.read_MAX31865TempF();
_temp1_F = MAX31865_1.read_MAX31865TempF();
qDebug() << "[DEBUG] 1 Fault: " << MAX31865_1.read_MAX31865FaultText();
RPIDataStructure->set_tempMAX_1(_temp1_F);

非常感谢大家对本项目提供的任何帮助,谢谢。


内容的提问来源于stack exchange,提问作者TyrantUT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:27:03