Interfacing LM35 Temperature Sensor with STM32 (ADC Reading Explained)

Measuring temperature accurately is one of the most common requirements in embedded systems. In this tutorial, we’ll learn how to interface the LM35 temperature sensor with an STM32 microcontroller and read temperature values using the ADC peripheral.
This guide focuses on STM32F4 series, but the concepts apply to most STM32 MCUs.

1. What is the LM35?

The LM35 is a precision analog temperature sensor with an output voltage directly proportional to temperature.

  • 10 mV per °C
  • 0°C → 0 mV, 25°C → 250 mV, 100°C → 1.0 V
  • No external calibration required
  • Operating range: –55°C to +150°C

Since LM35 gives an analog voltage, we must use the STM32 ADC to convert it into a digital value.

2. Hardware Connections

LM35 PinConnect To
VoutADC Input Pin (here., PA0)
Vs+5V or +3.3V
GNDMCU Ground

If powered from 5V, ensure STM32 ADC input is 5V-tolerant or use a voltage divider.

3. How ADC on STM32 Works

voltage=(adc * 3.3f) / 4095.0f;

temperature=voltage * 100.0f;

4. Why We Set ADC Sampling Time (SMPR2 Register)

In the code, we used:

ADC1->SMPR2 |= (0x3 << 0);   // Channel 0 sampling time = 56 cycles

Why sampling time matters?

LM35 has finite output impedance, typically around 0.1–1 kΩ.
STM32 ADC contains a sample-and-hold capacitor (~5 pF) that must charge fully before the conversion.

If sampling time is too small, the ADC capacitor won’t charge fully, leading to inaccurate readings.

Why choose 56 cycles?

From STM32 reference manual:

SMPR2 ValueSampling Time
0x03 cycles
0x115 cycles
0x228 cycles
**0x356 cycles**

56 cycles is a good balance between:

  • Accuracy
  • Stability
  • Noise filtering
  • LM35 response characteristics

LM35 is slow-changing (temperature doesn’t change instantly), so long sampling time is ideal.

5. Complete STM32 Code (Register Level)

/*
this program will read the real time atmospheric temperature
written by Anees Kokadan
*/

#include <stdint.h>
#include "stm32_f446xx.h"
#include<stdio.h>

void ADC_init(void)
{
RCC->AHB1ENR|=(1<<0);
GPIOA->MODER|=(0X3<<0); // PA0 set as 11, for analog mode
GPIOA->PUPDR&=~(0X3<<0); // No pull up, pull down

RCC->APB2ENR|=(1<<8); // ADC1 Clock enable

/*
* ADC_SR = ADC status register
* OVR STRT JSTRT JEOC EOC AWD
* its all values are set by hardware, we do not need to set it manually
* instead we will check its value during program running
* like, to check if the conversion finished or not (EOC bit )
* if EOC is 0 -> conversion not completed
* if EOC is 1 -> conversion completed
*/

// ADC configuration
ADC1->CR2=0; //clearing CR2 register
ADC1->SQR3=0;`// clearing SQR3 register
ADC1->SMPR2|=(0X3<<0); // SAMPLING 56 cycles for channel 0 --> PA0

/*
* for LM35, to reduce noise the sampling time need to set to 56
* from reference manual of stm32, I found that for 56 cycles we need to set 0x3 on channel 0
*/

ADC1->CR2|=(1<<0); // ADC ON, inside CR2 register 0th bit is ADON
/*
* Bit 0 ADON: A/D Converter ON / OFF
This bit is set and cleared by software.
0: Disable ADC conversion and go to power down mode
1: Enable ADC -- > here we made it 1 to make ADC ON
*/
}

uint16_t ADC_Read(void)
{
ADC1->CR2|=(1<<30); // SWSTART --> Start conversion of regular channels
while (!(ADC1->SR&(1<<1))); // wait until EOC is set to 1 (wait until conversion complete)
// EOC is the 1st bit of SR register
return ADC1->DR; // take the value from data register
/*
* DR --> These bits are read-only. They contain the conversion result from the regular
channels.
*/
}


int main(void)
{
uint16_t adc;
float voltage, temperature;

ADC_init();

while(1)
{
adc=ADC_Read();
voltage=(adc * 3.3f) / 4095.0f;
temperature=voltage * 100.0f;
printf("Room temperature: %.2f C\n", temperature);
for(volatile int i=0; i<200000; i++); // small delay


}

}

Git hub link for full code

GitHub link for bare metal code and reference : https://github.com/gsmanees/Embedded_Systems/tree/main/STM32/ADC_LM35

6.Conclusion

Interfacing the LM35 with STM32 is simple once the ADC is configured correctly.
The key is choosing the right sampling time, because LM35 requires the ADC to wait long enough for its output to stabilize.

This project is perfect for beginners who want to explore:

  • STM32 ADC registers
  • Analog sensor interfacing
  • Temperature measurement
  • Embedded C bare-metal coding

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top