聲明:此文件參考原創博客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.顯示結果: