zzz-29-PT100测温模块

数字转换模块(如 MAX31865)相比之前的模拟量变送器,它采用 SPI 数字通讯,避开了模拟信号的噪声和温漂,精度极高。

我们要把这个新成员加入到你的“User_Library”架构中。按照“从引脚到逻辑”的顺序,我们分三步走。

第一阶段:STM32CubeMX 引脚配置 (硬件层)

MAX31865 使用 SPI 协议。请在 CubeMX 中进行以下设置:

  1. SPI 配置
    • 选择一个闲置的 SPI(例如 SPI1)。
    • Mode: Full-Duplex Master(全双工主机)。
    • Hardware NSS: Disable(我们要用软件控制片选,更灵活)。
    • 参数设置
      • Baud Rate: 建议 1MBits/s 到 5MBits/s 之间。
      • CPOL: High (1) —— 空闲时时钟为高。
      • CPHA: 2nd Edge (1) —— 在第二个跳变沿采样(MAX31865 常用模式)。
      • First Bit: MSB First。
    • ![[Pasted image 20251228115855.png]]
  2. GPIO 配置 (CS 引脚)
    • 找一个普通引脚(例如 PA4)作为片选。
    • GPIO Output Level: High(默认不选通)。
    • User Label: MAX_CS
    • ![[Pasted image 20251228120028.png]]
  3. DRDY 引脚 (可选)
    • 找一个输入引脚(例如 PA3),用于检测转换是否完成。不接也可以,我们可以用延时或查寄存器代替。

关于硬件接线

模块引脚 功能说明 建议连接 STM32 引脚 备注
VIN 电源输入 (3-5V) 5V 或 3.3V 建议接 3.3V,与 STM32 电平一致
GND 电源地 GND 必须与单片机共地
CLK SPI 时钟 (Clock) PA5 (SPI1_SCK) 通讯节拍
SDO 串口输出 (MISO) PA6 (SPI1_MISO) 模块发数据给单片机
SDI 串口输入 (MOSI) PA7 (SPI1_MOSI) 单片机发数据给模块
CS 片选 (Chip Select) PA4 (GPIO) 手动控制,拉低才开始通讯

特殊引脚说明(可以暂时不接)

  • 3V3 引脚:
    • 如果你的模块 VIN 接了 5V,这个 3V3 通常是模块内置稳压芯片输出的 3.3V,可以不用管。
    • 注意:不要同时把 VIN 接 5V,又把 3V3 引脚接到单片机的 3.3V,这样可能会产生电流倒灌。
  • RDY (或 DRDY) 引脚:
    • 这是“数据就绪”信号。当芯片完成一次温度转换,它会把这个引脚拉低通知单片机。
    • 新手建议:先不接。我们在代码里使用简单的“延时等待”或者直接“读取寄存器”就能拿到数据,不需要占用额外的引脚。

PT100 端的接线(非常重要!)

模块的另一侧通常有几个焊盘或螺丝端子(通常标记为 Force+, Force-, RTDIn+, RTDIn-),这决定了你 PT100 的精度:

  • 2 线制:把引脚旁边的焊盘(通常标有 2/3/4 wire 的地方)按照说明书短接,PT100 两根线随便接。
  • 3 线制(工业最常用):这是你最可能买到的 PT100。模块上通常需要焊上一处短接点。
    • 接法:PT100 里面通常有两根颜色一样的线(比如红、蓝、蓝),两根颜色一样的接在一起。

第一步:用万用表确认(最稳妥)

在接线前,建议你拿万用表测一下这三根线,确保没有断线或阻值异常:

  • 红线 A 与 红线 B:阻值应该接近 $0\Omega$(通常只有 $0.2 \sim 0.5\Omega$ 的线阻)。
  • 白线 与 任意红线:在室温($25^\circ C$)左右,阻值应该在 $108 \sim 110\Omega$ 之间。

物理接线方案(两红一白)

三线制的本质是:一端用单线,另一端用双线来补偿线阻。

端子位置 标记 传感器线色 逻辑说明
第 1 个 (最左) F- 红线 1 电流回路负极
第 2 个 RTD- 红线 2 电压感知负极
第 3 个 RTD+ (空着) 正极感知(依靠背后的“3”焊盘连通到 F+)
第 4 个 (最右) F+ 白线 电流/电压正极

必须处理的“三个焊盘”

这是新手最容易失败的地方。请翻到模块背面(或者正面寻找标有 2/3/4 的区域):

  1. “2/3 Wire” 焊盘必须短接
    • 作用:告诉芯片启用三线制补偿算法。
  2. “3” 字样焊盘(通常在端子附近)必须短接
    • 作用:这会在内部把 Force+RTDIn+ 连接在一起。因为你只有一根白线,短接这里后,白线既负责供电,也负责检测电压。
  3. “2 Wire” 焊盘(通常是并排的两个)绝对不要动(保持开路)
    • 作用:这是给两线制准备的,短接它会毁掉你的红线补偿逻辑。

