STM32 內(nèi)部溫度傳感器
STM32 芯片內(nèi)部一項獨特的功能就是內(nèi)部集成了一個溫度傳感器, 因為是內(nèi)置, 所以測試的是芯片內(nèi)部的溫度, 如果芯片外接負載一定的情況下, 那么芯片的發(fā)熱也基本穩(wěn)定, 相對于外界的溫度而言, 這個偏差值也是基本穩(wěn)定的. 也就是說用 STM32 內(nèi)部傳感器來測量外界環(huán)境的溫度.
在一些惡劣的應(yīng)用環(huán)境下面, 可以通過檢測芯片內(nèi)部而感知設(shè)備的工作環(huán)境溫度, 如果溫度過高或者過低了 則馬上睡眠或者停止運轉(zhuǎn). 可以保證您的設(shè)備工作的可靠性.
1. STM32內(nèi)部溫度傳感器與ADC的通道16相連,與ADC配合使用實現(xiàn)溫度測量;
2. 測量范圍–40~125℃,精度±1.5℃。
3. 溫度傳感器產(chǎn)生一個隨溫度線性變化的電壓,轉(zhuǎn)換范圍在2V < VDDA < 3.6V之間。
轉(zhuǎn)換公式如下圖所示:
手冊中對于公式中的參數(shù)說明:
(二) 程序編寫
寫代碼的時候, 在測量要求不怎么高的情況下, 公式可以簡化.
簡化的公式:
Temperature= (1.42 - ADC_Value*3.3/4096)*1000/4.35 + 25;
程序編寫:
1. 初始化ADC , 初始化DMA
可以參考貼子:
[原創(chuàng)] MINI-STM32 開發(fā)板入門教程(六) 基于 DMA 的 ADC
http://www.mystm32.com/bbs/viewthread.php?tid=42&extra=page%3D1
主意: 內(nèi)部溫度傳感器是使用了 ADC1 的第 16 通道哦.
2. ADC_TempSensorVrefintCmd(ENABLE);
使能溫度傳感器和內(nèi)部參考電壓通道
3. 按照剛才列出的公式計算
Temperature= (1.42 - ADC_Value*3.3/4096)*1000/4.35 + 25;
(三) 仿真調(diào)試
(1) 使用Keil uVision3 通過ULINK 2仿真器連接實驗板,使用MINI-STM32 開發(fā)板附帶的串口線,連接實驗板上的 UART1 和 PC 機的串口,打開實驗例程目錄下的ADC.Uv2例程,編譯鏈接工程;
(2) 在 PC 機上運行 windows 自帶的超級終端串口通信程序(波特率115200、1位停止位、無校驗位、無硬件流控制);或者使用其它串口通信程序;
(3) 點擊MDK的Debug菜單,點擊Start/Stop Debug Session;
(4) 全速運行程序, 顯示結(jié)果如下所示。
基于 MDK 3.5 工程下載:
版權(quán)所有 麥思網(wǎng) 原創(chuàng),轉(zhuǎn)載請保留出處
http://www.mystm32.com/bbs/viewthread.php?tid=280&extra=page%3D1
========================================================================
貼一下初始化的函數(shù)
/*******************************************************************************
* Name : ADC_Configuration
* Deion : ADC_Configuration
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void ADC_Configuration(void)
{
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_55Cycles5);
/* Enable the temperature sensor and vref internal channel */
ADC_TempSensorVrefintCmd(ENABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
這個是抄襲馬七的均值數(shù)字濾波函數(shù) 呵呵
/*******************************************************************************
* Name : ADC_Filter
* Deion : ADC_Filter
* Input : None
* Output : None
* Return : ADC Converted Value
*******************************************************************************/
u16 ADC_Filter(void)
{
u16 result=0;
u8 i;
for(i=16;i>0;i--)
{
Delay_Ms(1);
result += ADCConvertedValue;
}
return result/16;
}
轉(zhuǎn)換結(jié)果 往串口發(fā)送顯示 (寫的很爛哈)
ADC_Value = ADC_filter();
vu16 Temperature= (1.42 - ADC_Value*3.3/4096)*1000/4.35 + 25;
ADC_Value = Temperature;
a = ADC_Value/1000;
b = (ADC_Value - a*1000)/100;
c = (ADC_Value - a*1000 - b*100)/10;
d = ADC_Value - a*1000 - b*100 - c*10;
Uart1_PutString("STM32 Chip Temperature = ",strlen("STM32 Chip Temperature = "));
Uart1_PutChar(a+0);
Uart1_PutChar(b+0);
Uart1_PutChar(c+0);
Uart1_PutChar(d+0);
Uart1_PutString(" Cn",strlen(" Cn"));
==================================================
11.10 溫度傳感器溫度傳感器可以用來測量器件周圍的溫度(TA)。
溫度傳感器在內(nèi)部和ADC1_IN16輸入通道相連接,此通道把傳感器輸出的電壓轉(zhuǎn)換成數(shù)字值。
溫度傳感器模擬輸入推薦采樣時間是17.1μs。 圖41是溫度傳感器的方框圖。 當沒有被使用時,傳感器可以置于關(guān)電模式。
注意:必須設(shè)置TSVREFE位激活內(nèi)部通道:ADC1_IN16(溫度傳感器)和ADC1_IN17(VREFINT)的轉(zhuǎn)換。
溫度傳感器輸出電壓隨溫度線性變化,由于生產(chǎn)過程的變化,溫度變化曲線的偏移在不同芯片上會有不同(最多相差45°C)。內(nèi)部溫度傳感器更適合于檢測溫度的變化,而不是測量絕對的溫度。如果需要測量精確的溫度,應(yīng)該使用一個外置的溫度傳感器。
讀溫度為使用傳感器:
1. 選擇ADC1_IN16輸入通道
2. 選擇采樣時間為17.1 μs
3. 設(shè)置ADC控制寄存器2(ADC_CR2)的TSVREFE位,以喚醒關(guān)電模式下的溫度傳感器
4. 通過設(shè)置ADON位啟動ADC轉(zhuǎn)換(或用外部觸發(fā))
5. 讀ADC數(shù)據(jù)寄存器上的VSENSE 數(shù)據(jù)結(jié)果
6. 利用下列公式得出溫度
溫度(°C) = {(V25 - VSENSE) / Avg_Slope} + 25
這里: V25 = VSENSE在25°C時的數(shù)值 Avg_Slope = 溫度與VSENSE曲線的平均斜率(單位為mV/ °C 或 μV/ °C)
參考數(shù)據(jù)手冊的電氣特性章節(jié)中V25 和Avg_Slope的實際值。 注意: 傳感器從關(guān)電模式喚醒后到可以輸出正確水平的VSENSE前,有一個建立時間。ADC在上電后也有一個建立時間,因此為了縮短延時,應(yīng)該同時設(shè)置ADON和TSVREFE位。
評論