ESP32-S2 SGM58031-热敏电阻电压转温度

一、SGM58031

        SGM58031是精密模数转换器(ADC)的16位分辨率,其设计精度高,功耗低,易于实现,具有片上基准和振荡器,采用IIC通信,3.3-5V供电。

图1.0 芯片封装

 图1.1 芯片引脚

图1.2 芯片地址

  图1.3 芯片寄存器地址

        电压转换公式(取决于PGA配置):

         ADC值  >  0X8000  :采样点电压值 = (0xFFFF  -  ADC值)  / 32768.0 * 增益对应的电压值 

         ADC值  <  0X8000  :采样点电压值 =  ADC值  / 32768.0 * 增益对应的电压值 

二、热敏电阻分压转实际温度

       本次实验采用的热敏电阻是NCU15WF104D60RC,它是一个负温度系数(NTC)热敏电阻,阻值为100K。原理就是在热敏电阻的基础上再串联一个电阻,形成一个串联分压电路,随着的温度变化热敏电阻的阻值也随之变化,然后经过ADC采样,最终把电压换算成温度。

   图2.4 NCU15WF104D60RC热敏电阻参数

 图2.5 硬件分压电路

        NTC热敏电阻温度计算公式:Rt = R * exp(B * (1 / T1 - 1 / T2))

        Rt:随着温度变化的阻值
        R:25℃时的阻值,100k
        B常数:4250
        T1:开尔文温度等于273.15 + 热敏电阻当前阻值对应的摄氏度
        T2:273.15+25(K度)

        根据图2.5得出

        R1:100000.0
        R2:200000.0
        B常数:4250.0
        VCC:3.3
        T2:(273.15 + 25)(K度)

        温度转换公式:温度值 = ((1 / (log( ((R2 * VCC) / HUB_TMP1点的电压值 - R2) / R1) / B + (1 / T2))) - 273.15 + 0.5)

三、程序

SGM58031源文件:

#include "sgm58031.h"
#include "bsp_iic.h"
#include "esp_log.h"

static const char *TAG = "SMG85031";

/**
* @brief  往SGM发送两个字节函数
* @param  
*	@arg   dev_addr:   器件地址
*   @arg reg_addr      寄存器地址
*   @arg send_data     发送的数据
* @retval 
*   @arg ESP_OK:发送成功 ESP_FAIL:发送失败
**/
esp_err_t SGM_SendBytes(uint8_t dev_addr,uint8_t reg_addr,uint16_t send_data)
{
	uint8_t write_data[2] = {0};

	write_data[0] = (send_data >> 8) & 0x00ff;
	write_data[1] = send_data & 0x00ff;

#if I2C_HARDWARE
	return I2C_Master_WriteBytes(dev_addr,reg_addr,write_data,sizeof(write_data),200);
#else
	EspI2cWriteBytes(dev_addr,reg_addr,write_data,sizeof(write_data));  
	return ESP_OK;
#endif
}

/**
* @brief  读取SGM两个字节函数
* @param  
*	@arg   dev_addr:   器件地址
*   @arg  reg_addr:    寄存器地址
*   @arg  *read_data:  读取的数据
* @retval 
*   @arg ESP_OK:读取成功 ESP_FAIL:读取失败
**/
esp_err_t SGM_ReadBytes(uint8_t dev_addr,uint8_t reg_addr,uint16_t *read_data)
{
	uint8_t reg_data[2] = {0};
	esp_err_t ret = ESP_OK;

#if I2C_HARDWARE
	ret = I2C_Master_ReadBytes(dev_addr,reg_addr,reg_data,sizeof(reg_data),200);
#else
	EspI2cReadBytes(dev_addr,reg_addr,reg_data,sizeof(reg_data));  
#endif
    *read_data = (uint16_t)((reg_data[0] << 8) | reg_data[1]);
	return ret;		
}

