Stm32下环境传感器-Stlm75-hts221-spg30(Hal)

本文介绍了如何在STM32环境下使用HAL库驱动STLM75温度传感器、HTS221湿度和温度传感器以及SPG30空气质量传感器。提供了I2C接口的读写函数以及传感器的初始化和数据读取示例代码,帮助开发者快速集成这些传感器到自己的项目中。
摘要由CSDN通过智能技术生成

Stm32下环境传感器-Stlm75-hts221-spg30(Hal)

简介

Stlm75与Hts221都是ST的传感器,有官方例程,我只是做了个搬运而已,Spg30网上也有驱动示例,所以我只是拿别人的代码过来水一贴

IIC驱动接口

/**
  ******************************************************************************
  * @file    bsp_i2c.c
  * @author  
  * @version V1.1
  * @date    Mar 5, 2021
  * @brief   
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "bsp_i2c.h"

/* Private Typedef -----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/

#define I2Cx_TIMEOUT_MAX      3000
#define I2Cx_MAXTRIALSIFERROR 50
/* Private Enum --------------------------------------------------------------*/
/* Private Struct ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern  variables ---------------------------------------------------------*/
/* Private Functions Prototypes-----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Extern  Functions ---------------------------------------------------------*/

/**
  * @brief  向指定的地址写入一个字节的值
  * @param  Addr: I2C地址
  * @param  Reg: 写地址
  * @param  Value: 要写的数据
  * @retval 执行状态码
  */
HAL_StatusTypeDef I2Cx_WriteData( I2C_HandleTypeDef *hi2c, uint16_t Addr, uint8_t Reg, uint8_t Value )
{
    return ( HAL_I2C_Mem_Write( hi2c, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, I2Cx_TIMEOUT_MAX ) );
}

/**
  * @brief  向指定的寄存器地址写入多个数据
  * @param  Addr: I2C地址I2C地址
  * @param  Reg: 写地址
  * @param  RegSize: 写地址大小 (8BIT or 16BIT)
  * @param  pBuffer: 要写的数据
  * @param  Length: 数据长度
  * @retval 执行状态码
  */
HAL_StatusTypeDef I2Cx_WriteBuffer( I2C_HandleTypeDef *hi2c, uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length )
{
    return ( HAL_I2C_Mem_Write( hi2c, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2Cx_TIMEOUT_MAX ) );
}

/**
  * @brief  从指定的地址读出一个字节的内容
  * @param  Addr: I2C地址
  * @param  Reg: 读地址
  * @retval 成功返回读出的数据,错误返回HAL_ERROR
  */
uint8_t I2Cx_ReadData( I2C_HandleTypeDef *hi2c, uint16_t Addr, uint8_t Reg )
{
    uint8_t value = 0;

    /* Check the communication status */
    if ( HAL_OK != HAL_I2C_Mem_Read( hi2c, Addr, Reg, I2C_MEMADD_SIZE_8BIT, &value, 1, I2Cx_TIMEOUT_MAX ) )
        return HAL_ERROR;
    return value;
}

/**
  * @brief  从指定的寄存器地址读出多个数据
  * @param  Addr: I2C地址I2C地址
  * @param  Reg: 读地址
  * @param  RegSize: 读地址大小 (8BIT or 16BIT)
  * @param  pBuffer: 存储读出数据的缓冲区
  * @param  Length: 数据长度
  * @retval 执行状态码
  */
HAL_StatusTypeDef I2Cx_ReadBuffer( I2C_HandleTypeDef *hi2c, uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length )
{
    return ( HAL_I2C_Mem_Read( hi2c, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2Cx_TIMEOUT_MAX ) );
}

/**
  * @brief  检查指定地址的I2C设备通讯是否正常
  * @note   只用于Rom设备
  * @param  DevAddress: 设备地址
  * @param  Trials: 测试值
  * @retval 状态
  */
HAL_StatusTypeDef I2Cx_IsDeviceReady( I2C_HandleTypeDef *hi2c, uint16_t DevAddress )
{
    return ( HAL_I2C_IsDeviceReady( hi2c, DevAddress, I2Cx_MAXTRIALSIFERROR, I2Cx_TIMEOUT_MAX ) );
}

/********************************* END OF FILE *********************************/

Stlm75

/**
  ******************************************************************************
  * @file    module_stlm75.c
  * @author  
  * @version V1.1
  * @date    Mar 5, 2021
  * @brief   
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "module_stlm75.h"
#include "bsp_i2c.h"
#include "tool.h"

/* Private Typedef -----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/

/* 设备地址 */
#define STLM75_I2C_ADDRESS 0x90

