一、MAX31865 温湿度传感器

  • MAX31865 是 RTD 数字转换器,内置 15 位模/数转换器(ADC)、输入保护、数字控制器、SPI 兼容接口以及相关的控制逻辑电路。
    信号调理电路优化用于 PT100-PT1000 RTD,也支持其它热敏电阻。
  • 电阻温度检测器(RTD)是一种阻值随温度变化的电阻。
    铂是最常见、精度最高的测温金属丝材料。铂 RTD 称为 PT-RTD。
  • 对于 PT-RTD,最常见的电阻是:0°C 下标称值为 100Ω 和 1kΩ,当然也有其它阻值。0°C 和+100°C 之间的平均斜率称为阿尔法(α),斜率与铂的杂质及密度有关。
    最常见的两个 α 值是:0.00385 和 0.00392,分别对应于 IEC 751 (PT100) 和 SAMA 标准。

1、MAX31865 相关寄存器

  • MAX31865 通过 8 个 8 位寄存器实现转换、状态和配置数据功能。
  • 存取寄存器时,地址 0Xh 为读操作,地址 8Xh 为写操作。

表1. 寄存器地址和POR状态

①、配置寄存器(00h)

  • 配置寄存器选择转换模式(自动模式或单次转换命令触发模式)、使能和禁止 BIAS 引脚输出 V B I A S V_{BIAS} VBIAS、发送单次转换命令、选择 RTD 连接方式(3 线或 2/4 线)、启动一次故障检测、清空故障状态寄存器,以及选择滤波器陷波频率。
  • D7(BIAS)位:不进行温度转换时,可禁止 V B I A S V_{BIAS} VBIAS,以降低功耗。
    1. 发送单次转换(1-Shot)指令之前,可通过向该位写 1 使能 V B I A S V_{BIAS} VBIAS
    2. 选择自动(连续)转换模式时, V B I A S V_{BIAS} VBIAS保持有效状态。
  • D6(转换模式)位:向该位写 1 时,选择自动转换模式,以 50/60 Hz 速率连续转换;向该位写 0 时,退出自动转换模式,进入 “常闭” 模式,该模式下可发送单次转换命令。
  • D5(1-Shot)位:转换模式为 “常闭” 时,向该位写 1 启动一次电阻测试转换。向该位写 1 后, CS ‾ \overline{\text{CS}} CS 变为高电平时触发转换。
    1. 在启动转换之前开启 V B I A S V_{BIAS} VBIAS,并等待至少 10.5 倍的输入RC网络时间常数加上 1ms。
    2. 单次转换完成时间在 60Hz 滤波模式下需要约 52ms,在 50Hz 滤波模式下需要 62.5ms。
    3. 1-Shot 为自动清零位。
  • D4(3-Wire)位:使用 3 线 RTD 连接时,该位写 1;使用 2 线或 4 线连接时,向该位写 0。
  • D3:D2(故障检测周期)位:主控制器启动的故障检测周期有两种工作模式:手动和自动模式。
    1. 如果外部 RTD 接口电路包括时间常数大于 100µs 的输入滤波器,故障检测周期时序应采用手动模式控制。
    2. 为进入自动故障检测,向配置寄存器写 100X010Xb,此时 ADC 处于“常闭”模式。
      自动故障检测周期在检查故障之前插入 100µs 延迟,允许外部输入滤波器达到稳定。完成检测后,故障检测周期设置位(D[3:2])自动清除为00b。
  • D1(故障状态清零)位:向 D5、D3 和 D2 位写 0 的同时向该位写 1,将使故障寄存器的全部故障状态位(D[7:2])清零。
    如果仍然存在过压/欠压故障,故障寄存器的 D2 位、RTD LSB 寄存器的 D0 位可能立即再次置位。故障状态清除位 D1 自动清零。
  • D0(50/60Hz)位:选择噪声抑制滤波器的陷波频率。向该位写 0 时,抑制 60Hz 及其谐波;向该位写 1 时抑制 50Hz 及其谐波。
    注意:自动转换模式下,不要更改陷波频率

表2. 配置寄存器定义

