MAX31855温度分辨率 0.25°C,内部自集成了冷端温度,用户可以用一个芯片实现热电偶温度数据读取。
STM32驱动使用HAL库,MAX31855使用软件SPI方式,用户使用时要对应修改SPI引脚。
调用 Max31855_Read_Data()函数; 就能读取温度传感器数据
最终的温度数据存放 SensorData.thermocouple_temperatur 是真实的浮点温度,单位°C,例如 10.25°C
程序正常用在工程上,用户使用时数据解析如果有问题,麻烦看下手册相关说明 会更有收获
程序E K S …各热电偶通用,美信MAX31855K 芯片尾号带K,就是K型热电偶专用。芯片内部会自动加载K热电偶分度表计算温度(这样用户就不用关心热电偶分度表了)
///温度传感器芯片使用 MAX31855K K型热电偶
///使用GPIO模拟的 软件SPI方式 对应的引脚
#define SPI_CS_HIGH() HAL_GPIO_WritePin( SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET )
#define SPI_CS_LOW() HAL_GPIO_WritePin( SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET)
#define SPI_SCLK_HIGH() HAL_GPIO_WritePin( SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_SET )
#define SPI_SCLK_LOW() HAL_GPIO_WritePin( SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_RESET)
#define READ_SPI_MISO() HAL_GPIO_ReadPin( SPI_MISO_GPIO_Port, SPI_MISO_Pin)
#define MAX31855_DATA_BIT_NUM 32 ///总共32BIT数据
#define SACN_TEMPERATURE_TASK_TIME 100
#define THERMOCOUPLE_TEMPERATUR_FITER_TIME 16 ///16次滑动滤波
#define MAX31855_FAULT_BIT (1<<16)
SensorStruct SensorData;
///MAX31855读取数据
uint32_t Max31855_Read_Data( void )
{
uint32_t temp_reg = 0;
SPI_CS_LOW();
SPI_SCLK_LOW();
for( uint8_t i = 0; i < MAX31855_DATA_BIT_NUM; i ++ )
{
temp_reg <<= 1;
SPI_SCLK_HIGH();
if( READ_SPI_MISO() == GPIO_PIN_SET ) ///高电平
{
temp_reg |= 1;
}
SPI_SCLK_LOW();
}
SPI_CS_HIGH();
return temp_reg;
}
///滤波函数
float Thermocouple_Temperatur_Fiter( float new_temp )
{
static uint8_t counter = 0;
static uint8_t cal_counter = 0;
static float temp_buffer[THERMOCOUPLE_TEMPERATUR_FITER_TIME];
float sum_temp = 0.0;
temp_buffer[counter] = new_temp;
counter++;
if( counter >= THERMOCOUPLE_TEMPERATUR_FITER_TIME )
{
counter = 0; ///环形填充BUF
}
cal_counter++; ///分母加
if( cal_counter >= THERMOCOUPLE_TEMPERATUR_FITER_TIME )
{
cal_counter = THERMOCOUPLE_TEMPERATUR_FITER_TIME; //
}
for( uint8_t temp = 0; temp < cal_counter; temp++ )
{
sum_temp += temp_buffer[temp];
}
sum_temp = ( sum_temp / cal_counter );
return sum_temp;
}
///温度扫描任务
void Scan_Temperature_Task( void )
{
uint32_t sensor_data = 0;
uint8_t temp[4] = {0x00, 0x00, 0x00,0x00};
int16_t temp_int16 = 0X0000;
float temp_float = 0.0;
if( TaskTime.scan_temperature_counter >= SACN_TEMPERATURE_TASK_TIME )
{
TaskTime.scan_temperature_counter = 0;
sensor_data = Max31855_Read_Data(); ///读取温度传感器数据
///获取错误标志
if( sensor_data & MAX31855_FAULT_BIT )
{
SensorData.fault_byte |= SENSOR_FAULT_BIT;
}
else
{
SensorData.fault_byte &= ~SENSOR_FAULT_BIT;
}
///SCV
if( sensor_data & SENSOR_SCV_FAULT_BIT )
{
SensorData.fault_byte |= SENSOR_SCV_FAULT_BIT;
}
else
{
SensorData.fault_byte &= ~SENSOR_SCV_FAULT_BIT;
}
///SCG
if( sensor_data & SENSOR_SCG_FAULT_BIT )
{
SensorData.fault_byte |= SENSOR_SCG_FAULT_BIT;
}
else
{
SensorData.fault_byte &= ~SENSOR_SCG_FAULT_BIT;
}
///OC
if( sensor_data & SENSOR_OC_FAULT_BIT )
{
SensorData.fault_byte |= SENSOR_OC_FAULT_BIT;
}
else
{
SensorData.fault_byte &= ~SENSOR_OC_FAULT_BIT;
}
temp[0] = ( uint8_t )( sensor_data >> 24 );
temp[1] = ( uint8_t )( sensor_data >> 16 );
temp[2] = ( uint8_t )( sensor_data >> 8 );
temp[3] = ( uint8_t )( sensor_data >> 0 );
///获取热电偶温度数据
temp_int16 = ( int16_t )( ( temp[0] << 8 ) | ( temp[1] << 0 ) );
///得到带符号的热电偶温度数值
temp_int16 = ( temp_int16 & 0XFFFC ); ///去掉BIT17 BIT16。就是带符号的数 左移4倍(放大16倍,要还原)
temp_float = temp_int16;
temp_float = ( temp_float / 16 ); ///还回原真实温度
SensorData.thermocouple_temperatur=Thermocouple_Temperatur_Fiter(temp_float); ///滤波后的数据
///获取冷端温度数据
///冷端温度暂时不使用,也不滤波
temp_int16=0X0000;
temp_int16 = ( int16_t )( ( temp[2] << 8 ) | ( temp[3] << 0 ) );
///得到带符号的冷端温度数值
temp_int16 = ( temp_int16 & 0XFFF0 ); ///去掉BIT0-BIT3 。就是带符号的数 左移8位(放大256倍,要还原)
SensorData.coldend_temperatur = temp_int16;
SensorData.coldend_temperatur = ( SensorData.coldend_temperatur / 256 ); ///还回原真实温度
}
}