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

一、简介:

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 接口进行通信,标准硬件连接如下:

  1. 引脚定义

    • VDD:电源正极(2.7V-5.5V)
    • GND:地
    • SDA:I2C 数据线
    • SCL:I2C 时钟线

四、寄存器说明:

SGM458 共有 8 个寄存器,主要包括温度数据寄存器、配置寄存器和阈值寄存器:

  1. 温度寄存器(0x00)

    • 16 位寄存器,存放当前温度测量值
    • 格式:12 位整数部分,4 位小数部分
    • 分辨率:0.0625°C/LSB
    • 数据格式:补码表示
  2. 配置寄存器(0x01)

    • 8 位寄存器,用于配置传感器工作模式
    • 位 7:OS 比较 / 中断模式选择
    • 位 6:OS 极性设置
    • 位 5-4:OS 故障队列设置
    • 位 3:工作模式控制
    • 位 2-0:转换速率设置
  3. 高温阈值寄存器(0x02)

    • 16 位寄存器,存放高温报警阈值
    • 格式与温度寄存器相同
  4. 低温阈值寄存器(0x03)

    • 16 位寄存器,存放低温报警阈值
    • 格式与温度寄存器相同
  5. 临界温度寄存器(0x04)

    • 16 位寄存器,存放临界温度阈值
    • 格式与温度寄存器相同
  6. 温度转换寄存器(0x05)

    • 8 位寄存器,存放温度转换配置
    • 位 7-6:温度分辨率设置
  7. 制造商 ID 寄存器(0xFE)

    • 8 位只读寄存器,存放制造商 ID(固定为 0x41,表示 SGMicro)
  8. 设备 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;
}    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值