②、RTD 电阻寄存器(01h−02h)

  • RTD MSB 和 RTD LSB 两个 8 位寄存器包含 RTD 电阻数据。
    1. 数据格式为 RTD 电阻与参考电阻的比值,包含 15 位有效数据。
    2. RTD LSB 寄存器的 D0 为故障位,表示是否检测到任意 RTD 故障。
  • 将 RTD 数据寄存器中 15 位 ADC 转换结果转换为 RTD 的阻值:
    R R T D = ( A D C   C o d e × R R E F ) / 2 15 R_{RTD} = (ADC \ Code × R_{REF})/2^{15} RRTD=(ADC Code×RREF)/215
    ADC 编码 = RTD 数据寄存器(01h – 02h)中的 15 位 ADC 转换结果
    R R E F R_{REF} RREF = 基准电阻的阻值

表4. RTD电阻寄存器定义,表5. RTD电阻与数据的关系

③、故障门限寄存器(03h−06h)

  • 故障上限和故障下限寄存器用于选择 RTD 故障检测的触发门限。将 RTD 转换结果与这些寄存器值进行比较,在故障状态寄存器中置位 “Fault” (D[7:6])。
  • 如果 RTD 电阻寄存器值大于或等于故障上限寄存器值,置位故障状态寄存器的 RTD High。
  • 如果 RTD 电阻值小于或等于故障下限寄存器值,则置位故障状态寄存器的 RTD Low。

表6. 故障门限寄存器定义

④、故障状态寄存器(07h)

  • 故障状态寄存器锁存所有检测到的故障位。
  • 向配置寄存器中的故障状态清除位写 1 时,将全部故障状态位清零。

表7. 故障状态寄存器定义

2、MAX31865 通过 SPI 进行通信

  • MAX31865 支持 SPI 模式 1 和 3
  • SPI 通信使用四个引脚:SDO(串行数据输出)、SDI(串行数据输入)、CS(片选)和 SCLK(串行时钟)。
    1. SDI 和 SDO 分别是器件的串行数据输入和输出引脚。
      读操作时,从 SDO 输出数据;写操作时,数据输入至 SDI。
    2. CS ‾ \overline{\text{CS}} CS 输入启动和终止数据传输。
    3. SCLK 同步主机(微控制器)和从机(MAX31865)之间的数据传输。
  • 地址和数据字节移入串行数据输入(SDI)和移出串行数据输出(SDO)时,MSB 在前
  • 任何传输都需要地址字节指定写或读操作,后面跟一个或多个数据字节。
    1. CS ‾ \overline{\text{CS}} CS 驱动为低电平后,传输的第一个字节总为地址字节,该字节的 MSB(A7)决定随后的字节为写还是为读操作。
    2. 如果 A7 为 0,地址字节后为一个或多个字节操作;
    3. 如果 A7 为 1,地址字节后为一个或多个字节操作。
  • 对于单字节传输,读或写 1 个字节,然后 CS ‾ \overline{\text{CS}} CS 驱动为高电平。
  • 对于多字节传输,写入地址后,可以读或写多个字节。
    1. 只要 CS ‾ \overline{\text{CS}} CS 保持为低电平,地址则连续在全部存储器内递增。
    2. 如果继续移入或移出数据,地址则从 7Fh/FFh 返回至 00h/80h。
    3. 存储器地址无效时,报告 FFh 值。
  • 注意:如果对只读寄存器执行写操作,不改变该寄存器的值
  • 注意:CPHA 位极性必须设置为 1

表8. 功能表,图5. 串行时钟为微控制器时钟极性(CPOL)的函数
图6. SPI单字节读,图7. SPI单字节写
图8. SPI多字节传输

二、硬件设计

1、接线说明

MAX31865 模块 STM32F407ZGT6 引脚定义
VIN 3.3V 电源正极 VCC
GND GND 电源负极 GND
SCLK B3 串行数据时钟输入引脚
SDO B4 串行数据输出引脚
SDI B5 串行数据输入引脚
nCS B6 低电平有效片选引脚
MAX31865 模块 PT100/PT1000 引脚定义
FORCE+ 红线 高边RTD驱动
RTD+ 红线 RTD输入正端
RTD- 蓝线 RTD输入负端
FORCE- 蓝线 低边RTD回路

2、模块设计

  • 只截取了 MAX31865 及其外围电路,电源和隔离部分电路可以参考用户手册。

MAX31865 及其外围电路

3、PT100/PT1000

  • 默认是 4 线模式。

两线连接方式
三线连接方式
四线连接方式

三、程序设计

