STM32
直播中

河神大人

8年用户 1506经验值
擅长:电源/新能源
私信 关注
[问答]

STM32内部温度传感器有哪些使用注意事项呢

STM32内部温度传感器的结构是怎样组成的?
STM32内部温度传感器有哪些使用注意事项呢?

回帖(1)

萧登水

2021-11-26 16:01:00
记录一下,方便以后翻阅~
主要内容:
1) STM32内部温度传感器概述;
2) 相关实验代码解读。
实验功能:系统启动后,实时将内部温度传感器的值传至串口助手上。
官方资料:《STM32中文参考手册V10》第11章——温度传感器
1. 内部温度传感器框图

  

  

2. STM32内部温度传感器概述
2.1 STM32有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA);
2.2 该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值;
2.3 温度传感器模拟输入推荐采样时间是17.1μs(最快);
2.4 STM32的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为±1.5℃左右。
备注:内部温度传感器更适合于检测温度的变化,而不是测量绝对温度。如果需要测量绝度温度,应该使用一个外部温度传感器。
3. STM32F10x系列芯片ADC通道和引脚对应关系

  

  

4. 内部温度传感器使用注意事项:
4.1 要使用STM32的内部温度传感器,必须先激活ADC的内部通道,通过ADC_CR2寄存器的TSVREFE位(bit23)设置。设置该位为1则启用内部温度传感器。

  

  

4.2 STM32的内部温度传感器固定的连接在ADC的通道16上,所以,在设置好ADC之后只要读取通道16的值,就是温度传感器返回来的电压值。根据该值,可计算出当前温度,公式如下:
T=[(V25-Vsense)/Avg_Slope]+25
上式中:
V25——Vsense在25度时的数值(典型值为:1.43);
Avg_Slope——温度与Vsense曲线的平均斜率(单位为mv/℃或uv/℃)(典型值为4.3Mv/℃);
利用以上公式,可以计算出当前温度传感器的温度。

  

  

5. 开启内部温度传感器步骤:
5.1 选择ADC_IN16输入通道;
5.2 设置采样时间大于17.1us;
5.3 设置ADC_CR2的TSVREFE位,打开内部温度传感器;
5.4 设置ADON位启动转换;
5.5 读取ADC结果;
5.6 计算。
6. 相关实验代码解读
6.1 tsensor.h头文件代码解读
  
#ifndef __TSENSOR_H
#define __TSENSOR_H
#include "stm32f10x.h"  
short Get_Temprate(void);               
void Adc_Init(void);                     
u16  Get_Adc(u8 ch);                     
u16  Get_Adc_Average(u8 ch,u8 times);        
#endif


6.2 tsensor.c文件代码解读


#include "tsensor.h"
#include "delay.h"
#include "sys.h"
//编写Adc_Init初始化函数//
void Adc_Init(void)  
{
ADC_InitTypeDef ADC_InitStructure;
//使能GPIOA,ADC1通道时钟//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE );   
//设置ADC时钟,对RCC_CFGR时钟配置寄存器的位[14~15] ADCPRE操作//
RCC_ADCCLKConfig(RCC_PCLK2_Div6);   
ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值//
//ADC_InitStructure参数设置//
//ADC_CR1寄存器,位[19:16]:DUALMODE双模式选择,ADC_Mode_Independent=0x00000000,独立模式//
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
//ADC_CR1寄存器,位8:SCAN扫描模式,0关闭扫描模式//
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
//ADC_CR2寄存器,位1:CONT连续转换,0单次转换模式//
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
//ADC_CR2寄存器,位[19:17]:EXTSEL选择启动规则通道组转换的外部事件,ADC_ExternalTrigConv_None=0x000E0000,SWSTART软件控制//
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//ADC_CR2寄存器,位11:ALIGN数据对齐,ADC_DataAlign_Right=0x00000000,右对齐//
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//ADC_SQR1寄存器,位[23:20]:L规则通道序列长度,1指1个转换,即位[23:20]设为0000//
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
//ADC_CR2寄存器,位23:TSVREFE温度传感器和Vrefint使能,启动温度传感器//
ADC_TempSensorVrefintCmd(ENABLE);
ADC_Cmd(ADC1, ENABLE);                          //使能指定的ADC1//
//下面四个函数用于校准//
ADC_ResetCalibration(ADC1);                     //重置指定的ADC1的复位寄存器//
while(ADC_GetResetCalibrationStatus(ADC1));     //获取ADC1重置校准寄存器的状态,设置状态则等待//
ADC_StartCalibration(ADC1);                     //开启AD校准//
while(ADC_GetCalibrationStatus(ADC1));          //获取指定ADC1的校准程序,设置状态则等待//
}
//编写Get_Adc函数,获取温度传感器的原始值(二进制转十进制的值)//
u16 Get_Adc(u8 ch)   
{
  //设置指定ADC的规则组通道,四个入口参数//
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );         
ADC_SoftwareStartConvCmd(ADC1, ENABLE);            //使能指定的ADC1的软件转换启动功能//
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));    //等待转换结束,EOC=1时,转换完成,则While停止//
return ADC_GetConversionValue(ADC1);               //返回最近一次ADC1规则组的转换结果//
}
//取times次,然后平均,取温度传感器采集的原始值(十进制值)//
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t {
  temp_val+=Get_Adc(ch);
  delay_ms(5);
}
return temp_val/times;
}     
short Get_Temprate(void)                     //获取内部温度传感器温度值//
{
u32 adcx;
double temperate;
adcx=Get_Adc_Average(ADC_Channel_16,20);    //读取通道16,20次取平均//
temperate=(float)adcx*(3.3/4096);           //先转成电压值//
temperate=(1.43-temperate)/0.0043+25;       //再转换为温度值//   
return temperate;
}


6.3 main.c文件代码解读


#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"  
#include "tsensor.h"
int main(void)
{  
float temp;   
delay_init();          //延时函数初始化   
uart_init(115200);     //串口初始化为115200
LED_Init();            //初始化与LED连接的硬件接口
Adc_Init();            //ADC初始化        
while(1)
{
  temp=Get_Temprate();  //得到温度值//
  printf("芯片温度:%.1fn",temp);
  LED0=!LED0;
  delay_ms(500);
}
}


  7. 实验效果

  

  
举报

更多回帖

发帖
×
20
完善资料,
赚取积分