基于STM32L4XX 、HAL库的SGM457数字温度传感器驱动应用C语言程序设计

一、简介:

SGM457 是一款高精度、低功耗的数字温度传感器,采用 I2C 接口通信,测量范围为 - 40°C 至 + 125°C,精度可达 ±0.25°C(典型值)。它具有极低的工作电流(1.5μA 典型值)和关机电流(0.1μA 典型值),非常适合电池供电的便携式设备。传感器输出 16 位温度数据,分辨率最高可达 0.0078125°C,并且支持温度报警功能。

二、典型应用:

                                      

三、寄存器说明:

  1. 温度寄存器 (0x00)

    • 16 位只读寄存器,存储最新的温度转换结果
    • 高字节在前,低字节在后
    • 数据格式:二进制补码
  2. 配置寄存器 (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:未使用
  3. T_HIGH 寄存器 (0x02)

    • 16 位读写寄存器,用于温度上限报警设置
  4. T_LOW 寄存器 (0x03)

    • 16 位读写寄存器,用于温度下限报警设置
  5. 配置寄存器 2 (0x04)

    • 8 位读写寄存器,用于高级配置
    • 位 7-5:未使用
    • 位 4:自动关断 (0 = 禁用,1 = 启用)
    • 位 3-0:转换周期设置

四、封装及引脚定义:

                                               

各引脚功能如下:

  1. VDD:电源正极 (2.7V-5.5V)
  2. GND:地
  3. SDA:I2C 数据线
  4. SCL:I2C 时钟线
  5. A0:I2C 地址选择位 (接地时地址为 0x48,接 VDD 时为 0x49)
  6. 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;
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值