/*
 * STLM75 命令寄存器
 */
/* Read Access Only */
#define STLM75_REG_TEMP 0x00  /* Temperature Register of LM75 */
/* Read/Write Access */
#define STLM75_REG_CONF 0x01  /* Configuration Register of LM75 */
#define STLM75_REG_THYS 0x02  /* Temperature Register of LM75 */
#define STLM75_REG_TOS  0x03  /* Over-temp Shutdown threshold Register of LM75 */

/*
 * STLM75 模式选择
 */
#define STLM75_CONTINUOUS_MODE                  ((uint8_t)0x00)
#define STLM75_ONE_SHOT_MODE                    ((uint8_t)0x01)
#define STLM75_COMPARATOR_MODE                  ((uint8_t)0x00)
#define STLM75_INTERRUPT_MODE                   ((uint8_t)0x02)

/*
 * Alert outside range Limit Temperature 12° <-> 40°c
 */
#define STLM75_TEMPERATURELIMITHIGH 40
#define STLM75_TEMPERATURELIMITlow  12

/* Private Enum --------------------------------------------------------------*/
/* Private Struct ------------------------------------------------------------*/

/* Stlm75温度传感器配置结构体 */
typedef struct
{
  uint8_t AlertMode;            /* Alert Mode Temperature out of range*/
  uint8_t ConversionMode;       /* Continuous/One Shot Mode */
  uint8_t ConversionResolution; /* Temperature Resolution */
  uint8_t ConversionRate;       /* Number of measure per second */
  uint8_t TemperatureLimitHigh; /* High Temperature Limit Range */
  uint8_t TemperatureLimitLow;  /* Low Temperature Limit Range */
}STLM75_InitTypeDef;

/* Private variables ---------------------------------------------------------*/
/* Extern  variables ---------------------------------------------------------*/
/* Private Functions Prototypes-----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Writes one byte to the TSENSOR.
  * @param  DevAddress: Target device address
  * @param  pBuffer: Pointer to data buffer
  * @param  WriteAddr: TSENSOR's internal address to write to.
  * @param  Length: Number of data to write
  */
static uint8_t STLM75_Write( uint8_t* pBuffer, uint8_t WriteAddr, uint16_t Length )
{
    return ( I2Cx_WriteBuffer( &hi2c1, STLM75_I2C_ADDRESS, WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length ) );
}

/**
  * @brief  Reads one byte from the TSENSOR.
  * @param  DevAddress: Target device address
  * @param  pBuffer : pointer to the buffer that receives the data read from the TSENSOR.
  * @param  ReadAddr : TSENSOR's internal address to read from.
  * @param  Length: Number of data to read
  */
static uint8_t STLM75_Read( uint8_t* pBuffer, uint8_t ReadAddr, uint16_t Length )
{
    return ( I2Cx_ReadBuffer( &hi2c1, STLM75_I2C_ADDRESS, ReadAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length ) );
}

/**
  * @brief  检查指定地址的I2C设备通讯是否正常
  * @note   只用于Rom设备
  * @param  DevAddress: 设备地址
  * @param  Trials: 测试值
  * @retval 状态
  */
static uint8_t STLM75_IsDeviceReady( void )
{
    return ( I2Cx_IsDeviceReady( &hi2c1, STLM75_I2C_ADDRESS ) );
}

/* Extern  Functions ---------------------------------------------------------*/

/**
  * @brief  STLM75温度传感器初始化
  * @param  void
  * @note   void
  * @retval 初始化状态
  */
uint8_t STLM75_Init( void )
{
    uint8_t confreg = 0;
    uint16_t tempreg = 0;

    /* 检查设备是否正常 */
    if ( STLM75_IsDeviceReady() != HAL_OK ) {
        Db_Error("Stlm75 device is error!!!");
        return HAL_ERROR;
    }

    do {
        /* Set the Configuration Register */
        confreg = (uint8_t)( STLM75_COMPARATOR_MODE | STLM75_CONTINUOUS_MODE );
        if ( STLM75_Write( &confreg, STLM75_REG_CONF, 1 ) != HAL_OK )
            break;

        /* Set the Temperature Registers */
        /* Keep the sign bit and shift the temperature value (as given value is integer, the 0.5 digit is not set) */
        tempreg = ( ( ( STLM75_TEMPERATURELIMITHIGH & 0x007F) << 8) | ( STLM75_TEMPERATURELIMITHIGH & 0x8000 ) );
        if ( STLM75_Write( (uint8_t*)(&tempreg), STLM75_REG_TOS, 2 ) != HAL_OK )
            break;

        tempreg = ( ( ( STLM75_TEMPERATURELIMITlow & 0x007F) << 8) | ( STLM75_TEMPERATURELIMITlow & 0x8000) );
        if ( STLM75_Write( (uint8_t*)(&tempreg), STLM75_REG_THYS, 2 ) != HAL_OK )
            break;

        return HAL_OK;
    } while ( 0 );

    return HAL_ERROR;
}

