一、简介:
SGM457 是一款高精度、低功耗的数字温度传感器,采用 I2C 接口通信,测量范围为 - 40°C 至 + 125°C,精度可达 ±0.25°C(典型值)。它具有极低的工作电流(1.5μA 典型值)和关机电流(0.1μA 典型值),非常适合电池供电的便携式设备。传感器输出 16 位温度数据,分辨率最高可达 0.0078125°C,并且支持温度报警功能。
二、典型应用:
三、寄存器说明:
-
温度寄存器 (0x00)
- 16 位只读寄存器,存储最新的温度转换结果
- 高字节在前,低字节在后
- 数据格式:二进制补码
-
配置寄存器 (0x01)
- 8 位读写寄存器,用于配置传感器工作模式
- 位 7-5:分辨率设置 (000=9 位,001=10 位,010=11 位,011=12 位)
- 位 4:转换模式 (0 = 单次转换,1 = 连续转换)
- 位 3:关机模式 (0 = 正常工作,1 = 关机)
- 位 2:ALERT 极性 (0 = 低电平有效,1 = 高电平有效)
- 位 1:ALERT 模式 (0 = 比较器模式,1 = 中断模式)
- 位 0:未使用
-
T_HIGH 寄存器 (0x02)
- 16 位读写寄存器,用于温度上限报警设置
-
T_LOW 寄存器 (0x03)
- 16 位读写寄存器,用于温度下限报警设置
-
配置寄存器 2 (0x04)
- 8 位读写寄存器,用于高级配置
- 位 7-5:未使用
- 位 4:自动关断 (0 = 禁用,1 = 启用)
- 位 3-0:转换周期设置
四、封装及引脚定义:
各引脚功能如下:
- VDD:电源正极 (2.7V-5.5V)
- GND:地
- SDA:I2C 数据线
- SCL:I2C 时钟线
- A0:I2C 地址选择位 (接地时地址为 0x48,接 VDD 时为 0x49)
- ALERT:温度报警输出 (开漏输出,需外接上拉电阻)
五、头文件:
#ifndef __SGM457_H
#define __SGM457_H
#include "stm32l4xx_hal.h"
/* SGM457 I2C地址 */
#define SGM457_I2C_ADDRESS 0x48 << 1 // 7位地址左移1位
/* SGM457寄存器地址 */
#define SGM457_TEMP_REG 0x00 // 温度寄存器
#define SGM457_CONFIG_REG 0x01 // 配置寄存器
#define SGM457_TLOW_REG 0x02 // 温度下限寄存器
#define SGM457_THIGH_REG 0x03 // 温度上限寄存器
/* 配置寄存器位定义 */
#define SGM457_CONFIG_OS_COMP_INT 0x80 // OS工作模式位
#define SGM457_CONFIG_ALERT_POL 0x40 // 告警极性位
#define SGM457_CONFIG_OS_FQUE_1 0x00 // OS故障队列1次
#define SGM457_CONFIG_OS_FQUE_2 0x08 // OS故障队列2次
#define SGM457_CONFIG_OS_FQUE_4 0x10 // OS故障队列4次
#define SGM457_CONFIG_OS_FQUE_6 0x18 // OS故障队列6次
#define SGM457_CONFIG_CONV_RATE_0 0x00 // 转换速率0.25Hz
#define SGM457_CONFIG_CONV_RATE_1 0x01 // 转换速率1Hz
#define SGM457_CONFIG_CONV_RATE_2 0x02 // 转换速率4Hz
#define SGM457_CONFIG_CONV_RATE_3 0x03 // 转换速率8Hz
#define SGM457_CONFIG_SHUTDOWN 0x01 // 关机模式
/* 函数声明 */
uint8_t SGM457_Init(I2C_HandleTypeDef *hi2c);
uint8_t SGM457_ReadTemperature(I2C_HandleTypeDef *hi2c, float *temperature);
uint8_t SGM457_SetConfig(I2C_HandleTypeDef *hi2c, uint8_t config);
uint8_t SGM457_ReadConfig(I2C_HandleTypeDef *hi2c, uint8_t *config);
uint8_t SGM457_SetLowTempThreshold(I2C_HandleTypeDef *hi2c, float temperature);
uint8_t SGM457_SetHighTempThreshold(I2C_HandleTypeDef *hi2c, float temperature);
uint8_t SGM457_ReadLowTempThreshold(I2C_HandleTypeDef *hi2c, float *temperature);
uint8_t SGM457_ReadHighTempThreshold(I2C_HandleTypeDef *hi2c, float *temperature);
uint8_t SGM457_GetAlertStatus(I2C_HandleTypeDef *hi2c, uint8_t *alert);
#endif /* __SGM457_H */
六、源文件:
#include "sgm457.h"
/**
* @brief 初始化SGM457温度传感器
* @param hi2c: I2C句柄
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_Init(I2C_HandleTypeDef *hi2c)
{
uint8_t config = SGM457_CONFIG_CONV_RATE_1; // 默认配置为1Hz转换速率
return SGM457_SetConfig(hi2c, config);
}
/**
* @brief 读取当前温度值
* @param hi2c: I2C句柄
* @param temperature: 存储温度值的指针
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_ReadTemperature(I2C_HandleTypeDef *hi2c, float *temperature)
{
uint8_t buffer[2];
int16_t temp_raw;
// 读取温度寄存器
if (HAL_I2C_Mem_Read(hi2c, SGM457_I2C_ADDRESS, SGM457_TEMP_REG, I2C_MEMADD_SIZE_8BIT, buffer, 2, 1000) != HAL_OK)
{
return HAL_ERROR;
}
// 转换温度数据
temp_raw = (buffer[0] << 8) | buffer[1];
temp_raw >>= 4; // 温度数据在高12位
// 计算实际温度值 (分辨率0.0625°C)
*temperature = (float)temp_raw * 0.0625f;
return HAL_OK;
}
/**
* @brief 设置配置寄存器
* @param hi2c: I2C句柄
* @param config: 配置值
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_SetConfig(I2C_HandleTypeDef *hi2c, uint8_t config)
{
return HAL_I2C_Mem_Write(hi2c, SGM457_I2C_ADDRESS, SGM457_CONFIG_REG, I2C_MEMADD_SIZE_8BIT, &config, 1, 1000);
}
/**
* @brief 读取配置寄存器
* @param hi2c: I2C句柄
* @param config: 存储配置值的指针
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_ReadConfig(I2C_HandleTypeDef *hi2c, uint8_t *config)
{
return HAL_I2C_Mem_Read(hi2c, SGM457_I2C_ADDRESS, SGM457_CONFIG_REG, I2C_MEMADD_SIZE_8BIT, config, 1, 1000);
}
/**
* @brief 设置温度下限阈值
* @param hi2c: I2C句柄
* @param temperature: 温度阈值(°C)
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_SetLowTempThreshold(I2C_HandleTypeDef *hi2c, float temperature)
{
uint16_t temp_raw = (uint16_t)(temperature / 0.0625f);
uint8_t buffer[2];
buffer[0] = (temp_raw >> 8) & 0xFF;
buffer[1] = temp_raw & 0xFF;
return HAL_I2C_Mem_Write(hi2c, SGM457_I2C_ADDRESS, SGM457_TLOW_REG, I2C_MEMADD_SIZE_8BIT, buffer, 2, 1000);
}
/**
* @brief 设置温度上限阈值
* @param hi2c: I2C句柄
* @param temperature: 温度阈值(°C)
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_SetHighTempThreshold(I2C_HandleTypeDef *hi2c, float temperature)
{
uint16_t temp_raw = (uint16_t)(temperature / 0.0625f);
uint8_t buffer[2];
buffer[0] = (temp_raw >> 8) & 0xFF;
buffer[1] = temp_raw & 0xFF;
return HAL_I2C_Mem_Write(hi2c, SGM457_I2C_ADDRESS, SGM457_THIGH_REG, I2C_MEMADD_SIZE_8BIT, buffer, 2, 1000);
}
/**
* @brief 读取温度下限阈值
* @param hi2c: I2C句柄
* @param temperature: 存储温度阈值的指针(°C)
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_ReadLowTempThreshold(I2C_HandleTypeDef *hi2c, float *temperature)
{
uint8_t buffer[2];
int16_t temp_raw;
if (HAL_I2C_Mem_Read(hi2c, SGM457_I2C_ADDRESS, SGM457_TLOW_REG, I2C_MEMADD_SIZE_8BIT, buffer, 2, 1000) != HAL_OK)
{
return HAL_ERROR;
}
temp_raw = (buffer[0] << 8) | buffer[1];
*temperature = (float)temp_raw * 0.0625f;
return HAL_OK;
}
/**
* @brief 读取温度上限阈值
* @param hi2c: I2C句柄
* @param temperature: 存储温度阈值的指针(°C)
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_ReadHighTempThreshold(I2C_HandleTypeDef *hi2c, float *temperature)
{
uint8_t buffer[2];
int16_t temp_raw;
if (HAL_I2C_Mem_Read(hi2c, SGM457_I2C_ADDRESS, SGM457_THIGH_REG, I2C_MEMADD_SIZE_8BIT, buffer, 2, 1000) != HAL_OK)
{
return HAL_ERROR;
}
temp_raw = (buffer[0] << 8) | buffer[1];
*temperature = (float)temp_raw * 0.0625f;
return HAL_OK;
}
/**
* @brief 获取告警状态
* @param hi2c: I2C句柄
* @param alert: 存储告警状态的指针(1表示告警,0表示正常)
* @retval 状态码: HAL_OK表示成功,其他值表示失败
*/
uint8_t SGM457_GetAlertStatus(I2C_HandleTypeDef *hi2c, uint8_t *alert)
{
uint8_t config;
if (SGM457_ReadConfig(hi2c, &config) != HAL_OK)
{
return HAL_ERROR;
}
*alert = (config & 0x80) ? 1 : 0; // OS位是配置寄存器的最高位
return HAL_OK;
}
七、应用:
#include "main.h"
#include "sgm457.h"
#include "stdio.h"
/* 定义I2C句柄 */
I2C_HandleTypeDef hi2c1;
/* 定义UART句柄用于调试输出 */
UART_HandleTypeDef huart2;
/* 函数声明 */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART2_UART_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
float temperature;
uint8_t status;
uint8_t alert;
/* 初始化SGM457传感器 */
status = SGM457_Init(&hi2c1);
if (status != HAL_OK)
{
printf("SGM457初始化失败!\r\n");
while(1);
}
/* 设置温度阈值 */
SGM457_SetLowTempThreshold(&hi2c1, 20.0f);
SGM457_SetHighTempThreshold(&hi2c1, 30.0f);
printf("SGM457温度传感器示例程序\r\n");
while (1)
{
/* 读取当前温度 */
if (SGM457_ReadTemperature(&hi2c1, &temperature) == HAL_OK)
{
printf("当前温度: %.2f°C\r\n", temperature);
}
else
{
printf("读取温度失败!\r\n");
}
/* 检查告警状态 */
if (SGM457_GetAlertStatus(&hi2c1, &alert) == HAL_OK)
{
if (alert)
{
printf("警告: 温度超出阈值范围!\r\n");
}
}
HAL_Delay(1000); // 每秒读取一次
}
}
/**
* @brief 配置系统时钟
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** 初始化RCC振荡器
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** 初始化RCC时钟
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief 初始化I2C1
*/
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00303D5B;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** 配置I2C快速模式
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief 初始化USART2
*/
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief 初始化GPIO
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
}
/**
* @brief 错误处理函数
*/
void Error_Handler(void)
{
while(1)
{
}
}
/* 实现printf函数用于串口输出 */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}