/**
* @brief  SGM配置函数
* @param  
*	@arg  mux  配置连接的引脚
* @retval 无
**/
void SGM_Config(uint32_t mux)
{
	// uint16_t reg_value = 0x0;

	const smg58031_register_config_t smg58031_config = {
		.reg.COMP_QUE = DISABLE_COMPARATOR,					//禁用比较器并将ALERT / RDY引脚设置为高阻态
		.reg.COMP_LAT = NONLATCHING_COMPARATOR,				//非锁存比较器
		.reg.COMP_POL = ACTIVE_LOW,							//Aler引脚,低电平有效
		.reg.COMP_MODE = TRADITIONAL_COMPARATOR,			//传统比较器
		.reg.DR = RATE_100,									//100 SPS
		.reg.MODE = POWER_DOWN_SINGLE_SHOT_MODE,			//连续转换模式
		.reg.PGA = GAIN_1_4096V,							//增益为1,引脚最大输入电压为±4.096 + 0.3V
		.reg.MUX = mux,										//MUX选通的连接到PGA的引脚为AIN0_GND
		.reg.OS = BEGIN_A_SINGLE_CONVERSION,				//开启一次转换
	};

	// ESP_LOGI(TAG,"CONVERSION_REG WRITE:%#x\n",smg58031_config.value);
	SGM_SendBytes(SGM58031_ADDR,CONFIG_REG,smg58031_config.value);

	// SGM_ReadBytes(SGM58031_ADDR,CONFIG_REG,&reg_value);
	// ESP_LOGI(TAG,"CONVERSION_REG READ:%#x\n",reg_value);
}

/**
* @brief  获取SGM数据函数
* @param  无
* @retval 
*   @arg  获取的数据
**/
void  Get_SGM_Data(float *hub_temp)
{
	float voltage = 0;
	uint16_t adc_value = 0;
	static uint32_t ain_num = AIN0_GND;

	if(SGM_ReadBytes(SGM58031_ADDR,CONVERSION_REG,&adc_value) == ESP_OK)
	{
		voltage = adc_value / 32768.0 * 4.096;
		if(voltage > 0)
		{
			*hub_temp = GET_NTC_TEMPRATURE(voltage);
		}
		ESP_LOGI(TAG,"voltage:%.2f  HUB_TEMP:%.2f \n",voltage,*hub_temp);
	}

	SGM_Config(ain_num);

	ain_num++;
	if(ain_num > AIN3_GND)
	{
		ain_num = AIN0_GND;
	}
}

SGM58031头文件:

#ifndef _SGM58031_H_
#define _SGM58031_H_

#include <stdio.h>
#include "esp_err.h"
#include "math.h"

//NTC热敏电阻温度计算公式:Rt = R * exp(B * (1 / T1 - 1 / T2))

#define R1								100000.0				//100k热敏电阻
#define R2 								200000.0				//200K固定串联分压电阻
#define T2 								(273.15 + 25.0)			//K度
#define B								4250.0					//B常数			
#define VCC								3.3						//串联电阻总电压

//U2 = R2*VCC/(R1+R2)
//R1 = (R2 * VCC) / U2 - R2
//Rt = (R2 * VCC) / voltage - R2;								//热敏电阻当前阻值
#define GET_NTC_TEMPRATURE(u2_voltage) 	((1 / (log( ((R2 * VCC) / u2_voltage - R2) / R1) / B + (1 / T2))) - 273.15 + 0.5)

//SGM58031设备地址
#define SGM58031_ADDR                   0x4B

//SGM58031内部寄存器地址
#define CONVERSION_REG                  0x00   //AD值转换寄存器,16bit数据,默认值0x0000,只读
#define CONFIG_REG                      0x01   //配置寄存器,默认0x8583,可读可写
#define LO_THRESH_REG                   0x02   //比较器阈值下限,默认0x8000
#define HI_THRESH_REG                   0x03   //比较器阈值上限,默认0x7FFF
#define CONFIG1_REG                     0x04   //扩展配置寄存器,默认0x0000
#define CHIP_ID_REG                     0x05   //芯片ID,默认0x0080
#define GN_TRIM1_REG                    0x06   //增益修正,默认0x03FA				

typedef union 
{
	uint16_t  value;
	struct{
        uint8_t COMP_QUE:2;
		uint8_t COMP_LAT:1;
		uint8_t COMP_POL:1;
		uint8_t COMP_MODE:1;
		uint8_t DR:3;
		uint8_t MODE:1;
		uint8_t PGA:3;
		uint8_t MUX:3;
		uint8_t OS:1;
	}reg;
}smg58031_register_config_t;
 

