MAX31865是简单易用的热敏电阻至数字输出转换器,优化用于铂电阻温度检测器(RTD)。外部电阻设置RTD灵敏度,高精度Δ- Σ ADC将RTD电阻与基准电阻之比转换为数字输出。MAX31865输入具有高达±45V的过压保护,提供可配置的RTD及电缆开路、短路条件检测。
驱动源码可参考如下:
/*********start********第一块max31865芯片相关************************/
//硬件对应
#define T1_SCLK PFout(8) // 对应PG1
#define T1_MISO PFin(6) // 对应PF15
#define T1_MOSI PFout(4) // 对应PF13
#define T1_CS PFout(2) // 对应PF11
#define T1_RE PFin(0) // 对应PB1
//信号描述定义
#define SDI_H T1_MOSI=1
#define SDI_L T1_MOSI=0
#define SCLK_H T1_SCLK=1
#define SCLK_L T1_SCLK=0
#define NCS_H T1_CS=1
#define NCS_L T1_CS=0
#define SDO T1_MISO
#define DRDY T1_RE
//数据变量
IO_EXT u8 Fault_Status; //出水max31865芯片错误标志
IO_EXT float tempture; //出水
IO_EXT u16 temp1_ad; //出水的AD值
/*********end********第一块max31865芯片相关************************/
//功能实现函数
IO_EXT void ConfigurePortPins(void); //初始化 引脚功能
IO_EXT void Task_ReadIOInfo(void); //读取IO资源函数
IO_EXT void MAX31865_SB_Write(u8 addr,u8 wdata); //3线配置MAX31865
IO_EXT u8 MAX31865_SB_Read(u8 addr);
#define IO_GLOBAL
#include "io.h"
#include "main.h"
/**
* @brief MAX31865芯片所用单片机引脚的初始化
* @param
* @param
* @retval
*/
static void MAX31865_Port_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Cloc #########################*/
/* Enable GPIO TX/RX clock */
__HAL_RCC_GPIOF_CLK_ENABLE();
/* SPI SCK GPIO pin configuration******** PG1 */
GPIO_InitStruct.Pin = GPIO_PIN_8; //哪个引脚
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //输出
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //速度选最快的
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* SPI MISO GPIO pin configuration****** PF15 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* SPI MOSI GPIO pin configuration**** PF13 */
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* SPI cs GPIO pin configuration**** PF11 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* re GPIO pin configuration****** PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
NCS_H;
SCLK_H;
}
/**
* @brief IO资源引脚的初始化
* @param
* @param
* @retval
*/
void ConfigurePortPins(void)
{
MAX31865_Port_Init();
}
#define DT_NUM 0x30 //延时时间
/**
* @brief 简单粗暴的延时函数
* @param
* @param
* @retval
*/
void Delay(u32 nCount)
{
for(; nCount != 0; nCount--);
}
/**
* @brief 读max31865的寄存器
* @param 地址
* @param
* @retval
*/
u8 MAX31865_SB_Read(u8 addr)//SPI Single-Byte Read
{
u8 i=0;
u8 read = 0;
NCS_L;
Delay(DT_NUM);
for(i = 0; i < 8; i++)
{
SCLK_L;
if (addr & 0x80)
{SDI_H;}
else
{SDI_L;}
Delay(DT_NUM);
SCLK_H;
addr <<= 1;
Delay(DT_NUM);
}
Delay(DT_NUM);
for (i = 0; i < 8; i++)
{
SCLK_L;
read = read<<1;
Delay(DT_NUM);
if(SDO)
{
read++;
}
SCLK_H;
Delay(DT_NUM);
}
NCS_H;
return read;
}
/**
* @brief 写max31865的寄存器
* @param 地址
* @param 数据
* @retval
*/
void MAX31865_SB_Write(u8 addr,u8 wdata)//SPI Single-Byte Write
{
u8 i = 0;
NCS_L; //拉低片选信号
Delay(DT_NUM); //粗暴延时
//写地址
for(i = 0; i < 8; i++) //0-7
{
SCLK_L; //时钟线拉高
if (addr & 0x80) // xxxx xxxx & 1000 0000 addr最高位是否为1简单判断
{SDI_H;} // 为1 发送高电平
else
{SDI_L;} //为0 发送低电平
Delay(DT_NUM); //粗暴延时
SCLK_H; //时钟线拉低
addr <<= 1; //数据左移 判断次高位
Delay(DT_NUM); //粗暴延时
}
//写数据
for(i = 0; i < 8; i++)
{
SCLK_L;
if (wdata & 0x80)
{SDI_H;}
else {SDI_L;}
Delay(DT_NUM);
SCLK_H;
wdata <<= 1;
Delay(DT_NUM);
}
//操作完成拉高片选
NCS_H;
}
/**
* @brief 简单滤波计算温度值
* @param
* @param
* @retval 扩大100倍的温度
*/
u8 temp1;
u8 temp2;
float Get_tempture(void)//PT100
{
float temps;
u16 dtemp[2];
u16 data_temp;
u8 i;
static u8 cnt_num =0;
static u16 temp1_num[8];
static u32 temp1_sum;
static u16 temp1_min =0;
static u16 temp1_max =0;
dtemp[0]=MAX31865_SB_Read(0x01);//读RTD_MSB
dtemp[1]=MAX31865_SB_Read(0x02);//读RTD_LSB
data_temp=(dtemp[0]<<7)+(dtemp[1]>>1);//Get 15Bit DATA;
temp1=dtemp[0];
temp2=dtemp[1];
temp1_ad = data_temp;
if(cnt_num<8)cnt_num++;
else cnt_num=0;
temp1_num[cnt_num] = data_temp;
temp1_min = temp1_num[cnt_num];
temp1_max = temp1_num[cnt_num];
if(power_time < 10) return 0;
for (i=0,temp1_sum=0; i<8; i++)
{
temp1_sum += temp1_num[i];
if (temp1_num[i]<=temp1_min) temp1_min = temp1_num[i];
if (temp1_num[i]>=temp1_max) temp1_max = temp1_num[i];
}
temp1_sum -= temp1_min;
temp1_sum -= temp1_max;
temps = temp1_sum/6;
temps=(temps*402)/32768;//Here is the rtd R value;
temps=(temps-100)*100/0.385055;//A gruad 本身值经扩大100倍单位为1摄氏度
return temps;
}
/**
* @brief 得到PT100温度值
* @param
* @param
* @retval
*/
void GetPT100_Temp(void)
{
u8 i;
static u8 cnt_num =0;
static float temp1_num[64];
static float temp1_sum;
static float temp1_min =0;
static float temp1_max =0;
if(cnt_num<64)cnt_num++;
else cnt_num=0;
temp1_num[cnt_num] = Get_tempture();
temp1_min = temp1_num[cnt_num];
temp1_max = temp1_num[cnt_num];
if(power_time < 10) return;
for (i=0,temp1_sum=0; i<64; i++)
{
temp1_sum += temp1_num[i];
if (temp1_num[i]<=temp1_min) temp1_min = temp1_num[i];
if (temp1_num[i]>=temp1_max) temp1_max = temp1_num[i];
}
temp1_sum -= temp1_min;
temp1_sum -= temp1_max;
tempture = temp1_sum/62;
Fault_Status=MAX31865_SB_Read(0x07);//Get Fault_Status
}
/**
* @brief 读取IO资源
* @param
* @param
* @retval
*/