野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13511|回复: 2

STM32内部温度传感器的使用

[复制链接]
发表于 2016-11-25 16:28:05 | 显示全部楼层 |阅读模式
STM32有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA)。
  • 该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值
  • 温度传感器模拟输入推荐采样时间是17.1μs
  • STM32的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为±1.5℃左右
  • 内部温度传感器更适合于检测温度的变化,而不是测量绝对温度。

我们要使用STM32的内部温度传感器,必须先激活ADC的内部通道,这里通过ADC_CR2的TSVREFE位(bit23)设置。设置该位为1则启用内部温度传感器。

ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
温度计算公式:
T(℃)=((V25-Vsense)/Avg_Slope)+25



  1. //初始化ADC
  2. //这里我们仅以规则通道为例
  3. //我们默认将开启通道0~3
  4. void T_Adc_Init(void)  //ADC通道初始化
  5. {
  6.     ADC_InitTypeDef ADC_InitStructure;
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1    , ENABLE );   //使能GPIOA,ADC1通道时钟
  8.     RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //分频因子6时钟为72M/6=12MHz
  9.   ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值
  10.     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //ADC工作模式:ADC1和ADC2工作在独立模式
  11.     ADC_InitStructure.ADC_ScanConvMode = DISABLE;   //模数转换工作在单通道模式
  12.     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
  13.     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
  14.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  //ADC数据右对齐
  15.     ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目
  16.     ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
  17.     ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
  18.     ADC_Cmd(ADC1, ENABLE);  //使能指定的ADC1
  19.     ADC_ResetCalibration(ADC1); //重置指定的ADC1的复位寄存器
  20.   while(ADC_GetResetCalibrationStatus(ADC1));   //获取ADC1重置校准寄存器的状态,设置状态则等待
  21.     ADC_StartCalibration(ADC1);
  22.     while(ADC_GetCalibrationStatus(ADC1));      //获取指定ADC1的校准程序,设置状态则等待
  23. }

  24. u16 T_Get_Adc(u8 ch)   
  25. {
  26.     ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );  //ADC1,ADC通道3,第一个转换,采样时间为239.5周期                    
  27.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能
  28.     while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
  29.     return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
  30. }

  31. //得到ADC采样内部温度传感器的值
  32. //取10次,然后平均
  33. u16 T_Get_Temp(void)
  34.     {
  35.     u16 temp_val=0;
  36.     u8 t;
  37.     for(t=0;t<10;t++)
  38.         {
  39.         temp_val+=T_Get_Adc(ADC_Channel_16);      //TampSensor
  40.         delay_ms(5);
  41.         }
  42.     return temp_val/10;
  43.     }

  44. //获取通道ch的转换值
  45. //取times次,然后平均
  46. u16 T_Get_Adc_Average(u8 ch,u8 times)
  47. {
  48.     u32 temp_val=0;
  49.     u8 t;
  50.     for(t=0;t<times;t++)
  51.     {
  52.         temp_val+=T_Get_Adc(ch);
  53.         delay_ms(5);
  54.     }
  55.     return temp_val/times;
  56. }      

  57. //得到温度值
  58. //返回值:温度值(扩大了100倍,单位:℃.)
  59. short Get_Temprate(void)    //获取内部温度传感器温度值
  60. {
  61.     u32 adcx;
  62.     short result;
  63.     double temperate;
  64.     adcx=T_Get_Adc_Average(ADC_Channel_16,20);  //读取通道16,20次取平均
  65.     temperate=(float)adcx*(3.3/4096);       //电压值
  66.     temperate=(1.43-temperate)/0.0043+25;   //转换为温度值     
  67.     result=temperate*=100;                  //扩大100倍.
  68.     return result;
  69. }


  70. int main(void)
  71. {   
  72.     short temp;
  73.     delay_init();            //延时函数初始化   
  74.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
  75.     uart_init(115200);      //串口初始化为115200
  76.     LED_Init();             //初始化与LED连接的硬件接口
  77.     LCD_Init();             //初始化LCD
  78.     T_Adc_Init();               //ADC初始化        
  79.     POINT_COLOR=RED;//设置字体为红色
  80.     LCD_ShowString(30,50,200,16,16,"WarShip STM32");   
  81.     LCD_ShowString(30,70,200,16,16,"Temperature TEST");
  82.     LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
  83.     LCD_ShowString(30,110,200,16,16,"2015/1/14");     
  84.     POINT_COLOR=BLUE;//设置字体为蓝色      
  85.     LCD_ShowString(30,140,200,16,16,"TEMPERATE: 00.00C");         
  86.     while(1)
  87.     {
  88.         temp=Get_Temprate();    //得到温度值
  89.         if(temp<0)
  90.         {
  91.             temp=-temp;
  92.             LCD_ShowString(30+10*8,140,16,16,16,"-");   //显示负号
  93.         }else LCD_ShowString(30+10*8,140,16,16,16," "); //无符号      
  94.         LCD_ShowxNum(30+11*8,140,temp/100,2,16,0);      //显示整数部分
  95.         LCD_ShowxNum(30+14*8,140,temp%100,2,16, 0X80);  //显示小数部分
  96.         LED0=!LED0;
  97.         delay_ms(250);  
  98.     }
  99. }
复制代码



回复

使用道具 举报

发表于 2016-11-25 16:30:28 | 显示全部楼层
其实这个传感器的最大作用是用来测量芯片内部的温度的变化
回复 支持 反对

使用道具 举报

发表于 2016-11-25 18:34:39 | 显示全部楼层
之前玩过这个,纯粹的是玩,但是具体应用的话...貌似没想到哪能用的上

如果是一个密闭的控制盒,只能检测单片机,难道要来个过温降频么
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-1-13 14:19 , Processed in 0.030646 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表