STM32 驱动 MAX31865 读取 PT100 温度方案

STM32 驱动 MAX31865 读取 PT100 温度方案

目录

  1. MAX31865 与 PT100 简介

  2. 硬件连接 (STM32 与 MAX31865)

  3. 软件配置与代码

    • SPI 初始化
    • MAX31865 初始化配置
    • 读取温度数据
    • 温度值计算
  4. 注意和常见问题

1. MAX31865 与 PT100 简介

MAX31865 是一款专用于电阻式温度检测器 (RTD)(如 PT100、PT1000)的信号调理器,它将 RTD 的电阻变化转换为数字信号并通过 SPI 接口输出。其特点包括:

PT100 是一种铂电阻温度传感器,其在 0°C 时的电阻值为 100Ω,电阻值随温度变化而变化(温度系数约为 0.385Ω/°C)。

2. 硬件连接 (STM32 与 MAX31865)

MAX31865 通过 SPI 接口与 STM32 连接。以下是常见的连接方式(以 STM32F103C8T6 和 3 线制 PT100 为例):

MAX31865 引脚 STM32 引脚 (SPI1) 功能说明
VDD 3.3V 电源正极
GND GND 电源地
CS PA4 (或其它 GPIO) SPI 片选 (软件 NSS)
SDI PA7 (SPI1_MOSI) SPI 数据输入 (主机输出)
SDO PA6 (SPI1_MISO) SPI 数据输出 (主机输入)
SCK PA5 (SPI1_SCK) SPI 时钟

PT100 与 MAX31865 的连接(3线制)

注意:不同的 MAX31865 模块厂商,跳线设置方式可能略有不同,请务必参考你的模块具体说明。

3. 软件配置与代码

3.1 SPI 初始化 (STM32 HAL库)

首先需要初始化 STM32 的 SPI 外设。

#include "stm32f1xx_hal.h"

SPI_HandleTypeDef hspi1;

void SPI1_Init(void)
{
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;   // CPOL = 0
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;       // CPHA = 0
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; // 例如 72MHz / 32 = 2.25 MHz
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
}

3.2 MAX31865 初始化配置

通过 SPI 向 MAX31865 的配置寄存器写入设置,使其工作在所需模式(如 3 线制、自动转换、50Hz/60Hz 滤波等)。

#define MAX31865_CONFIG_REG 0x00
#define MAX31865_RTD_MSB_REG 0x01
#define MAX31865_RTD_LSB_REG 0x02

// 配置寄存器位定义
#define MAX31865_CONFIG_BIAS_ON (0x80)
#define MAX31865_CONFIG_BIAS_OFF (0x00)
#define MAX31865_CONFIG_MODE_AUTO (0x40) // VBIAS 持续开启,自动转换
#define MAX31865_CONFIG_MODE_OFF (0x00)
#define MAX31865_CONFIG_3WIRE (0x10) // 1=3线制, 0=2/4线制
#define MAX31865_CONFIG_FAULT_STATUS_AUTO_CLEAR (0x0C)
#define MAX31865_CONFIG_FILTER_50HZ (0x01)
#define MAX31865_CONFIG_FILTER_60HZ (0x00)

void MAX31865_Init(void)
{
    uint8_t config_data[2];
    uint8_t rx_data[2];

    // 选择3线制、50Hz滤波、自动故障清除、开启自动转换模式
    config_data[0] = 0x80; // 写配置寄存器(最高位为1)
    config_data[1] = MAX31865_CONFIG_BIAS_ON | MAX31865_CONFIG_MODE_AUTO | MAX31865_CONFIG_3WIRE | MAX31865_CONFIG_FAULT_STATUS_AUTO_CLEAR | MAX31865_CONFIG_FILTER_50HZ;

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS拉低
    HAL_SPI_Transmit(&hspi1, config_data, 2, 100);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS拉高
}

3.3 读取温度数据和计算

读取 RTD 电阻值并转换为温度。

float MAX31865_ReadTemperature(void)
{
    uint8_t tx_data;
    uint8_t rtd_data[2];
    uint16_t rtd_raw;
    float resistance, temperature;
    float Rref = 430.0; // 参考电阻值,根据模块实际电阻填写(常见430Ω)
    float R0 = 100.0;   // PT100在0°C时的标称电阻值

    // 1. 读取RTD ADC值(2字节)
    tx_data = MAX31865_RTD_MSB_REG;
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, &tx_data, 1, 100);
    HAL_SPI_Receive(&hspi1, rtd_data, 2, 100);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

    // 组合MSB和LSB,并右移1位(15位数据)
    rtd_raw = ((rtd_data[0] << 8) | rtd_data[1]) >> 1;

    // 2. 计算RTD电阻值
    // RTD电阻值 = (ADC读数 * Rref) / 32768
    resistance = (rtd_raw * Rref) / 32768.0;

    // 3. 根据电阻值计算温度 (使用Callendar-Van Dusen公式简化或查表)
    // 简化计算(适用于0°C以上):
    // temperature = (resistance - R0) / (R0 * 0.00385); // α = 0.00385
    
    // 更精确的计算(考虑非线性,适用于更宽范围):
    // 这里是一个近似计算,如需高精度请查阅PT100分度表或使用完整的Callendar-Van Dusen公式
    float Z1, Z2, Z3, Z4;
    Z1 = -0.0039083;
    Z2 = 0.000017608;
    Z3 = -0.000000005;
    Z4 = (resistance / R0) - 1;
    temperature = (Z1 + sqrt(Z2 + Z3 * Z4)) / (2 * Z3); // 求解二次方程

    return temperature;
}

3.4 主循环示例

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    SPI1_Init();
    MX_GPIO_Init(); // 初始化CS等GPIO
    MAX31865_Init();

    while (1)
    {
        float temp = MAX31865_ReadTemperature();
        printf("Temperature: %.2f °C\r\n", temp); // 通过串口打印
        HAL_Delay(1000); // 每秒读取一次
    }
}

参考代码 STM32 读取max31855的数据,传感器为PT100 www.youwenfan.com/contentcsh/56760.html

4. 注意和常见问题

  1. 跳线设置至关重要务必根据PT100的线制(2、3、4线)正确设置MAX31865模块上的跳线。错误的设置会导致读数不准甚至损坏传感器或模块。
  2. 参考电阻 (Rref):代码中的 Rref 变量值必须与你的 MAX31865 模块上实际焊接的参考电阻值一致(常见的是 430Ω 或 400Ω)。不准的 Rref 值会直接导致测量误差。
  3. SPI 时序与模式:确保 STM32 的 SPI 时钟极性 (CPOL) 和相位 (CPHA) 与 MAX31865 要求匹配。通常模式为 CPOL=0, CPHA=0CPOL=0, CPHA=1
  4. 故障检测:MAX31865 具有故障检测功能。读取配置寄存器或单独的故障状态寄存器可以获取故障信息(如开路、短路),建议在代码中添加故障检查逻辑。
  5. 滤波频率:根据电源频率(国内 50Hz)选择合适的滤波器设置(MAX31865_CONFIG_FILTER_50HZ),以抑制工频干扰。
  6. 温度计算精度:上述提供的温度计算公式是近似值。对于高精度应用,建议使用查表法或完整的 Callendar-Van Dusen 方程进行计算。
  7. 接线可靠性:PT100 传感器和 MAX31865 之间的连接要牢固,接触电阻会影响测量精度,尤其是在 2 线制模式下。

专注于matlab/simulink,电子电路,编程