![[Pasted image 20251228122403.png]]

  • 位置 ① (2/3 Wire):必须焊上(短接)
    • 作用:告诉芯片启用补偿逻辑,准备处理 2 线或 3 线模式。
  • 位置 ② (2 Wire):保持断开(不要焊)
    • 原因:这是专门给两线制传感器用的。如果你焊了这里,三线制的线阻补偿功能就失效了,会导致测量温度偏高。
  • 位置 ③ (24 / 3 选区):将中间焊盘与标有“3”的一侧焊在一起
    • 作用:这是三线制最核心的跳线。它在硬件上将 Force+RTD+ 连通,使你的那一根白线同时承担供电和感知电压的任务。

为什么这么接?

  • 白线端:通过跳线将 F+RTD+ 合二为一,用一根线完成供电和检测。
  • 红线端:利用两根红线。一根(F-)负责跑电流,另一根(RTD-)负责探测电压。MAX31865 通过对比两端的电位差,就能自动减去红线的导线电阻,从而给出最精准的温度。

MAX31865 芯片测量温度的原理是测量 RTD+RTD- 之间的电压。

  • 4 线制F+ 供电,RTD+ 只负责测电压。
  • 3 线制:因为只有一根白线,所以白线既要当“供电员”(F+),又要当“检测员”(RTD+)。
  • 结论:只要在进入芯片之前,这两个点是连通的(不管是在 PCB 内部连,还是在端子外面连),芯片收到的信号都是一样的。

记住这个原则:哪里有“双线”,哪里就是负极 在三线制 PT100 的世界里,请务必遵守这个“潜规则”:

传感器侧 导线数量 对应模块端子 备注
单线侧 (白线) 1 根 $F+$ / $RTD+$ 这里需要通过焊接或跳线短接。
双线侧 (红线) 2 根 $RTD-$ / $F-$ 芯片靠这两根线来“感知”并“消灭”线阻。

快速“握手”测试(验证焊接和连线)

main.cwhile(1) 之前,先写这几行。如果串口能打印出 0xD1,说明你的 SPI 连线、焊接、片选全部正确!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 在 main.c 的 USER CODE BEGIN 2 处
uint8_t read_val = 0;
uint8_t reg_addr = 0x00; // 配置寄存器的读地址
uint8_t test_config = 0xD1; // 我们准备写入的值

// 1. 尝试写入配置
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 拉低 CS (PA4)
uint8_t write_buf[2] = {0x80, test_config}; // 0x80 是配置寄存器的写地址
HAL_SPI_Transmit(&hspi1, write_buf, 2, 100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);   // 拉高 CS

HAL_Delay(10);

// 2. 尝试读回配置
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 拉低 CS
HAL_SPI_Transmit(&hspi1, &reg_addr, 1, 100);
HAL_SPI_Receive(&hspi1, &read_val, 1, 100);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);   // 拉高 CS

printf("MAX31865 Config Reg: 0x%02X (Expected: 0xD1)\n", read_val);

这里可线停止打印电流、压力等参数,保持串口输出的内容不会刷一下子就跳过去了 ![[Pasted image 20251228161427.png]]

看到 0xD1 就说明硬件焊接、引脚连线、SPI 时序配置这三大难关已经全部打通了。芯片已经正确识别了你的指令,并做好了测量准备。

1
2
[16:12:57.342] MAX31865 Config Reg: 0xD1 (Expecte
[16:12:57.342] d: 0xD1)

1、完善正式驱动 (max31865.c)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "max31865.h"

static SPI_HandleTypeDef *max_hspi;

// 片选宏(假设你的 CS 接在 PA4)
#define MAX_CS_L() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define MAX_CS_H() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

void MAX31865_Init(SPI_HandleTypeDef *hspi) {
    max_hspi = hspi;
    // 写入配置:0xD1 (1101 0001) -> 开启偏置, 自动模式, 3线制, 50Hz滤波
    uint8_t buf[2] = {0x80, 0xD1}; 
    MAX_CS_L();
    HAL_SPI_Transmit(max_hspi, buf, 2, 100);
    MAX_CS_H();
}

/**
 * @brief 读取当前温度值
 * @return float 温度值 (摄氏度)
 */
float MAX31865_ReadTemp(void) {
    uint8_t addr = 0x01; // RTD 数据起始地址
    uint8_t raw[2];
    
    MAX_CS_L();
    HAL_SPI_Transmit(max_hspi, &addr, 1, 100);
    HAL_SPI_Receive(max_hspi, raw, 2, 100);
    MAX_CS_H();

    // 1. 合并为 16 位原始码,并去掉最后一位 Fault 标志位
    uint16_t rtd_code = ((raw[0] << 8) | raw[1]) >> 1;

    // 2. 计算电阻:$R = \frac{RTD\_Code \times R_{ref}}{32768}$
    // MAX31865_RREF 建议定义为 430.0f
    float resistance = (float)rtd_code * 430.0f / 32768.0f;

    // 3. 计算温度(简化线性公式):$T = \frac{R/R_{nominal} - 1}{0.003851}$
    // MAX31865_RNOMINAL 建议定义为 100.0f
    float temp = (resistance / 100.0f - 1.0f) / 0.003851f;
    
    return temp;
}

2、整合到 Logic_Update 业务层

参考资料

Licensed under CC BY-NC-SA 4.0