一、简介:
SGM459 是一款高精度数字温度传感器,采用 I2C 接口通信,测量范围为 - 40°C 至 + 125°C,精度可达 ±0.5°C(典型值)。它具有低功耗特性,工作电流仅为 1.5μA(典型值),非常适合电池供电的便携式设备。传感器输出 16 位温度数据,分辨率最高可达 0.0078125°C。
二、SGM459 的主要寄存器包括:
-
温度寄存器 (0x00)
- 16 位只读寄存器,存储最新的温度转换结果
- 高字节在前,低字节在后
- 数据格式:二进制补码
-
配置寄存器 (0x01)
- 8 位读写寄存器,用于配置传感器工作模式
- 位 7-5:分辨率设置 (000=9 位,001=10 位,010=11 位,011=12 位)
- 位 4:转换模式 (0 = 单次转换,1 = 连续转换)
- 位 3:关机模式 (0 = 正常工作,1 = 关机)
- 位 2-0:未使用
-
T_HIGH 寄存器 (0x02)
- 16 位读写寄存器,用于温度上限报警设置
-
T_LOW 寄存器 (0x03)
- 16 位读写寄存器,用于温度下限报警设置
三、典型应用:
四、封装及引脚说明:
五、头文件:
#ifndef __SGM459_H
#define __SGM459_H
#include "stm32l4xx_hal.h"
/* SGM459 I2C地址定义 (根据A0引脚电平选择) */
#define SGM459_ADDR_A0_LOW 0x48 // A0引脚接地时的I2C地址
#define SGM459_ADDR_A0_HIGH 0x49 // A0引脚接VDD时的I2C地址
/* SGM459寄存器地址 */
#define SGM459_REG_TEMP 0x00 // 温度寄存器
#define SGM459_REG_CONFIG 0x01 // 配置寄存器
#define SGM459_REG_T_HIGH 0x02 // 温度上限寄存器
#define SGM459_REG_T_LOW 0x03 // 温度下限寄存器
/* 温度分辨率配置 */
typedef enum {
SGM459_RESOLUTION_9BIT = 0x00, // 9位分辨率,精度0.5°C
SGM459_RESOLUTION_10BIT = 0x20, // 10位分辨率,精度0.25°C
SGM459_RESOLUTION_11BIT = 0x40, // 11位分辨率,精度0.125°C
SGM459_RESOLUTION_12BIT = 0x60 // 12位分辨率,精度0.0625°C
} SGM459_Resolution_t;
/* 转换模式配置 */
typedef enum {
SGM459_MODE_ONE_SHOT = 0x00, // 单次转换模式
SGM459_MODE_CONTINUOUS = 0x10 // 连续转换模式
} SGM459_Mode_t;
/* SGM459设备句柄 */
typedef struct {
I2C_HandleTypeDef* hi2c; // I2C句柄
uint8_t address; // 设备I2C地址
} SGM459_HandleTypeDef;
/* 函数声明 */
HAL_StatusTypeDef SGM459_Init(SGM459_HandleTypeDef* hsgm459, I2C_HandleTypeDef* hi2c, uint8_t address);
HAL_StatusTypeDef SGM459_Config(SGM459_HandleTypeDef* hsgm459, SGM459_Resolution_t resolution, SGM459_Mode_t mode);
HAL_StatusTypeDef SGM459_ReadTemperature(SGM459_HandleTypeDef* hsgm459, float* temperature);
HAL_StatusTypeDef SGM459_SetAlertThresholds(SGM459_HandleTypeDef* hsgm459, float high_temp, float low_temp);
HAL_StatusTypeDef SGM459_ReadAlertStatus(SGM459_HandleTypeDef* hsgm459, uint8_t* alert_status);
#endif /* __SGM459_H */
六、源文件:
#include "sgm459.h"
/**
* @brief 初始化SGM459传感器
* @param hsgm459 SGM459设备句柄
* @param hi2c I2C句柄
* @param address 设备I2C地址
* @retval HAL状态
*/
HAL_StatusTypeDef SGM459_Init(SGM459_HandleTypeDef* hsgm459, I2C_HandleTypeDef* hi2c, uint8_t address) {
if (hsgm459 == NULL || hi2c == NULL) {
return HAL_ERROR;
}
hsgm459->hi2c = hi2c;
hsgm459->address = (address << 1); // 转换为7位地址格式
// 软复位传感器
uint8_t config_data = 0x00;
return HAL_I2C_Mem_Write(hsgm459->hi2c, hsgm459->address, SGM459_REG_CONFIG, 1, &config_data, 1, 100);
}
/**
* @brief 配置SGM459传感器
* @param hsgm459 SGM459设备句柄
* @param resolution 温度分辨率
* @param mode 转换模式
* @retval HAL状态
*/
HAL_StatusTypeDef SGM459_Config(SGM459_HandleTypeDef* hsgm459, SGM459_Resolution_t resolution, SGM459_Mode_t mode) {
if (hsgm459 == NULL) {
return HAL_ERROR;
}
uint8_t config_data = resolution | mode;
return HAL_I2C_Mem_Write(hsgm459->hi2c, hsgm459->address, SGM459_REG_CONFIG, 1, &config_data, 1, 100);
}
/**
* @brief 读取SGM459温度值
* @param hsgm459 SGM459设备句柄
* @param temperature 温度值(摄氏度)
* @retval HAL状态
*/
HAL_StatusTypeDef SGM459_ReadTemperature(SGM459_HandleTypeDef* hsgm459, float* temperature) {
if (hsgm459 == NULL || temperature == NULL) {
return HAL_ERROR;
}
uint8_t temp_data[2] = {0};
HAL_StatusTypeDef status = HAL_I2C_Mem_Read(hsgm459->hi2c, hsgm459->address, SGM459_REG_TEMP, 1, temp_data, 2, 100);
if (status == HAL_OK) {
// 转换温度数据
int16_t raw_temp = (temp_data[0] << 8) | temp_data[1];
*temperature = (float)(raw_temp >> 4) * 0.0625f; // 12位分辨率计算
}
return status;
}
/**
* @brief 设置温度报警阈值
* @param hsgm459 SGM459设备句柄
* @param high_temp 高温阈值(摄氏度)
* @param low_temp 低温阈值(摄氏度)
* @retval HAL状态
*/
HAL_StatusTypeDef SGM459_SetAlertThresholds(SGM459_HandleTypeDef* hsgm459, float high_temp, float low_temp) {
if (hsgm459 == NULL || high_temp <= low_temp) {
return HAL_ERROR;
}
HAL_StatusTypeDef status;
uint8_t threshold_data[2];
// 设置高温阈值
int16_t high_raw = (int16_t)(high_temp / 0.0625f) << 4;
threshold_data[0] = (high_raw >> 8) & 0xFF;
threshold_data[1] = high_raw & 0xFF;
status = HAL_I2C_Mem_Write(hsgm459->hi2c, hsgm459->address, SGM459_REG_T_HIGH, 1, threshold_data, 2, 100);
if (status != HAL_OK) {
return status;
}
// 设置低温阈值
int16_t low_raw = (int16_t)(low_temp / 0.0625f) << 4;
threshold_data[0] = (low_raw >> 8) & 0xFF;
threshold_data[1] = low_raw & 0xFF;
status = HAL_I2C_Mem_Write(hsgm459->hi2c, hsgm459->address, SGM459_REG_T_LOW, 1, threshold_data, 2, 100);
return status;
}
/**
* @brief 读取报警状态
* @param hsgm459 SGM459设备句柄
* @param alert_status 报警状态(0=正常, 1=高温报警, 2=低温报警)
* @retval HAL状态
*/
HAL_StatusTypeDef SGM459_ReadAlertStatus(SGM459_HandleTypeDef* hsgm459, uint8_t* alert_status) {
if (hsgm459 == NULL || alert_status == NULL) {
return HAL_ERROR;
}
uint8_t temp_data[2] = {0};
HAL_StatusTypeDef status = HAL_I2C_Mem_Read(hsgm459->hi2c, hsgm459->address, SGM459_REG_TEMP, 1, temp_data, 2, 100);
if (status == HAL_OK) {
int16_t current_temp = (temp_data[0] << 8) | temp_data[1];
// 读取高温阈值
status = HAL_I2C_Mem_Read(hsgm459->hi2c, hsgm459->address, SGM459_REG_T_HIGH, 1, temp_data, 2, 100);
if (status != HAL_OK) {
return status;
}
int16_t high_temp = (temp_data[0] << 8) | temp_data[1];
// 读取低温阈值
status = HAL_I2C_Mem_Read(hsgm459->hi2c, hsgm459->address, SGM459_REG_T_LOW, 1, temp_data, 2, 100);
if (status != HAL_OK) {
return status;
}
int16_t low_temp = (temp_data[0] << 8) | temp_data[1];
// 比较温度值
if (current_temp > high_temp) {
*alert_status = 1; // 高温报警
} else if (current_temp < low_temp) {
*alert_status = 2; // 低温报警
} else {
*alert_status = 0; // 正常
}
}
return status;
}
七、应用:
#include "main.h"
#include "sgm459.h"
#include "stdio.h"
/* 定义全局变量 */
I2C_HandleTypeDef hi2c1;
SGM459_HandleTypeDef hsgm459;
/* 函数声明 */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
void UART_Printf(const char* format, ...);
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
// 初始化SGM459传感器
SGM459_Init(&hsgm459, &hi2c1, SGM459_ADDR_A0_LOW);
// 配置传感器为12位分辨率,连续转换模式
SGM459_Config(&hsgm459, SGM459_RESOLUTION_12BIT, SGM459_MODE_CONTINUOUS);
// 设置温度报警阈值
SGM459_SetAlertThresholds(&hsgm459, 30.0f, 20.0f);
UART_Printf("SGM459 Temperature Sensor Demo\r\n");
UART_Printf("--------------------------------\r\n");
while (1) {
float temperature;
uint8_t alert_status;
// 读取当前温度
if (SGM459_ReadTemperature(&hsgm459, &temperature) == HAL_OK) {
UART_Printf("Current Temperature: %.2f°C\r\n", temperature);
} else {
UART_Printf("Failed to read temperature!\r\n");
}
// 读取报警状态
if (SGM459_ReadAlertStatus(&hsgm459, &alert_status) == HAL_OK) {
if (alert_status == 1) {
UART_Printf("ALERT: Temperature too high!\r\n");
} else if (alert_status == 2) {
UART_Printf("ALERT: Temperature too low!\r\n");
}
}
HAL_Delay(1000); // 每秒读取一次
}
}
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
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();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) {
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) {
Error_Handler();
}
}
/**
* @brief 重定向printf函数到UART
* @param format 格式化字符串
* @param ... 可变参数
* @retval None
*/
void UART_Printf(const char* format, ...) {
static char buffer[256];
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
// 这里需要根据实际UART配置实现发送功能
// HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
}