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
#include "module_stlm75.h"
#include "bsp_i2c.h"
#include "tool.h"
#define STLM75_I2C_ADDRESS 0x90
#define STLM75_REG_TEMP 0x00
#define STLM75_REG_CONF 0x01
#define STLM75_REG_THYS 0x02
#define STLM75_REG_TOS 0x03
#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)
#define STLM75_TEMPERATURELIMITHIGH 40
#define STLM75_TEMPERATURELIMITlow 12
typedef struct
{
uint8_t AlertMode;
uint8_t ConversionMode;
uint8_t ConversionResolution;
uint8_t ConversionRate;
uint8_t TemperatureLimitHigh;
uint8_t TemperatureLimitLow;
}STLM75_InitTypeDef;
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 ) );
}
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 ) );
}
static uint8_t STLM75_IsDeviceReady( void )
{
return ( I2Cx_IsDeviceReady( &hi2c1, STLM75_I2C_ADDRESS ) );
}
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 {
confreg = (uint8_t)( STLM75_COMPARATOR_MODE | STLM75_CONTINUOUS_MODE );
if ( STLM75_Write( &confreg, STLM75_REG_CONF, 1 ) != HAL_OK )
break;
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;
}
uint8_t STLM75_ReadStatus( void )
{
uint8_t tmp = 0;
STLM75_Read( &tmp, STLM75_REG_CONF, 1 );
return (uint8_t)(tmp);
}
uint16_t STLM75_ReadTemp( void )
{
uint16_t tempreg = 0;
uint16_t tmp = 0;
STLM75_Read( (uint8_t*)(&tempreg), STLM75_REG_TEMP, 2 );
tmp = ((tempreg & 0x00FF) << 8) | ((tempreg & 0xFF00) >> 8);
tempreg = (((tmp & 0x7F80) >> 7) | (tmp & 0x8000));
return ( tempreg / 2 );
}
hts221
#include "module_stlm75.h"
#include "bsp_i2c.h"
#include "tool.h"
#define STLM75_I2C_ADDRESS 0x90
#define STLM75_REG_TEMP 0x00
#define STLM75_REG_CONF 0x01
#define STLM75_REG_THYS 0x02
#define STLM75_REG_TOS 0x03
#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)
#define STLM75_TEMPERATURELIMITHIGH 40
#define STLM75_TEMPERATURELIMITlow 12
typedef struct
{
uint8_t AlertMode;
uint8_t ConversionMode;
uint8_t ConversionResolution;
uint8_t ConversionRate;
uint8_t TemperatureLimitHigh;
uint8_t TemperatureLimitLow;
}STLM75_InitTypeDef;
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 ) );
}
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 ) );
}
static uint8_t STLM75_IsDeviceReady( void )
{
return ( I2Cx_IsDeviceReady( &hi2c1, STLM75_I2C_ADDRESS ) );
}
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 {
confreg = (uint8_t)( STLM75_COMPARATOR_MODE | STLM75_CONTINUOUS_MODE );
if ( STLM75_Write( &confreg, STLM75_REG_CONF, 1 ) != HAL_OK )
break;
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;
}
uint8_t STLM75_ReadStatus( void )
{
uint8_t tmp = 0;
STLM75_Read( &tmp, STLM75_REG_CONF, 1 );
return (uint8_t)(tmp);
}
uint16_t STLM75_ReadTemp( void )
{
uint16_t tempreg = 0;
uint16_t tmp = 0;
STLM75_Read( (uint8_t*)(&tempreg), STLM75_REG_TEMP, 2 );
tmp = ((tempreg & 0x00FF) << 8) | ((tempreg & 0xFF00) >> 8);
tempreg = (((tmp & 0x7F80) >> 7) | (tmp & 0x8000));
return ( tempreg / 2 );
}
Spg30
#include "module_sgp30.h"
#include "i2c.h"
#include "tool.h"
#define CRC8_POLYNOMIAL 0x31
#define CRC8_INITIAALIZATION 0xFF
#define SGP30_ADDR 0x58
#define SGP30_ADDR_WRITE ( SGP30_ADDR << 1 )
#define SGP30_ADDR_READ ( ( SGP30_ADDR << 1 ) + 1 )
typedef enum {
INIT_AIR_QUALITY = 0x2003,
MEASURE_AIR_QUALITY = 0x2008
}sgp30_cmd;
struct sgp30_data_t {
uint16_t co2;
uint16_t tvoc;
}sgp30Data;
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 );
}
}
}
return remainder;
}
static uint8_t sgp30SoftReset( void )
{
uint8_t cmd = 0x06;
return HAL_I2C_Master_Transmit( &hi2c1, SGP30_ADDR_WRITE, &cmd, 1, 0xFFFF );
}
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 );
}
uint8_t sgp30Init ( void )
{
if ( HAL_OK != sgp30SoftReset() )
return HAL_ERROR;
HAL_Delay( 100 );
return spg30CmdSend( INIT_AIR_QUALITY );
}
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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)