1、读取温度数据的步骤

  1. 配置 MAX31865 传感器:设置 MAX31865 配置寄存器。
  2. 发送读取命令:发送读取 RTD 电阻寄存器(01h−02h)命令。
  3. 读取数据:接收传感器返回的 15 位有效数据。
  4. 数据转换:将 15 位数据通过公式转换为实际的温度值。
  5. 数据显示:可以通过串口或 OLED 屏幕显示实际的温度值。

2、max31865_hardspi.h

#ifndef __MAX31865_HARDSPI_H
#define __MAX31865_HARDSPI_H

#include "./SYSTEM/sys/sys.h"


/******************************************************************************************/
/* 基准电阻的阻值 */

#define PT100_Resistance_Ref                    402.0f              /* PT100基准电阻的阻值 */
#define PT1000_Resistance_Ref                   4020.0f             /* PT1000基准电阻的阻值 */

/******************************************************************************************/


/******************************************************************************************/
/* 指令表 */

#define MAX31865_CONFIG_REG                     0x00                /* 配置寄存器(00h、80h) */

#define MAX31865_RTD_MSB_REG                    0x01                /* RTD电阻寄存器 - RTD MSBS(01h) */
#define MAX31865_RTD_LSB_REG                    0x02                /* RTD电阻寄存器 - RTD LSBS(02h) */

#define MAX31865_RTD_HIGH_MSB_THRESHOLD_REG     0x03                /* 故障门限寄存器(03h、83h) */
#define MAX31865_RTD_HIGH_LSB_THRESHOLD_REG     0x04                /* 故障门限寄存器(04h、84h) */

#define MAX31865_RTD_LOW_MSB_THRESHOLD_REG      0x03                /* 故障门限寄存器(05h、85h) */
#define MAX31865_RTD_LOW_LSB_THRESHOLD_REG      0x04                /* 故障门限寄存器(06h、86h) */

#define MAX31865_FAULT_STATUS_REG               0x07                /* 故障状态寄存器(07h) */

/******************************************************************************************/


/******************************************************************************************/
/* 配置寄存器 */

#define MAX31865_Init_2_4_Line                  0xC1                /* 2、4线模式 */
#define MAX31865_Init_3_Line                    0xD1                /* 3线模式 */

/******************************************************************************************/


/******************************************************************************************/
/* 函数声明 */

void MAX31865_Init_HardSPI(void);                                   /* 硬件SPI初始化MAX31865 */

uint8_t MAX31865_ReadRegister_HardSPI(uint8_t reg);                 /* 硬件SPI读取MAX31865寄存器 */
void MAX31865_WriteRegister_HardSPI(uint8_t reg, uint8_t data);     /* 硬件SPI写MAX31865寄存器 */

float MAX31865_Get_Temperature_HardSPI(void);                       /* 获取温度值 */
uint8_t MAX31865_Set_Configuration(uint8_t data);                   /* 设置配置寄存器 */
uint8_t MAX31865_Read_Fault_Status(void);                           /* 读取故障状态寄存器 */

/******************************************************************************************/


#endif  /* __MAX31865_HARDSPI_H */

3、max31865_hardspi.c

#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"

#include "./BSP/SPI/hardspi.h"
#include "./BSP/MAX31865/max31865_hardspi.h"


/**
 * @brief       硬件SPI初始化MAX31865
 * @param       无
 * @retval      无
 */
void MAX31865_Init_HardSPI(void)
{
    HardSPI1_CS1_Init();                                    /* 初始化CS1引脚 */
    HSPI1_CS1(1);
    
    HardSPI1_Init();                                        /* 初始化硬件SPI:SCK、MISO、MOSI */
    
    HSPI1_Set_Speed(SPI_SPEED_32);                          /* 设置SPI1速度 */
    
    MAX31865_Set_Configuration(MAX31865_Init_2_4_Line);     /* 设置配置寄存器 */
}

/**
 * @brief       硬件SPI读取MAX31865寄存器
 * @param       reg:寄存器
 * @retval      data:读取到的寄存器的值
 */
uint8_t MAX31865_ReadRegister_HardSPI(uint8_t reg)
{
    uint8_t data = 0;
    
    HSPI1_CS1(0);
    
    HSPI1_Read_Write_Byte(reg & 0x7F);
    data = HSPI1_Read_Write_Byte(0xFF);
    
    HSPI1_CS1(1);
    
    return data;
}