//运行状态或单次转换位
//运行状态或单次转换启动此位确定设备的运行状态。 OS只能在掉电状态下写入,并且在转换正在进行时无效。
enum OS
{
	NO_EFFECT = 0,			    //无效
	BEGIN_A_SINGLE_CONVERSION	//开启一次转换
};
 
//输入多路复用器配置
//这些位配置输入多路复用器
enum MUX
{
	AIN0_AIN1 = 0,	//MUX选通的连接到PGA的引脚为AIN0和AIN1
	AIN0_AIN3,
	AIN1_AIN3,
	AIN2_AIN3,
	AIN0_GND,
	AIN1_GND,
	AIN2_GND,
	AIN3_GND
};
 
//可编程增益放大器配置
//这些位设置可编程增益放大器的FSR
//此参数表示ADC缩放的满量程范围。 请勿对器件的模拟输入施加超过VDD + 0.3 V的电压
enum PGA
{
	GAIN_2_3_6144V = 0,	//增益为2/3,引脚最大输入电压为±6.144 + 0.3V  
	GAIN_1_4096V,		//增益为1,引脚最大输入电压为±4.096 + 0.3V
	GAIN_2_2048V,		//增益为2,引脚最大输入电压为±2.048 + 0.3V
	GAIN_4_1024V,		//增益为4,引脚最大输入电压为±1.024 + 0.3V
	GAIN_8_0512V,		//增益为8,引脚最大输入电压为±0.512 + 0.3V
	GAIN_16_0256V,		//增益为16,引脚最大输入电压为±0.256 + 0.3V
	GAIN_16_0256V1,		//增益为16,引脚最大输入电压为±0.256 + 0.3V
	GAIN_16_0256V2		//增益为16,引脚最大输入电压为±0.256 + 0.3V
};
 
//设备运行模式
//该位控制操作模式。
enum MODE
{
    CONTINUOUS_CONVERSION_MODE = 0, //连续转换模式
	POWER_DOWN_SINGLE_SHOT_MODE		//掉电单次模式
};
 
//数据速率
//这些位控制数据速率设置。
enum DR
{
	RATE_6 = 0,			//6.25 SPS
	RATE_12,			//12.5 SPS
	RATE_25,			//25.5 SPS
	RATE_50,			//50   SPS
	RATE_100,			//100  SPS
	RATE_200,			//200  SPS
	RATE_400,			//400  SPS
	RATE_800			//800  SPS
};
 
//比较器模式
//该位配置比较器工作模式di
enum COMP_MODE
{
	TRADITIONAL_COMPARATOR = 0,	//传统比较器
	WINDOW_COMPARATOR			//窗口比较器
};
 
//比较器极性
//该位控制ALERT / RDY引脚的极性
enum COMP_POL
{
	ACTIVE_LOW = 0,		//低电平有效
	ACTIVE_HIGH			//高电平有效
};
 
//比较器锁存
//该位控制ALERT / RDY引脚在置位后是锁存还是在转换后的阈值上限和下限范围内清零
enum COMP_LAT
{
	NONLATCHING_COMPARATOR = 0,		//非锁存比较器
	LATCHING_COMPARATOR			    //锁存比较器
};
 
//比较器队列和失能
//这些位执行两个功能。 设置为11时,比较器禁用,ALERT / RDY引脚设置为高阻态。 当设置为任何其他值时,ALERT / RDY引脚和比较器功能被使能,并且设置值确定在断言ALERT / RDY引脚之前超过所需的上限或下限的连续转换次数
enum COMP_QUE
{
	ASSERT_AFTER_ONE_CONVERSION = 0,	   //一次转换后断言
	ASSERT_AFTER_TOW_CONVERSION,		   //两次转换后断言
	ASSERT_AFTER_FOUR_CONVERSION,		   //四次转换后断言
	DISABLE_COMPARATOR		               //禁用比较器并将ALERT / RDY引脚设置为高阻态
};

void  SGM_Config(uint32_t mux);
void  Get_SGM_Data(float *hub_temp);
#endif

四、验证

        硬件需要采集四路电压,软件循环切换通道,实验数据如下:

 图4.6 实验数据

        工程源码:链接:https://pan.baidu.com/s/1KzVAYrx_iMhH5-dPn_yxsw?pwd=46yz 提取码:46yzhttps://pan.baidu.com/s/1KzVAYrx_iMhH5-dPn_yxsw?pwd=46yz

  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值