cortex_m3_stm32嵌入式學習筆記(十七):內部溫度傳感器(ADC采集)

ARM 370瀏覽
STM32 有一個內部的溫度傳感器,可以用來測量 CPU 及周圍的溫度(TA)。該溫度傳感器在內部和 ADCx_IN16 輸入通道相連接,此通道把傳感器輸出的電壓轉換成數字值。溫度傳感器模擬輸入推薦采樣時間是 17.1μ s。 STM32 的內部溫度傳感器支持的溫度范圍為: -40~125度,精度為±?1.5℃左右(實際效果不咋地)。
效果確實不咋地。。大冬天的測出來是20多度。。

STM32 內部溫度傳感器的使用很簡單,只要設置一下內部 ADC,并激活其內部通道就差不多了。關于 ADC 的設置,我們在第上一章已經進行了詳細的介紹,這里就不再多說。接下來我們介紹一下和溫度傳感器設置相關的 2 個地方。


第一個地方,我們要使用 STM32 的內部溫度傳感器,必須先激活 ADC 的內部通道,這里通過 ADC_CR2 的 AWDEN 位( bit23)設置。設置該位為 1 則啟用內部溫度傳感器。第二個地方, STM32 的內部溫度傳感器固定的連接在 ADC 的通道 16 上,所以,我們在設置好 ADC 之后只要讀取通道 16 的值,就是溫度傳感器返回來的電壓值了。根據這個值,我們就可以計算出當前溫度。計算公式如下:
T(℃) ={( V25-Vsense) /Avg_Slope}+25
上式中:
V25=Vsense 在 25 度時的數值(典型值為: 1.43)。
Avg_Slope=溫度與 Vsense 曲線的平均斜率(單位: mv/℃或 uv/℃)(典型值: 4.3mv/℃)。
利用以上公式,我們就可以方便的計算出當前溫度傳感器的溫度了。


上一節的ADC是讀取外部通道的值,而內部溫度傳感器相當與把通道端口連接在內部溫度傳感器上。

配置ADC和上一節大體類似,只不過不用初始化外部IO,但要增加一句開啟內部溫度傳感器的語句。
temperate.c

#include "temperate.h" void T_Adc_Init(void) { 	ADC_InitTypeDef ADC_ist; 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE ); 	//72M/6=12,ADC 最大時間不能超過 14M 	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//設置 ADC分頻因子6 	ADC_DeInit(ADC1);//復位 ADC1,將外設 ADC1 的全部寄存器重設為缺省值 	 	ADC_ist.ADC_Mode= ADC_Mode_Independent;//ADC 獨立模式 	ADC_ist.ADC_ScanConvMode=DISABLE;//單通道模式 	ADC_ist.ADC_ContinuousConvMode=DISABLE;//單次轉換模式 	//轉換由軟件而不是外部觸發啟動 	ADC_ist.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; 	ADC_ist.ADC_DataAlign=ADC_DataAlign_Right;//ADC 數據右對齊 	ADC_ist.ADC_NbrOfChannel=1;//順序進行規則轉換的 ADC 通道的數目 	ADC_Init(ADC1,&ADC_ist); 	 	ADC_TempSensorVrefintCmd(ENABLE);  //開啟內部溫度傳感器 	ADC_Cmd(ADC1,ENABLE);//使能指定的 ADC1 	ADC_ResetCalibration(ADC1);//開啟復位校準 	while(ADC_GetResetCalibrationStatus(ADC1));//等待復位校準結束 	ADC_StartCalibration(ADC1);//開啟 AD 校準 	while(ADC_GetCalibrationStatus(ADC1));//等待校準結束 } //獲得 ADC 值 //ch:通道值 0~3 u16 T_Get_Adc(u8 ch) { 	//設置指定 ADC 的規則組通道設置它們的轉化順序和采樣時間 	ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);  	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的 ADC1 的軟件轉換功能 	while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待轉換結束 	return ADC_GetConversionValue(ADC1);//返回最近一次 ADC1 規則組的轉換結果 } u16 T_Get_Temp(void) { 	u16 temp_val=0;u8 i; 	for(i=0;i<10;i++) 	{ 		temp_val+=T_Get_Adc(ADC_Channel_16); 		delay_ms(5); 	} 	return temp_val/10; } u16 T_Get_Adc_Average(u8 ch,u8 times) { 	u32 tem_val=0; 	u8 i; 	for(i=0;i<times;i++) 	{ 		tem_val+=T_Get_Adc(ch); 		delay_ms(5); 	} 	return tem_val/times; }

temperate.h

#ifndef _TEMP_H #define _TEMP_H #include "sys.h" #include "delay.h"  #define ADC_CH_TEMP  	ADC_Channel_16 //溫度傳感器通道 void T_Adc_Init(void); u16 T_Get_Adc(u8 ch); u16 T_Get_Temp(void); u16 T_Get_Adc_Average(u8 ch,u8 times); #endif

主函數是在上一節的基礎上修改的。。

#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "lcd.h" #include "temperate.h" void init() { 	delay_init();	    	 //延時函數初始化	   	uart_init(9600);	 	//串口初始化為9600 	LED_Init();		  		//初始化與LED連接的硬件接口  	LCD_Init(); 	T_Adc_Init(); 	POINT_COLOR=RED;//設置字體為紅色 	LCD_ShowString(60,40,200,24,24,"ADC Test ^-^"); 	LCD_ShowString(60,70,200,16,16,"Medium difficulty"); 	LCD_ShowString(60,90,200,16,16,"2015/1/25"); 	LCD_ShowString(60,110,200,16,16,"By--Mr yh"); 	//顯示提示信息 	POINT_COLOR=BLUE;//設置字體為藍色 	LCD_ShowString(60,130,200,16,16,"TEMP_VAL:");	       	LCD_ShowString(60,150,200,16,16,"TEMP_VOL:0.000V");	       	LCD_ShowString(60,170,200,16,16,"TEMPERATE:00.00C");	   } int main(void) { 	u16 adcnum; 	float tem,temperate; 	init(); 	while(1) 	{ 		adcnum=T_Get_Adc_Average(ADC_CH_TEMP,10); 		LCD_ShowxNum(132,130,adcnum,4,16,0);//顯示ADC的值 		tem=(float)adcnum*(3.3/4096); 		temperate=tem; 		adcnum=tem; 		LCD_ShowxNum(132,150,adcnum,1,16,0);//顯示電壓值的整數位 		tem-=(u8)tem; 		LCD_ShowxNum(148,150,(u32)(tem*1000),3,16,0X80);//顯示電壓值的小數位 		temperate=(1.43-temperate)/0.0043+25;		//計算出當前溫度值 		LCD_ShowxNum(140,170,(u8)temperate,2,16,0); //顯示溫度整數部分 		temperate-=(u8)temperate; 		LCD_ShowxNum(164,170,temperate*100,2,16,0X80);//顯示溫度小數部分 		LED0=!LED0; 		delay_ms(250); 	} }

七星彩走势图2元网官网