一、简介:
SGM458 是一款高精度、低功耗的数字温度传感器,采用 I2C 接口进行通信。该传感器提供 ±0.5°C 的精度(-20°C 至 + 85°C 范围内),分辨率可达 0.0625°C,工作电压范围为 2.7V 至 5.5V,非常适合电池供电的应用场景。
主要特性:
- 高精度:±0.5°C(典型值)
- 低功耗:工作电流 < 150μA,关机电流 < 1μA
- 宽温度范围:-40°C 至 + 125°C
- 可编程转换速率:0.25Hz 至 8Hz
- 比较器和中断模式
- SMBus/I2C 兼容接口
二、典型应用:
三、封装及引脚定义:
SGM458 采用 I2C 接口进行通信,标准硬件连接如下:
-
引脚定义
- VDD:电源正极(2.7V-5.5V)
- GND:地
- SDA:I2C 数据线
- SCL:I2C 时钟线
四、寄存器说明:
SGM458 共有 8 个寄存器,主要包括温度数据寄存器、配置寄存器和阈值寄存器:
-
温度寄存器(0x00)
- 16 位寄存器,存放当前温度测量值
- 格式:12 位整数部分,4 位小数部分
- 分辨率:0.0625°C/LSB
- 数据格式:补码表示
-
配置寄存器(0x01)
- 8 位寄存器,用于配置传感器工作模式
- 位 7:OS 比较 / 中断模式选择
- 位 6:OS 极性设置
- 位 5-4:OS 故障队列设置
- 位 3:工作模式控制
- 位 2-0:转换速率设置
-
高温阈值寄存器(0x02)
- 16 位寄存器,存放高温报警阈值
- 格式与温度寄存器相同
-
低温阈值寄存器(0x03)
- 16 位寄存器,存放低温报警阈值
- 格式与温度寄存器相同
-
临界温度寄存器(0x04)
- 16 位寄存器,存放临界温度阈值
- 格式与温度寄存器相同
-
温度转换寄存器(0x05)
- 8 位寄存器,存放温度转换配置
- 位 7-6:温度分辨率设置
-
制造商 ID 寄存器(0xFE)
- 8 位只读寄存器,存放制造商 ID(固定为 0x41,表示 SGMicro)
-
设备 ID 寄存器(0xFF)
- 8 位只读寄存器,存放设备 ID(固定为 0x58,表示 SGM458)
五、头文件:
#ifndef __SGM458_H
#define __SGM458_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32l4xx_hal.h"
/**
* @defgroup SGM458_Exported_Constants SGM458导出常量
* @{
*/
/* SGM458 I2C地址定义 */
#define SGM458_I2C_ADDRESS 0x48 /**< 7位I2C地址,左移一位后为0x90 */
#define SGM458_I2C_TIMEOUT 1000 /**< I2C通信超时时间(ms) */
/* SGM458寄存器地址 */
#define SGM458_TEMP_REG 0x00 /**< 温度寄存器 */
#define SGM458_CONFIG_REG 0x01 /**< 配置寄存器 */
#define SGM458_T_HIGH_REG 0x02 /**< 高温阈值寄存器 */
#define SGM458_T_LOW_REG 0x03 /**< 低温阈值寄存器 */
#define SGM458_T_CRIT_REG 0x04 /**< 临界温度寄存器 */
#define SGM458_T_CONV_REG 0x05 /**< 温度转换寄存器 */
#define SGM458_MANUF_ID_REG 0xFE /**< 制造商ID寄存器 */
#define SGM458_DEVICE_ID_REG 0xFF /**< 设备ID寄存器 */
/* 配置寄存器位定义 */
#define SGM458_CONFIG_OS_COMP_INT 0x80 /**< OS比较/中断模式位 */
#define SGM458_CONFIG_OS_POL 0x40 /**< OS极性位 */
#define SGM458_CONFIG_OS_F_QUE 0x30 /**< OS故障队列位掩码 */
#define SGM458_CONFIG_MODE 0x08 /**< 工作模式位掩码 */
#define SGM458_CONFIG_CONV_RATE 0x07 /**< 转换速率位掩码 */
/** @} */
/**
* @defgroup SGM458_Exported_Types SGM458导出类型
* @{
*/
/* 转换速率选项 */
typedef enum {
SGM458_CONV_RATE_0_25HZ = 0x00, /**< 0.25Hz转换速率 */
SGM458_CONV_RATE_1HZ = 0x01, /**< 1Hz转换速率 */
SGM458_CONV_RATE_4HZ = 0x02, /**< 4Hz转换速率 */
SGM458_CONV_RATE_8HZ = 0x03 /**< 8Hz转换速率 */
} SGM458_ConvRate_TypeDef;
/* 工作模式选项 */
typedef enum {
SGM458_MODE_CONTINUOUS = 0x00, /**< 连续转换模式 */
SGM458_MODE_ONE_SHOT = 0x01, /**< 单次转换模式 */
SGM458_MODE_SHUTDOWN = 0x02 /**< 关机模式 */
} SGM458_Mode_TypeDef;
/** @} */
/**
* @defgroup SGM458_Exported_Functions SGM458导出函数
* @{
*/
/**
* @brief 初始化SGM458温度传感器
* @param hi2c I2C句柄
* @return HAL状态码
*
* 该函数初始化SGM458传感器,设置默认配置参数为
* 连续转换模式,1Hz转换速率。
*/
HAL_StatusTypeDef SGM458_Init(I2C_HandleTypeDef *hi2c);
/**
* @brief 读取SGM458温度值
* @param hi2c I2C句柄
* @param temperature 温度值(摄氏度)
* @return HAL状态码
*
* 该函数从SGM458传感器读取当前温度值,
* 并将原始数据转换为摄氏度表示的浮点值。
*/
HAL_StatusTypeDef SGM458_ReadTemperature(I2C_HandleTypeDef *hi2c, float *temperature);
/**
* @brief 设置SGM458工作模式
* @param hi2c I2C句柄
* @param mode 工作模式
* @return HAL状态码
*
* 该函数设置SGM458传感器的工作模式,
* 包括连续转换、单次转换和关机模式。
*/
HAL_StatusTypeDef SGM458_SetMode(I2C_HandleTypeDef *hi2c, SGM458_Mode_TypeDef mode);
/**
* @brief 设置SGM458转换速率
* @param hi2c I2C句柄
* @param rate 转换速率
* @return HAL状态码
*
* 该函数设置SGM458传感器的温度转换速率,
* 可配置范围从0.25Hz到8Hz。
*/
HAL_StatusTypeDef SGM458_SetConversionRate(I2C_HandleTypeDef *hi2c, SGM458_ConvRate_TypeDef rate);
/**
* @brief 读取SGM458制造商ID
* @param hi2c I2C句柄
* @param manuf_id 制造商ID
* @return HAL状态码
*
* 该函数读取SGM458传感器的制造商ID,
* 标准值为0x41(表示SGMicro)。
*/
HAL_StatusTypeDef SGM458_ReadManufacturerID(I2C_HandleTypeDef *hi2c, uint8_t *manuf_id);
/**
* @brief 读取SGM458设备ID
* @param hi2c I2C句柄
* @param device_id 设备ID
* @return HAL状态码
*
* 该函数读取SGM458传感器的设备ID,
* 标准值为0x58(表示SGM458)。
*/
HAL_StatusTypeDef SGM458_ReadDeviceID(I2C_HandleTypeDef *hi2c, uint8_t *device_id);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __SGM458_H */
六、源文件:
#include "sgm458.h"
/**
* @brief 初始化SGM458温度传感器
* @param hi2c I2C句柄
* @return HAL状态码
*
* 该函数初始化SGM458传感器,设置默认配置参数为
* 连续转换模式,1Hz转换速率。
*/
HAL_StatusTypeDef SGM458_Init(I2C_HandleTypeDef *hi2c)
{
HAL_StatusTypeDef status;
uint8_t config = 0x00; /* 默认配置:连续转换,1Hz */
/* 设置转换速率为1Hz */
config |= (uint8_t)SGM458_CONV_RATE_1HZ;
/* 写入配置寄存器 */
status = HAL_I2C_Mem_Write(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_CONFIG_REG,
I2C_MEMADD_SIZE_8BIT, &config, 1, SGM458_I2C_TIMEOUT);
return status;
}
/**
* @brief 读取SGM458温度值
* @param hi2c I2C句柄
* @param temperature 温度值(摄氏度)
* @return HAL状态码
*
* 该函数从SGM458传感器读取当前温度值,
* 并将原始数据转换为摄氏度表示的浮点值。
*/
HAL_StatusTypeDef SGM458_ReadTemperature(I2C_HandleTypeDef *hi2c, float *temperature)
{
HAL_StatusTypeDef status;
uint8_t buffer[2];
int16_t temp_raw;
/* 读取温度寄存器 */
status = HAL_I2C_Mem_Read(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_TEMP_REG,
I2C_MEMADD_SIZE_8BIT, buffer, 2, SGM458_I2C_TIMEOUT);
if (status != HAL_OK) {
return status;
}
/* 合并两个字节为16位温度值 */
temp_raw = (int16_t)((buffer[0] << 8) | buffer[1]);
/* 右移4位,去掉低4位的小数部分 */
temp_raw >>= 4;
/* 转换为摄氏度 (分辨率为0.0625°C) */
*temperature = (float)temp_raw * 0.0625f;
return HAL_OK;
}
/**
* @brief 设置SGM458工作模式
* @param hi2c I2C句柄
* @param mode 工作模式
* @return HAL状态码
*
* 该函数设置SGM458传感器的工作模式,
* 包括连续转换、单次转换和关机模式。
*/
HAL_StatusTypeDef SGM458_SetMode(I2C_HandleTypeDef *hi2c, SGM458_Mode_TypeDef mode)
{
HAL_StatusTypeDef status;
uint8_t config;
/* 读取当前配置 */
status = HAL_I2C_Mem_Read(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_CONFIG_REG,
I2C_MEMADD_SIZE_8BIT, &config, 1, SGM458_I2C_TIMEOUT);
if (status != HAL_OK) {
return status;
}
/* 清除模式位 */
config &= ~SGM458_CONFIG_MODE;
/* 设置新的模式 */
switch (mode) {
case SGM458_MODE_CONTINUOUS:
config |= 0x00; /* 连续转换模式 */
break;
case SGM458_MODE_ONE_SHOT:
config |= 0x04; /* 单次转换模式 (写1触发) */
break;
case SGM458_MODE_SHUTDOWN:
config |= 0x08; /* 关机模式 */
break;
default:
return HAL_ERROR;
}
/* 写入新配置 */
status = HAL_I2C_Mem_Write(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_CONFIG_REG,
I2C_MEMADD_SIZE_8BIT, &config, 1, SGM458_I2C_TIMEOUT);
return status;
}
/**
* @brief 设置SGM458转换速率
* @param hi2c I2C句柄
* @param rate 转换速率
* @return HAL状态码
*
* 该函数设置SGM458传感器的温度转换速率,
* 可配置范围从0.25Hz到8Hz。
*/
HAL_StatusTypeDef SGM458_SetConversionRate(I2C_HandleTypeDef *hi2c, SGM458_ConvRate_TypeDef rate)
{
HAL_StatusTypeDef status;
uint8_t config;
/* 读取当前配置 */
status = HAL_I2C_Mem_Read(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_CONFIG_REG,
I2C_MEMADD_SIZE_8BIT, &config, 1, SGM458_I2C_TIMEOUT);
if (status != HAL_OK) {
return status;
}
/* 清除转换速率位 */
config &= ~SGM458_CONFIG_CONV_RATE;
/* 设置新的转换速率 */
config |= (uint8_t)rate;
/* 写入新配置 */
status = HAL_I2C_Mem_Write(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_CONFIG_REG,
I2C_MEMADD_SIZE_8BIT, &config, 1, SGM458_I2C_TIMEOUT);
return status;
}
/**
* @brief 读取SGM458制造商ID
* @param hi2c I2C句柄
* @param manuf_id 制造商ID
* @return HAL状态码
*
* 该函数读取SGM458传感器的制造商ID,
* 标准值为0x41(表示SGMicro)。
*/
HAL_StatusTypeDef SGM458_ReadManufacturerID(I2C_HandleTypeDef *hi2c, uint8_t *manuf_id)
{
return HAL_I2C_Mem_Read(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_MANUF_ID_REG,
I2C_MEMADD_SIZE_8BIT, manuf_id, 1, SGM458_I2C_TIMEOUT);
}
/**
* @brief 读取SGM458设备ID
* @param hi2c I2C句柄
* @param device_id 设备ID
* @return HAL状态码
*
* 该函数读取SGM458传感器的设备ID,
* 标准值为0x58(表示SGM458)。
*/
HAL_StatusTypeDef SGM458_ReadDeviceID(I2C_HandleTypeDef *hi2c, uint8_t *device_id)
{
return HAL_I2C_Mem_Read(hi2c, SGM458_I2C_ADDRESS << 1, SGM458_DEVICE_ID_REG,
I2C_MEMADD_SIZE_8BIT, device_id, 1, SGM458_I2C_TIMEOUT);
}
七、应用:
#include "main.h"
#include "sgm458.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_StatusTypeDef status;
float temperature;
uint8_t manuf_id, device_id;
/* MCU初始化 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/* 打印初始化信息 */
printf("SGM458 Temperature Sensor Example\r\n");
printf("================================\r\n");
/* 初始化SGM458传感器 */
status = SGM458_Init(&hi2c1);
if (status != HAL_OK) {
printf("SGM458 initialization failed!\r\n");
while (1); /* 初始化失败,进入死循环 */
}
printf("SGM458 initialized successfully\r\n");
/* 读取制造商ID和设备ID进行验证 */
status = SGM458_ReadManufacturerID(&hi2c1, &manuf_id);
if (status == HAL_OK) {
printf("Manufacturer ID: 0x%02X (should be 0x41 for SGMicro)\r\n", manuf_id);
}
status = SGM458_ReadDeviceID(&hi2c1, &device_id);
if (status == HAL_OK) {
printf("Device ID: 0x%02X (should be 0x58 for SGM458)\r\n", device_id);
}
/* 设置转换速率为4Hz,提高采样频率 */
status = SGM458_SetConversionRate(&hi2c1, SGM458_CONV_RATE_4HZ);
if (status != HAL_OK) {
printf("Failed to set conversion rate!\r\n");
}
while (1)
{
/* 读取温度值 */
status = SGM458_ReadTemperature(&hi2c1, &temperature);
if (status == HAL_OK) {
printf("Temperature: %.2f C\r\n", temperature);
} else {
printf("Temperature read failed! Error code: %d\r\n", status);
}
/* 延时1秒 */
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; /* 标准模式,100kHz */
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时钟 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* 可以在这里添加额外的GPIO配置 */
}
/**
* @brief 错误处理函数
*/
void Error_Handler(void)
{
/* 错误处理实现 */
while(1)
{
/* 可以添加LED闪烁等错误指示 */
}
}
/* 重定向printf函数到USART2 */
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}