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.顯示結果:

        
https://blog.csdn.net/qq_27970103/article/details/81325418

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章