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

一、简介:

SGM459 是一款高精度数字温度传感器,采用 I2C 接口通信,测量范围为 - 40°C 至 + 125°C,精度可达 ±0.5°C(典型值)。它具有低功耗特性,工作电流仅为 1.5μA(典型值),非常适合电池供电的便携式设备。传感器输出 16 位温度数据,分辨率最高可达 0.0078125°C。

二、SGM459 的主要寄存器包括:

  1. 温度寄存器 (0x00)

    • 16 位只读寄存器,存储最新的温度转换结果
    • 高字节在前,低字节在后
    • 数据格式:二进制补码
  2. 配置寄存器 (0x01)

    • 8 位读写寄存器,用于配置传感器工作模式
    • 位 7-5:分辨率设置 (000=9 位,001=10 位,010=11 位,011=12 位)
    • 位 4:转换模式 (0 = 单次转换,1 = 连续转换)
    • 位 3:关机模式 (0 = 正常工作,1 = 关机)
    • 位 2-0:未使用
  3. T_HIGH 寄存器 (0x02)

    • 16 位读写寄存器,用于温度上限报警设置
  4. 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);
}    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值