/**
  * @brief  Read The Temperature Sensor Status
  * @param  void
  * @retval Status
  */
uint8_t STLM75_ReadStatus( void )
{
  uint8_t tmp = 0;

  /* Read Status register */
  STLM75_Read( &tmp, STLM75_REG_CONF, 1 );

  /* Return Temperature Sensor Status */
  return (uint8_t)(tmp);
}

/**
  * @brief  Read ID address of STLM75
  * @param  void
  * @retval ID name
  */
uint16_t STLM75_ReadTemp( void )
{
  uint16_t tempreg = 0;
  uint16_t tmp = 0;

  /* Read Temperature registers */
  STLM75_Read( (uint8_t*)(&tempreg), STLM75_REG_TEMP, 2 );

  tmp = ((tempreg & 0x00FF) << 8) | ((tempreg & 0xFF00) >> 8);
  tempreg = (((tmp & 0x7F80) >> 7) | (tmp & 0x8000));

  /* Return Temperature value */
  return ( tempreg / 2 );
}

/********************************* END OF FILE *********************************/

hts221

/**
  ******************************************************************************
  * @file    module_stlm75.c
  * @author  
  * @version V1.1
  * @date    Mar 5, 2021
  * @brief   
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "module_stlm75.h"
#include "bsp_i2c.h"
#include "tool.h"

/* Private Typedef -----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/

/* 设备地址 */
#define STLM75_I2C_ADDRESS 0x90

/*
 * STLM75 命令寄存器
 */
/* Read Access Only */
#define STLM75_REG_TEMP 0x00  /* Temperature Register of LM75 */
/* Read/Write Access */
#define STLM75_REG_CONF 0x01  /* Configuration Register of LM75 */
#define STLM75_REG_THYS 0x02  /* Temperature Register of LM75 */
#define STLM75_REG_TOS  0x03  /* Over-temp Shutdown threshold Register of LM75 */

/*
 * STLM75 模式选择
 */
#define STLM75_CONTINUOUS_MODE                  ((uint8_t)0x00)
#define STLM75_ONE_SHOT_MODE                    ((uint8_t)0x01)
#define STLM75_COMPARATOR_MODE                  ((uint8_t)0x00)
#define STLM75_INTERRUPT_MODE                   ((uint8_t)0x02)

/*
 * Alert outside range Limit Temperature 12° <-> 40°c
 */
#define STLM75_TEMPERATURELIMITHIGH 40
#define STLM75_TEMPERATURELIMITlow  12

/* Private Enum --------------------------------------------------------------*/
/* Private Struct ------------------------------------------------------------*/

/* Stlm75温度传感器配置结构体 */
typedef struct
{
  uint8_t AlertMode;            /* Alert Mode Temperature out of range*/
  uint8_t ConversionMode;       /* Continuous/One Shot Mode */
  uint8_t ConversionResolution; /* Temperature Resolution */
  uint8_t ConversionRate;       /* Number of measure per second */
  uint8_t TemperatureLimitHigh; /* High Temperature Limit Range */
  uint8_t TemperatureLimitLow;  /* Low Temperature Limit Range */
}STLM75_InitTypeDef;

/* Private variables ---------------------------------------------------------*/
/* Extern  variables ---------------------------------------------------------*/
/* Private Functions Prototypes-----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Writes one byte to the TSENSOR.
  * @param  DevAddress: Target device address
  * @param  pBuffer: Pointer to data buffer
  * @param  WriteAddr: TSENSOR's internal address to write to.
  * @param  Length: Number of data to write
  */
static uint8_t STLM75_Write( uint8_t* pBuffer, uint8_t WriteAddr, uint16_t Length )
{
    return ( I2Cx_WriteBuffer( &hi2c1, STLM75_I2C_ADDRESS, WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length ) );
}