/**
 * @brief       硬件SPI写MAX31865寄存器
 * @param       reg:寄存器
 * @param       data:写寄存器的值
 * @retval      无
 */
void MAX31865_WriteRegister_HardSPI(uint8_t reg, uint8_t data)
{
    HSPI1_CS1(0);
    
    HSPI1_Read_Write_Byte(reg | 0x80);
    HSPI1_Read_Write_Byte(data);
    
    HSPI1_CS1(1);
}


/**
 * @brief       获取温度值
 * @param       无
 * @retval      temperature:温度值
 */
float MAX31865_Get_Temperature_HardSPI(void)
{
    uint16_t adc_code[2];
    uint16_t data_adc_code;

    float resistance;
    float temperature;

    /* RTD LSB寄存器的D0为故障位,表示是否检测到任意RTD故障。 */
    adc_code[0] = MAX31865_ReadRegister_HardSPI(MAX31865_RTD_MSB_REG);      /* 读取RTD MSBS(01h)寄存器 */
    printf("RTD_MSB:%x\r\n", adc_code[0]);
    adc_code[1] = MAX31865_ReadRegister_HardSPI(MAX31865_RTD_LSB_REG);      /* 读取RTD LSBS(02h)寄存器 */
    printf("RTD_LSB:%x\r\n", adc_code[1]);
    
    data_adc_code = (adc_code[0] << 7) | (adc_code[1] >> 1);                /* 获取15位有效数据 */
    printf("ADC_Code:%x\r\n", data_adc_code);
    
    resistance = ((float)data_adc_code * PT100_Resistance_Ref) / 32768.0f;  /* 计算RTD的电阻值:Rrtd = (ADC Code * Rref)/(2^15)*/
    printf("Resistance:%.2f\r\n", resistance);
    
    temperature = (resistance - 100.0f) / 0.385055f;                        /* 计算温度值 */
    printf("Temperature:%.2f\r\n", temperature);
    
    return temperature;                                                     /* 返回接收到的温度值 */
}

/**
 * @brief       设置配置寄存器
 * @param       data:要设置配置寄存器的值
 * @retval      Cfg_data:读取配置寄存器的值
 */
uint8_t MAX31865_Set_Configuration(uint8_t data)
{
    uint8_t Cfg_data;
    
    MAX31865_WriteRegister_HardSPI(MAX31865_CONFIG_REG, data);              /* 设置配置寄存器 */
    Cfg_data = MAX31865_ReadRegister_HardSPI(MAX31865_CONFIG_REG);          /* 读取配置寄存器 */
    printf("MAX31865_CONFIG_REG:%x\r\n", Cfg_data);
    
    return Cfg_data;
}

/**
 * @brief       读取故障状态寄存器
 * @param       无
 * @retval      data:读取到的故障状态寄存器的值
 */
uint8_t MAX31865_Read_Fault_Status(void)
{
    uint8_t data;
    uint8_t config_data;
    
    data = MAX31865_ReadRegister_HardSPI(MAX31865_FAULT_STATUS_REG);                /* 读取故障状态寄存器 */
    printf("MAX31865_FAULT_STATUS_REG:%x\r\n", data);
    
    config_data = MAX31865_ReadRegister_HardSPI(MAX31865_CONFIG_REG);               /* 读取配置寄存器 */
    MAX31865_WriteRegister_HardSPI(MAX31865_CONFIG_REG, config_data | 0x02);        /* 清除故障状态位 */
    
    data = MAX31865_ReadRegister_HardSPI(MAX31865_FAULT_STATUS_REG);                /* 读取故障状态寄存器 */
    printf("MAX31865_FAULT_STATUS_REG:%x\r\n", data);
    
    return data;
}

4、main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"

#include "configure.h"

#include "./BSP/MAX31865/max31865_hardspi.h"


int main(void)
{
    Configure_Init();

    while(1)
    {
        MAX31865_Set_Configuration(MAX31865_Init_2_4_Line);     /* 设置配置寄存器 */
        
        MAX31865_Get_Temperature_HardSPI();                     /* 获取温度值 */
        MAX31865_Read_Fault_Status();                           /* 读取故障状态寄存器 */
        delay_ms(2000);
    }
}

四、功能展示 - 串口显示

串口显示

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