Honza T. / Mbed 2 deprecated EXAMPLE_Nucleo_InternalTempSensor

Dependencies:   TextLCD_improved mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "stm32f411xe.h"
00003 #include "TextLCD.h"
00004 
00005 /*
00006 Reading the temperature
00007 To use the sensor:
00008 3.     Select ADC1_IN16 or ADC1_IN18 input channel. 
00009 4.     Select a sampling time greater than the minimum sampling time specified in the datasheet.
00010 5.     Set the TSVREFE bit in the ADC_CCR register to wake up the temperature sensor from power down mode
00011 6.     Start the ADC conversion by setting the SWSTART bit (or by external trigger)
00012 7.     Read the resulting VSENSE data in the ADC data register
00013 8.     Calculate the temperature using the following formula: Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25
00014 Where:
00015     – V25 = VSENSE value for 25° C
00016     – Avg_Slope = average slope of the temperature vs. VSENSE curve (given in mV/°C or μV/°C)
00017 
00018     Refer to the datasheet’s electrical characteristics section for the actual values of V25and Avg_Slope.
00019  
00020 The TSVREFE bit must be set to enable the conversion of both internal channels: the ADC1_IN16 or ADC1_IN18 (temperature sensor) and the ADC1_IN17 (VREFINT). 
00021 
00022 The sensor has a startup time after waking from power down mode before it can output VSENSE at the correct level.
00023 The ADC also has a startup time after power-on, so to minimize the delay, the ADON and TSVREFE bits should be set at the same time.
00024 The temperature sensor output voltage changes linearly with temperature.
00025 The offset of this linear function depends on each chip due to process variation (up to 45 °C from one chip to another).
00026 The internal temperature sensor is more suit ed for applications that detect temperature variations instead of absolute temperatures.
00027 If accurate temperature reading is required, an external temperature sensor should be used.
00028 
00029 SINGLE Conversion:
00030 
00031 START
00032     CONT = 0
00033     ADC_CR2.SWSTART = 
00034 
00035 COMPLETED
00036     16bit data in ADC_DR
00037     EOC Flag is set
00038     If JEOCIE bit is set then interrupt generated
00039     ADC Stops
00040     
00041 ADC_SR (Status Register)
00042     - EOC (0x02): Cleared upon reading ADC_DR
00043     
00044 ADC_CR1 (Control Register 1)
00045     - RES [1:0]: Resolution
00046         00  12bit
00047         01  10bit
00048         10  8bit
00049         11  6bit
00050 
00051 ADC_CR2 (Control Register 2)
00052     - SWSTART (ADON must be set to 1): Start conversion on regular channels
00053     - ADON: A/D Convertor on/off
00054     - CONT: Continuous conversion
00055     
00056 ADC_DR (Data Register)
00057 
00058 ADC_CCR (Common Control Register)
00059     - TSVREFE (): Temperature Sensor and Vrefint enable
00060         VBATE must be disabled to measure temperature
00061     - VBATE (): Vbat enable
00062 
00063 ADC1_SQR1
00064     - L - počet převod; u regular
00065         0 = 1 převod
00066 
00067 ADC_SQR3
00068     - nejnižších 5 bitů je první převod
00069     
00070 ADC_Typedef
00071 ADC_Common_TypeDef
00072 
00073 RCC_TypeDef (APB2ENR)
00074 
00075 ADC_BASE
00076 ADC1_BASE
00077 
00078 ADC
00079 ADC1
00080 
00081  */
00082 
00083 void initADCTemp() {
00084     //enable ADC1 clock
00085     SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);
00086 
00087     // ADC on
00088     SET_BIT(ADC1->CR2, ADC_CR2_ADON);
00089     CLEAR_BIT(ADC1->CR2, ADC_CR2_CONT);
00090     
00091     // Temp sensor on
00092     CLEAR_BIT(ADC->CCR, ADC_CCR_VBATE);
00093     SET_BIT(ADC->CCR, ADC_CCR_TSVREFE);
00094     
00095     CLEAR_BIT(ADC1->CR1, ADC_CR1_RES);
00096 }
00097 
00098 uint16_t getADCTemp() {
00099     // Set channel
00100     ADC1->SQR1 &= ~ADC_SQR1_L;  // Count = 1
00101     ADC1->SQR3 |= ADC_SQR3_SQ1 & 18;
00102 
00103     // Start conversion
00104     SET_BIT(ADC1->CR2, ADC_CR2_SWSTART);
00105     
00106     // Wait for completion
00107     while (!READ_BIT(ADC1->SR, ADC_SR_EOC))
00108         ;
00109         
00110     // Return result
00111     return READ_REG(ADC1->DR);
00112 }
00113      
00114             
00115 int main() {
00116     const float     V25 = 943.3212f;// when V25=1.41V at ref 3.3V (0,76V)
00117     const float     Avg_Slope = 3.1030303f; //when avg_slope=4.3mV/C at ref 3.3V  (2.5mV/C)
00118     const uint16_t  bufferSize = 4;
00119 
00120     float       temp;
00121     uint16_t    i;
00122     uint16_t    uiCnt = 0;
00123 
00124     TextLCD lcd(PA_8, PA_7, PA_9, PA_1, PB_5, PA_10, TextLCD::LCD16x2);
00125 
00126     initADCTemp();
00127         
00128     while (true) {
00129         for (i = 0, temp = 0.0f; i < bufferSize; i++) {
00130             temp += ((float)getADCTemp() - V25) / Avg_Slope + 48.2f;
00131             wait_us(1000);
00132         }
00133         temp /= (float)bufferSize;
00134      
00135         lcd.cls();
00136         lcd.printf("Time: % 4u s", uiCnt);
00137         uiCnt += 1;
00138         lcd.locate(0, 1);    
00139         lcd.printf("Temp: % 3.1f%cC", temp, 0xdf);
00140         wait_us(1000000);
00141     }
00142 }
00143