/**
  * @brief  Reads one byte from the TSENSOR.
  * @param  DevAddress: Target device address
  * @param  pBuffer : pointer to the buffer that receives the data read from the TSENSOR.
  * @param  ReadAddr : TSENSOR's internal address to read from.
  * @param  Length: Number of data to read
  */
static uint8_t STLM75_Read( uint8_t* pBuffer, uint8_t ReadAddr, uint16_t Length )
{
    return ( I2Cx_ReadBuffer( &hi2c1, STLM75_I2C_ADDRESS, ReadAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length ) );
}

/**
  * @brief  检查指定地址的I2C设备通讯是否正常
  * @note   只用于Rom设备
  * @param  DevAddress: 设备地址
  * @param  Trials: 测试值
  * @retval 状态
  */
static uint8_t STLM75_IsDeviceReady( void )
{
    return ( I2Cx_IsDeviceReady( &hi2c1, STLM75_I2C_ADDRESS ) );
}

/* Extern  Functions ---------------------------------------------------------*/

/**
  * @brief  STLM75温度传感器初始化
  * @param  void
  * @note   void
  * @retval 初始化状态
  */
uint8_t STLM75_Init( void )
{
    uint8_t confreg = 0;
    uint16_t tempreg = 0;

    /* 检查设备是否正常 */
    if ( STLM75_IsDeviceReady() != HAL_OK ) {
        Db_Error("Stlm75 device is error!!!");
        return HAL_ERROR;
    }

    do {
        /* Set the Configuration Register */
        confreg = (uint8_t)( STLM75_COMPARATOR_MODE | STLM75_CONTINUOUS_MODE );
        if ( STLM75_Write( &confreg, STLM75_REG_CONF, 1 ) != HAL_OK )
            break;

        /* Set the Temperature Registers */
        /* Keep the sign bit and shift the temperature value (as given value is integer, the 0.5 digit is not set) */
        tempreg = ( ( ( STLM75_TEMPERATURELIMITHIGH & 0x007F) << 8) | ( STLM75_TEMPERATURELIMITHIGH & 0x8000 ) );
        if ( STLM75_Write( (uint8_t*)(&tempreg), STLM75_REG_TOS, 2 ) != HAL_OK )
            break;

        tempreg = ( ( ( STLM75_TEMPERATURELIMITlow & 0x007F) << 8) | ( STLM75_TEMPERATURELIMITlow & 0x8000) );
        if ( STLM75_Write( (uint8_t*)(&tempreg), STLM75_REG_THYS, 2 ) != HAL_OK )
            break;

        return HAL_OK;
    } while ( 0 );

    return HAL_ERROR;
}

/**
  * @brief  Read The Temperature Sensor Status
  * @param  void
  * @retval Status
  */
uint8_t STLM75_ReadStatus( void )
{
  uint8_t tmp = 0;

  /* Read Status register */
  STLM75_Read( &tmp, STLM75_REG_CONF, 1 );

  /* Return Temperature Sensor Status */
  return (uint8_t)(tmp);
}

/**
  * @brief  Read ID address of STLM75
  * @param  void
  * @retval ID name
  */
uint16_t STLM75_ReadTemp( void )
{
  uint16_t tempreg = 0;
  uint16_t tmp = 0;

  /* Read Temperature registers */
  STLM75_Read( (uint8_t*)(&tempreg), STLM75_REG_TEMP, 2 );

  tmp = ((tempreg & 0x00FF) << 8) | ((tempreg & 0xFF00) >> 8);
  tempreg = (((tmp & 0x7F80) >> 7) | (tmp & 0x8000));

  /* Return Temperature value */
  return ( tempreg / 2 );
}

/********************************* END OF FILE *********************************/

Spg30

/**
  ******************************************************************************
  * @file    module_sgp30.c
  * @author  HuZhang
  * @version V1.1
  * @date    Mar 5, 2021
  * @brief   
  ******************************************************************************
  * @attention
  *
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "module_sgp30.h"
#include "i2c.h"
#include "tool.h"

/* Private Typedef -----------------------------------------------------------*/
/* Private Define ------------------------------------------------------------*/

/* CRC8校验参数 */
#define CRC8_POLYNOMIAL      0x31
#define CRC8_INITIAALIZATION 0xFF

/* I2C地址 */
#define SGP30_ADDR       0x58
#define SGP30_ADDR_WRITE ( SGP30_ADDR << 1 )
#define SGP30_ADDR_READ  ( ( SGP30_ADDR << 1 ) + 1 )

/* Private Enum --------------------------------------------------------------*/

