STM32 内部温度传感器

声明:此文件参考原创博客https://blog.csdn.net/windows260/article/details/51136072,支持原创。

1.简介:

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

2.特点:

        1.该温度传感器在内部和ADCx_IN16输入通道相连接。

        2.STM32的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为±1.5℃左右

        3. 温度传感器产生一个随温度线性变化的电压,转换范围在2V < VDDA < 3.6V之间。

3.注意:

        使用STM32的温度传感器,必须先激活ADC的内部通道,通过ADC_CR2的TSVREFE位(bit23)置1使能。

4.计算公式:

        

5.工程代码(以STM32F103C8T6 + SSD1306为例):

//WSCH_ADC.C文件
#include "WSCH_ADC.h"

/*********************************************************************************************************
** Function name:           User_Adc_Init
** Descriptions:            ADC初始化
** input parameters:        none
** Returned value:          none
*********************************************************************************************************/
void User_Adc_Init(void)  //ADC通道初始化
{
    ADC_InitTypeDef ADC_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |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 = DISABLE;   //模数转换工作在单通道模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
    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_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
    ADC_Cmd(ADC1, ENABLE);  //使能指定的ADC1
    
    ADC_ResetCalibration(ADC1); //重置指定的ADC1的复位寄存器
    while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1重置校准寄存器的状态,设置状态则等待
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));      //获取指定ADC1的校准程序,设置状态则等待
}

/*********************************************************************************************************
** Function name:           Get_Adc
** Descriptions:            获取ADC采样值
** input parameters:        ch:通道
** Returned value:          最近一次ADC规则组的转换结果
*********************************************************************************************************/
uint16_t Get_Adc(uint8_t ch)
{
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );  //ADC1,ADC通道3,第一个转换,采样时间为239.5周期                    
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
    return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}

/*********************************************************************************************************
** Function name:           Get_Temp
** Descriptions:            取10次采样值,然后平均
** input parameters:        none
** Returned value:          10次采样平均值
*********************************************************************************************************/
uint16_t Get_Temp(void)
{
    uint16_t temp_val=0;
    uint8_t t;
    for(t=0;t<10;t++)
    {
        temp_val += Get_Adc(ADC_Channel_16);      //TampSensor
        Delay_mS(5);
    }
    return temp_val/10;
}


/*********************************************************************************************************
** Function name:           Get_Adc_Average
** Descriptions:            获取通道ch的转换值,取times次采样值,然后平均
** input parameters:        ch:通道
                            times:采样次数
** Returned value:          times次采样平均值
*********************************************************************************************************/
uint16_t Get_Adc_Average(uint8_t ch,uint8_t times)
{
    uint32_t temp_val=0;
    uint8_t t;
    for(t=0;t<times;t++)
    {
        temp_val += Get_Adc(ch);
        Delay_mS(5);
    }
    return temp_val/times;
}


/*********************************************************************************************************
** Function name:           Get_Temprate
** Descriptions:            获取STM32内部温度传感器的值
** input parameters:        none
** Returned value:          温度值(扩大了100倍,单位:℃.)
*********************************************************************************************************/
short Get_Temprate(void)    //获取内部温度传感器温度值
{
    uint32_t adcx;
    short result;
    double temperate;
    adcx = Get_Adc_Average(ADC_Channel_16,50);  //读取通道16,50次取平均
    temperate = (float)adcx*(3.3/4096);       //电压值 
    temperate = (1.43-temperate)/0.0043+25;   //转换为温度值     
    result = temperate*=100;                  //扩大100倍.
    return result;
}


/*****************************************************************************
 
                             OLED显示部分接口函数

*****************************************************************************/


/*******************************************
*Name: DecToChar
*Description: BCD转字符
*param: *s:源数组
        *d:待写入数组
        DataCnt:数据长度
********************************************/
void DecToChar(unsigned char *s,unsigned char *d,unsigned char DataCnt)
{
    unsigned char temp1,temp2,i;
    for(i=0;i<DataCnt;i++)
    {
        temp1 = *s/10;
        *d = HexToChar(temp1);
        d = d + 1;
        temp2 = *s%10;
        *d = HexToChar(temp2);
        d = d + 1;
        s = s + 1;
    }
}

/*******************************************
*Name: HexToChar
*Description: 将16进制转换成字符型数据
*param: temp:待发送数据
********************************************/
uint8_t HexToChar(unsigned char temp)
{
    uint8_t dst;
    if (temp < 10)
    {
        dst = temp + '0';
    }
    else
    {
        dst = temp -10 +'A';
    }
    return dst;
}

//WSCH_ADC.h文件
#ifndef __WSCH_ADC_H
#define __WSCH_ADC_H

#include "Mcu_config.h"
void User_Adc_Init(void);

uint16_t Get_Temp(void);
uint16_t Get_Adc(uint8_t ch);
uint16_t Get_Adc_Average(uint8_t ch,uint8_t times);

short Get_Temprate(void);


uint8_t HexToChar(unsigned char temp);
void DecToChar(unsigned char *s,unsigned char *d,unsigned char DataCnt);

#endif



#include "Mcu_config.h"
#include "WCH_OLED.h"
#include "WSCH_ADC.h"

void Show_Temprate(short data);

//main.c文件
int main(void)
{
    short temp;
    
    User_ST32_Init();
    OLED_Init();
    
    OLED_Fill(0xFF);//全屏点亮
    Delay_mS(1000);
    OLED_Fill(0x00);//全屏灭
    Delay_mS(1000);
    
    User_Adc_Init();
    while(1)
    {
        temp = Get_Temprate();    //得到温度值
        Show_Temprate(temp);
        Delay_mS(250);
    }
}

void Show_Temprate(short Tempdata)
{
    uint8_t i,x;
    uint8_t OLEDShowData[4];
    uint8_t data[2];
    data[0] = Tempdata/100;
    data[1] = Tempdata%100;
    
    DecToChar(data,OLEDShowData,2);
    
    OLED_ShowStr(0,2,"STM32",2);
    OLED_ShowCN(40,2,0);
    OLED_ShowCN(56,2,1);
    OLED_ShowCN(72,2,2);
    OLED_ShowCN(88,2,3);
    OLED_ShowStr(104,2,":",2);
    
    for(i=0,x=0; i<sizeof(OLEDShowData); i++,x++)
    {
        OLED_ShowData(30+8*x,4,OLEDShowData[i],2);
        if(i==1)
        {
            x++;
            OLED_ShowStr(30+8*x,4,".",2);
        }
    }
    OLED_ShowStr(30+8*x,4," C",2);
}

6.显示结果:

        

猜你喜欢

转载自blog.csdn.net/qq_27970103/article/details/81325418