文章目录

  • 一、温度传感器的简介
  • 内置温度传感器特性
  • 温度的计算
  • 二、编程
  • 编程思路:
  • 代码:
  • 遇到的问题-数据类型问题


一、温度传感器的简介

内置温度传感器特性

esp32 接入SD_MMC_esp32 接入SD_MMC


■ STM32有一个内部的温度传感器,可以用来测量CPU测量周围的温度(TA)。

■ STM32内部温度传感器与ADC的通道16相连,与ADC配合使用实现温度测量

■ 温度传感器模拟输入推荐采样时间是17.1μs。

■ STM32的内部温度传感器测量范围–40~125℃,精度 ± 1.5℃。

温度的计算

官方数据手册公式如下:

esp32 接入SD_MMC_温度传感器_02


百度给出了V25和Avg_Slope的值:

最小

经典

最大

V25

1340mV

1430mV

1520mV

Avg_Slope(mV/°C)

4.0

4.3

4.3

  • VSENSE 如何得到?
    我们得到的AD结果是ADC_DR这个变量,存在以下关系:
    ADC_DR / VSENSE = 212 / 3300mV
    VSENSE
    = ADC_DR * 3300mV / 212
    = ADC_DR3300/4096
    = ADC_DR
    825/1024
    = (ADC_DR*825)>>10
  • 例:读到VSENSE = 1. 35V,分别取V25的典型值1340mV和Avg_Slope 的经典值4.3,计算当前温度。
      由公式 T = (VSENSE -V25 )/Avg_Slope + 25
        得 T = (1430 - 1350)/4.3 + 25 = 43.60
      所以温度大约为43.6°C

二、编程

编程思路:

①初始化ADC
②设置ADC CR2的TSVREFE位,打开内部温度传感器
 ADC_TempSensorVrefintCmd(ENABLE);
③设置采样时间等于17.1us,配置规则通道参数:选择ADC_ IN16输入通道。
 ADC_RegularChannelConfig( );
④启动软件转换
 ADC_SoftwareStartConvCmd();
⑤等待转换结束并读取ADC_DR结果
 (u32)ADC_GetConversionValue(ADC1);
⑥由ADC_DR结果计算出温度值

代码:

adc.h

#ifndef ADC_H
#define ADC_H
#include "stm32f10x.h"
#include "bsp_systick.h"

#define		V25					1370
#define		Avg_Slope		4.35
void T_ADC_Configuration(void);
u32 Get_ADC_Average(u8 channel,u8 times);
float Get_InternalSensorTemperate(void);
#endif

adc.c

#include "adc.h"

void T_ADC_Configuration(void)
{
	ADC_InitTypeDef ADC_InitStructure; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1	, ENABLE );	  //使能GPIOA,ADC1通道时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //分频因子6时钟为72M/6=12MHz

  ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE;	//使能扫描
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	//设置模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	ADC_ResetCalibration(ADC1);	//重置指定的ADC1的复位寄存器
  while(ADC_GetResetCalibrationStatus(ADC1));	//获取ADC1重置校准寄存器的状态,设置状态则等待
	ADC_StartCalibration(ADC1);	 
	while(ADC_GetCalibrationStatus(ADC1));		//获取指定ADC1的校准程序,设置状态则等待
	
	ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
}

/*******************************************************************
*函数:u8 Get_ADC_Average(u8 channel,u8 times) 
*功能:获取adc转换平均值
*输入:
	u8 channel, 通道号:ADC_Channel_0 ~ ADC_Channel_17
	u8 times,	获取次数
*输出:获取次数的平均值
*特殊说明:
*******************************************************************/
u32 Get_ADC_Average(u8 channel,u8 times)   
{	
	u32 convert_Result=0;
	u8 i;
	for(i=0;i<times;i++)
	{
		ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_55Cycles5 );	//ADC1,第一个转换,采样时间为28.5周期?  			    
		ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能
		while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
		convert_Result+=(u32)ADC_GetConversionValue(ADC1);//读取ADC_DR结果数据,此时EOC会自动清除
		SysTick_Delay_ms(5);
	}
	return convert_Result/times;
}

/*******************************************************************
*函数:u8 Get_InternalSensorTemperate(u8 channel,u8 times) 
*功能:获取adc转换平均值
*输入:
*输出:获取的温度值
*特殊说明:
*******************************************************************/
float Get_InternalSensorTemperate(void)	//获取内部温度传感器温度值
{
	int ADC_ConvertedValue;//用来存储ADC转换出来的值
 	float Current_Temp;
	
	ADC_ConvertedValue = (int)Get_ADC_Average(ADC_Channel_16,20);	//20次取平均
	ADC_ConvertedValue = (ADC_ConvertedValue*825)>>10;//换算成Vsensor
	Current_Temp = (((V25-ADC_ConvertedValue)/Avg_Slope)+25);	//计算温度值 	 
	return Current_Temp;
}

main.c

#include "stm32f10x.h"
#include "bsp_systick.h"
#include "usart.h"
#include "adc.h"

int main(void)
{
	usart1_Init(9600);
	printf("start!\n");
	
	T_ADC_Configuration();
	u32 adc_DRValue = 0 ;
	float temperature;
	
	while(1)
	{
		adc_DRValue = Get_ADC_Average(ADC_Channel_16,20);//指定ADC_Channel_1,获取ADC的值
		printf("adc_DRValue:%d\n",adc_DRValue);//通过串口打印获取ADC的值
		temperature=Get_InternalSensorTemperate();//转换ADC的值,得到具体的温度
		printf("temperature:%f\n",temperature);//通过串口打印获取电压的值
		SysTick_Delay_ms(1500);
	}
}

遇到的问题-数据类型问题

esp32 接入SD_MMC_esp32 接入SD_MMC_03


代码如下

float Get_Temperate(void)	//获取内部温度传感器温度值
{
	u32 ADC_ConvertedValue;//用来存储ADC转换出来的值,单位是mV
 	float Current_Temp;
	ADC_ConvertedValue = T_Get_ADC_Average(10);	//20次取平均
	ADC_ConvertedValue = (ADC_ConvertedValue*825)>>10;//(ADC_ConvertedValue*825)>>10 表示 ADC_ConvertedValue*3300/4096
	Current_Temp=(float)(((1370-ADC_ConvertedValue)/4.35)+25);	//转换为温度值 	 
	return Current_Temp;
}

思来想去,最后发现是数据类型的问题,因为ADC_ConvertedValue会得到负数。
ADC_ConvertedValue由u32改为int类型就得到正确结果。

float Get_Temperate(void)	//获取内部温度传感器温度值
{
	int ADC_ConvertedValue;//用来存储ADC转换出来的值,单位是mV
 	float Current_Temp;
	ADC_ConvertedValue = (int)T_Get_ADC_Average(20);	//20次取平均
	ADC_ConvertedValue = (ADC_ConvertedValue*825)>>10;//(ADC_ConvertedValue*825)>>10 表示 ADC_ConvertedValue*3300/4096
	Current_Temp = (((1370-ADC_ConvertedValue)/4.35)+25);	//转换为温度值 	 
	return Current_Temp;
}

esp32 接入SD_MMC_esp32 接入SD_MMC_04