typedef enum  {
    /* 初始化空气质量测量 */
    INIT_AIR_QUALITY    = 0x2003,
    /* 开始空气质量测量 */
    MEASURE_AIR_QUALITY = 0x2008
}sgp30_cmd;

/* Private Struct ------------------------------------------------------------*/

struct sgp30_data_t {
    uint16_t co2;
    uint16_t tvoc;
}sgp30Data;

/* Private variables ---------------------------------------------------------*/
/* Extern  variables ---------------------------------------------------------*/
/* Private Functions Prototypes-----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  CRC-8校验
  * @param  message:要校验的数据
  * @param  initial_value:要校验的数据
  * @note   void
  * @retval void
  */
uint8_t CheckCrc8( const uint8_t* message )
{
    uint8_t  remainder;     /* 余数 */
    uint8_t  i = 0, j = 0;  /* 循环变量 */

    /* 初始化 */
    remainder = CRC8_INITIAALIZATION;

    for ( j = 0; j < 2; j++ ) {
        remainder ^= message[ j ];

        /* 从最高位开始依次计算  */
        for ( i = 0; i < 8; i++ ) {
            if ( remainder & 0x80 ) {
                remainder = ( remainder << 1 ) ^ CRC8_POLYNOMIAL;
            }
            else {
                remainder = ( remainder << 1 );
            }
        }
    }

    /* 返回计算的CRC码 */
    return remainder;
}

/**
 * @brief   软复位SGP30
 * @param   void
 * @retval  成功返回HAL_OK
*/
static uint8_t sgp30SoftReset( void )
{
    uint8_t cmd = 0x06;
    return HAL_I2C_Master_Transmit( &hi2c1, SGP30_ADDR_WRITE, &cmd, 1, 0xFFFF );
}

/**
  * @brief  spg指令发送
  * @param  cmd:指令
  * @note   void
  * @retval 发送结果
  */
static uint8_t spg30CmdSend ( sgp30_cmd cmd )
{
    uint8_t cmdBuffer[2];

    cmdBuffer[ 0 ] = cmd >> 8;
    cmdBuffer[ 1 ] = cmd;

    return HAL_I2C_Master_Transmit( &hi2c1, SGP30_ADDR_WRITE, cmdBuffer, 2, 0xFFFF );
}

/* Extern  Functions ---------------------------------------------------------*/

/**
  * @brief  初始化空气传感器-spg30
  * @param  void
  * @note   void
  * @retval void
  */
uint8_t sgp30Init ( void )
{
    /* 复位 */
    if ( HAL_OK != sgp30SoftReset() )
        return HAL_ERROR;

    HAL_Delay( 100 );

    return spg30CmdSend( INIT_AIR_QUALITY );
}

/**
  * @brief  sgp30获取空气质量参数
  * @param  sgp30Data:二氧化碳浓度 甲醛浓度
  * @note   void
  * @retval void
  */
uint8_t spg30GetArgument ( uint16_t *sgp30Data )
{
    uint8_t status;
    uint8_t recv_buffer[6] = { 0 };

    /* 启动测量 */
    status = spg30CmdSend( MEASURE_AIR_QUALITY );
    if ( status != HAL_OK ) {
        Db_Error("sgp30 start fail\r\n");
        return HAL_ERROR;
    }

    HAL_Delay(100);

    /* 读取测量数据 */
    status = HAL_I2C_Master_Receive( &hi2c1, SGP30_ADDR_READ, (uint8_t*)recv_buffer, 6, 0xFFFF );
    if ( status != HAL_OK ) {
        Db_Error("I2C Master Receive fail\r\n");
        return HAL_ERROR;
    }

    /* 校验接收的测量数据 */
    if ( CheckCrc8( &recv_buffer[ 0 ] ) != recv_buffer[ 2 ]) {
        Db_Error("co2 recv data crc check fail\r\n");
        return HAL_ERROR;
    }
    if ( CheckCrc8( &recv_buffer[ 3 ] ) != recv_buffer[ 5 ]) {
        Db_Error("tvoc recv data crc check fail\r\n");
        return HAL_ERROR;
    }


    /* 转换测量数据 */
    sgp30Data[ 0 ]  = recv_buffer[ 0 ] << 8 | recv_buffer[ 1 ];
    sgp30Data[ 1 ] = recv_buffer[ 3 ] << 8 | recv_buffer[ 4 ];

    return HAL_OK;
}

/********************************* END OF FILE *********************************/

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值