实验目的
STM32内部集成了一个温度传感器,可以用来测量芯片的温度,本章学习如何读取此温度值,数据手册请参看第11章。
实验简介
STM32的内部温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压换成数字。温度传感器模拟输入推荐采样时间是17.1us。STM32的内部温度传感器支持的范围为-40~125度。精度比较差,为±1.5度左右。STM32内部温度传感器的使用很简单,只要设置一下内部ADC,并激活其内部通道就差不多了。
读温度
为使用传感器:
1.选择ADC1_IN16输入通道
2.选择采样时间为17.1us
3.设置ADC控制寄存器2(ADC_CR2)的TSVREFE位,以唤醒关电模式下温度传感器
4.通过设置ADON位启动ADC转换(或用外部触发)
5.读ADC数据寄存器上的Vsense数据结果
6.利用下列公式得出温度
温度( °C )= {(V25 - Vsense)/Avg_Slope } +25;
这里:
V25 = Vsense在25°C时的数值
Avg_Slope = 温度与Vsense曲线的平均斜率(单位为mV/°C或uV/°C)
其中V25和Avg_Slope的参考值在下图中
代码
main.c
#include "MyIncludes.h"
char buff[100];
int16_t Val;
u16 sys_cnt = 0;
void systick_isr(void)
{
if(sys_cnt < 1000)
sys_cnt++;
else
{
sys_cnt = 0;
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5);
}
}
int main(void)
{
System_Init();
LED_Init();
SysTick_Init(systick_isr);
USART1_Init(115200,NULL,NULL);
STM32_TempSample_Init();
//内部温度采集
while(1)
{
delay_ms(1000);
Val = Temp_Sample();
if(Val < 0)
sprintf(buff,"Chip Temp: -%d%d.%d'C\n",Val/1000,Val%1000/100,Val%100/10);
else
sprintf(buff,"Chip Temp: %d%d.%d'C\n",Val/1000,Val%1000/100,Val%100/10);
printf(buff);
}
}
adc.c
#ifndef __ADC_H_
#define __ADC_H_
#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"
#define ADC_DMA_ENABLE
//使能DMA传输
typedef struct
{
void (*isr_op)(void);
//中断处理
} _ADC_ISR_;
extern ADC_HandleTypeDef AdcHandle;
void STM32_ADC_Init(ADC_TypeDef *ADCx,uint32_t Channel,void(*ISR)(void));
//ADC初始化
uint32_t Vol_Sample(void);
//电压采样
void STM32_VRefSample_Init(void);
//内部参考电压Vref采集
uint16_t VRef_Sample(void);
//内部参考电压Vref采样
void STM32_TempSample_Init(void);
//内部温度传感器采集
int Temp_Sample(void);
//内部温度采样
#endif
adc.c
#include "adc.h"
ADC_HandleTypeDef AdcHandle;
//ADC句柄结构变量声明
_ADC_ISR_ adc_isr;
//DMA句柄结构变量声明
#ifdef ADC_DMA_ENABLE
//使能DMA
uint32_t aADCxConvertedValues;
#endif
//在HAL_ADC_Init中调用
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
//GPIO初始化结构变量声明
static DMA_HandleTypeDef hdma_adc;
//DMA句柄结构变量声明
RCC_PeriphCLKInitTypeDef PeriphClkInit;
//RCC扩展时钟结构变量声明
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
//要配置的扩展时钟 ADC外围时钟
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
//ADC时钟源 可以是预分频器的值 PCLK(IO接口时钟)2/6