STM32F407ZGT6驱动MAX31865获取PT100温度数据
STM32F407ZGT6驱动MAX31865读取PT100温度传感器获取温度
·
目录
一、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 为写操作。
①、配置寄存器(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-Shot)指令之前,可通过向该位写 1 使能 V B I A S V_{BIAS} VBIAS。
- 选择自动(连续)转换模式时, V B I A S V_{BIAS} VBIAS保持有效状态。
- D6(转换模式)位:向该位写 1 时,选择自动转换模式,以 50/60 Hz 速率连续转换;向该位写 0 时,退出自动转换模式,进入 “常闭” 模式,该模式下可发送单次转换命令。
- D5(1-Shot)位:转换模式为 “常闭” 时,向该位写 1 启动一次电阻测试转换。向该位写 1 后, CS ‾ \overline{\text{CS}} CS 变为高电平时触发转换。
- 在启动转换之前开启 V B I A S V_{BIAS} VBIAS,并等待至少 10.5 倍的输入RC网络时间常数加上 1ms。
- 单次转换完成时间在 60Hz 滤波模式下需要约 52ms,在 50Hz 滤波模式下需要 62.5ms。
- 1-Shot 为自动清零位。
- D4(3-Wire)位:使用 3 线 RTD 连接时,该位写 1;使用 2 线或 4 线连接时,向该位写 0。
- D3:D2(故障检测周期)位:主控制器启动的故障检测周期有两种工作模式:手动和自动模式。
- 如果外部 RTD 接口电路包括时间常数大于 100µs 的输入滤波器,故障检测周期时序应采用手动模式控制。
- 为进入自动故障检测,向配置寄存器写 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 及其谐波。
注意:自动转换模式下,不要更改陷波频率。
②、RTD 电阻寄存器(01h−02h)
- RTD MSB 和 RTD LSB 两个 8 位寄存器包含 RTD 电阻数据。
- 数据格式为 RTD 电阻与参考电阻的比值,包含 15 位有效数据。
- 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 = 基准电阻的阻值
③、故障门限寄存器(03h−06h)
- 故障上限和故障下限寄存器用于选择 RTD 故障检测的触发门限。将 RTD 转换结果与这些寄存器值进行比较,在故障状态寄存器中置位 “Fault” (D[7:6])。
- 如果 RTD 电阻寄存器值大于或等于故障上限寄存器值,置位故障状态寄存器的 RTD High。
- 如果 RTD 电阻值小于或等于故障下限寄存器值,则置位故障状态寄存器的 RTD Low。
④、故障状态寄存器(07h)
- 故障状态寄存器锁存所有检测到的故障位。
- 向配置寄存器中的故障状态清除位写 1 时,将全部故障状态位清零。
2、MAX31865 通过 SPI 进行通信
- MAX31865 支持 SPI 模式 1 和 3。
- SPI 通信使用四个引脚:SDO(串行数据输出)、SDI(串行数据输入)、CS(片选)和 SCLK(串行时钟)。
- SDI 和 SDO 分别是器件的串行数据输入和输出引脚。
读操作时,从 SDO 输出数据;写操作时,数据输入至 SDI。- CS ‾ \overline{\text{CS}} CS 输入启动和终止数据传输。
- SCLK 同步主机(微控制器)和从机(MAX31865)之间的数据传输。
- 地址和数据字节移入串行数据输入(SDI)和移出串行数据输出(SDO)时,MSB 在前。
- 任何传输都需要地址字节指定写或读操作,后面跟一个或多个数据字节。
- CS ‾ \overline{\text{CS}} CS 驱动为低电平后,传输的第一个字节总为地址字节,该字节的 MSB(A7)决定随后的字节为写还是为读操作。
- 如果 A7 为 0,地址字节后为一个或多个字节读操作;
- 如果 A7 为 1,地址字节后为一个或多个字节写操作。
- 对于单字节传输,读或写 1 个字节,然后 CS ‾ \overline{\text{CS}} CS 驱动为高电平。
- 对于多字节传输,写入地址后,可以读或写多个字节。
- 只要 CS ‾ \overline{\text{CS}} CS 保持为低电平,地址则连续在全部存储器内递增。
- 如果继续移入或移出数据,地址则从 7Fh/FFh 返回至 00h/80h。
- 存储器地址无效时,报告 FFh 值。
- 注意:如果对只读寄存器执行写操作,不改变该寄存器的值。
- 注意:CPHA 位极性必须设置为 1。
二、硬件设计
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 及其外围电路,电源和隔离部分电路可以参考用户手册。
3、PT100/PT1000
- 默认是 4 线模式。
三、程序设计
1、读取温度数据的步骤
- 配置 MAX31865 传感器:设置 MAX31865 配置寄存器。
- 发送读取命令:发送读取 RTD 电阻寄存器(01h−02h)命令。
- 读取数据:接收传感器返回的 15 位有效数据。
- 数据转换:将 15 位数据通过公式转换为实际的温度值。
- 数据显示:可以通过串口或 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);
}
}
四、功能展示 - 串口显示

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