STM32 ADC Single Channel Polling Mode
In this tutorial we will learn how to use STM32 ADC in single channel polling mode. We will configure the ADC using CubeMX and HAL to read analog signals. With polling mode, the microcontroller waits until the conversion is complete and then reads the value. This method is easy to understand and works well for basic projects where you need to measure only one input. We will also test the setup on different STM32 boards and explain the example code step by step.
This is the 1st tutorial in the STM32 ADC series. I am going to use the STM32H750 based development board for this series because it has advanced ADC features. But I will also cover the configuration changes required for some of the popular series that includes STM32F103C8 and STM32F446RE.
STM32 ADC Polling Mode Video Tutorial
This tutorial shows how to configure and read STM32 ADC in single channel Polling mode using CubeMX. You’ll learn how to set up the ADC clock, write the code, and check results step by step. To make things even clearer, I’ve also created a video walkthrough that demonstrates the full process in action. Follow the written guide here while watching the video for a better understanding.
Watch the Video- Hardware Required for STM32 ADC Tutorial
- What is ADC Polling Mode in STM32
- STM32 ADC Features and Board Comparison
- STM32F103 ADC Configuration
- STM32F446 ADC Configuration
- STM32H750 ADC Configuration
- STM32 ADC Wiring Diagram
- Example Code: Polling Mode ADC Read
- Result of STM3 ADC Single Channel Polling Mode
- Conclusion
- Next Tutorials in the STM32 ADC Series
- PROJECT DOWNLOAD
- STM32 ADC Polling Mode – Common Questions and Answers
Hardware Required for STM32 ADC Tutorial
To follow this tutorial, you will need the following hardware:
- STM32F446 Dev Board (e.g., STM32F4, STM32F7, STM32H7, or any board with ADC support)
- Potentiometer (to provide an analog input signal)
- Breadboard (for easy circuit connections)
- Jumper Wires (male-to-male for connections)
- USB Cable (to connect the STM32 board to the PC for programming and debugging)
What is ADC Polling Mode in STM32
When we use ADC polling mode in STM32, the microcontroller starts a conversion and then waits until the conversion is complete. After that, it reads the digital value from the ADC data register. This method is simple to use and does not need interrupts or DMA. However, it keeps the CPU busy while waiting, so it is not the best choice for real-time applications.
Definition and working of ADC polling mode
ADC polling mode means the code runs in a loop and checks the status flag until the conversion is finished. Once the flag is set, the program reads the ADC value and continues.
Advantages of ADC polling mode
Polling mode is easy to set up and works well when you only need to read a single channel. It helps beginners understand how ADC works in STM32 without adding complex code.
Limitations of ADC polling mode
Since the CPU waits for the conversion to finish, it cannot do other tasks at the same time. This makes polling mode less efficient for projects that require multitasking or continuous data processing.
STM32 ADC Features and Board Comparison
Different STM32 boards come with slightly different ADC features. The main settings such as resolution, sampling time, and channel selection remain the same, but each series has its own limits. Understanding these features helps you configure the ADC correctly for your project.
Here’s a simple comparison table of STM32 ADC features for F103, F446, and H750 boards:
STM32 Series | ADC Resolution | Sampling Speed | Channels | Best Use Case |
---|---|---|---|---|
STM32F103 | 12-bit (0–4095) | Basic speed | Multiple channels | Beginner projects, single or simple multi-channel readings |
STM32F446 | 12-bit | Higher speed than F1 | Multiple channels | Applications needing faster sampling and better accuracy |
STM32H750 | 12-bit+ (advanced ADC) | Very high speed | Multiple channels with advanced modes | Signal processing, real-time control, high-performance projects |
STM32F103 ADC Configuration
To configure ADC on STM32F103 in single channel polling mode, we will use CubeMX and HAL library. The process includes setting up the clock, enabling the ADC, and selecting the input channel.
Clock setup for STM32F103 ADC
The image below shows the clock configuration for the STM32F103C8T6.
The system is clocked by the external 8MHz crystal and we can use the PLL to run the system at maximum 72 MHz. Further the ADC prescaler (6 in the image) can be used to set the ADC clock (12MHz in the image) at desired frequency.
The STM32F103C8T6 supports the ADC clock upto a maximum frequency of 14MHz.
ADC Configuration
The image below shows the ADC Configuration in STM32F103C8.
I have selected the ADC1 Channel 0 and you can see the pin PA0 is configured as the ADC1_IN0 pin. The ADC is configured in the independent mode. In this mode, the ADC1 can be used independently and we do not need any other ADC for it.
ADC Resolution
The STM32F103C8T6 ADC does not have the option to configure the ADC Resolution. By default the Resolution is 12 bit and it is fixed. You can find this information in the reference manual of the MCU. The image below is from pg 215 of the STM32F103C8 reference manual.
ADC Data Alignement
Since the ADC Resolution is 12bit, the data is stored in a 16 bit Data Register. The Data Alignment controls whether we want to align the data to the left or right of this array. The image below shows the available data alignment in STM32F103 ADC.
We will keep the Data alignment to the Right, as it is easier to process the data.
ADC Scan Conversion mode
This mode is used to scan a group of analog channels. This mode will be automatically selected if you are converting more than 1 channel. A single conversion is performed for each channel of the group. After each end of conversion the next channel of the group is converted automatically. If the continuousconversionmode is ENABLED, conversion does not stop at the last selected group channel but continues again from the first selected group channel.
Since we are using single channel in this tutorial, we will keep this mode disabled.
ADC Continuous conversion mode
In continuous conversion mode ADC starts another conversion as soon as it finishes one. This method is more efficient if you want to convert continuously. In case of single channel, the same channel will be converted again and again.
We are using the polling mode in this tutorial, where we will manually call the ADC to start the conversion. So we will keep this disabled for this tutorial.
ADC Regular/Injected Conversion
The ADC can be used in either the Regular conversion Mode or injected conversion mode. The Regular conversion mode is simple as it sounds, basically the normal ADC mode we use. Whereas in the injected mode, we can ‘inject’ a sequence of conversions in between the regular conversions. The injected channels has higher priority, so the ADC will pause the conversion for the regular sequence, then first convert the injected sequence, and it will resume the regular sequence afterwards.
ADC External Trigger Source
The Trigger Source can be used to start the conversion. We can use the timer’s output to trigger the ADC conversion, and hence we can also control the conversion rate. For now we will set this trigger to be launched by the software, so that we can manually start the conversion when needed.
ADC Rank
The Rank section is used to configure the individual channel. When using multiple channels, we can configure the sequence of conversion here. Also we can set the sampling time for each channel. The sampling time is set in ADC CYCLES, and the higher the cycles, the more time ADC will take to sample each channel.
I am setting the maximum sampling time as here we are using a simple potentiometer and time requirement is not an issue. To understand more about how to sample the ADC at a fixed rate, check out the ADC sampling time tutorial.
STM32F446 ADC Configuration
Clock setup for STM32F446 ADC
The image below shows the clock configuration for the ADC in STM32F446RE.
The system is clocked by the external 8MHz crystal and we can use the PLL to run the system at maximum 180 MHz. There is no separate ADC Clock shown in the clock configuration.
If we check the block diagram at pg 16 of the STM32F446RE Datasheet, we can see that the ADC1 is connected to the APB2 Clock. The image is shown below.
As per our current clock configuration, the APB2 clock is at 90MHz.
ADC Configuration
The image below shows the ADC configuration.
I have selected the ADC1 Channel 0 and you can see the pin PA0 is configured as the ADC1_IN0 pin. The ADC is configured in the independent mode. In this mode, the ADC1 can be used independently and we do not need any other ADC for it.
ADC Prescaler
We have the option to configure the clock Prescaler for the ADC. Our current APB2 clock is at 90MHz, and if we set the prescaler to 6, the ADC clock will be reduced to 90/6 = 15MHz.
ADC Resolution
The F446RE has the option to configure the ADC Resolution. We can set the Resolution to 6its, 8bits, 10bits or 12bits. The higher the resolution is, the more accurate will be the ADC data, but the ADC will take more time to sample and convert the result.
Here I have configured the resolution to 12bits.
The rest of the configuration is similar to what we have seen in the F103C8. We have the Data alignment, Scan conversion mode, continuous conversion mode, regular conversion, rank, sampling time etc. So I will cover the ones which are different here.
ADC DMA Continuous Request
This feature is used along with the DMA. Basically while using the DMA to fetch the data from the ADC, we can enable this feature to allow the DMA to continuously request the data from the ADC. This way we do not need to call the DMA again after it has finished receiving the data.
End of Conversion Section
The end of conversion flag (EOC) shows that the conversion is finished and the data is ready to be processed. We can choose whether this flag sets after each channel is converted or only after a sequence of channels is converted in the case of multiple channels.
Since we are using a single channel in this tutorial, either of the options are fine. But you need to be careful while using the multiple channels. This flag should be configured as according to how you want to the process the data. For example, if you are converting 10 channels and set the EOC for each channel, the interrupt will trigger 10 times for each sequence.
STM32H750 ADC Configuration
Clock setup for STM32H750 ADC
The image below shows the clock configuration for ADC in STM32H750.
The external 25 MHz crystal clocks the system, and we use the PLL to run it at a maximum of 480 MHz. The PLL2p clocks the ADC, and we can configure it separately. With the current setup, the ADC clock runs at 15 MHz.
ADC Configuration
Below is the image showing the ADC configuration.
I have selected ADC1 Channel 3 in the Single Ended Mode. The single Ended mode is the Normal ADC mode we have available in the above mentioned MCUs also. In this mode, the ADC measures the voltage on the input pin. Other than this, we have another option to configure the ADC in the Differential mode. Where the ADC will measure the voltage different between the two inputs.
We will cover the differential mode in the future tutorials.
ADC Prescaler
We have the option to configure the clock Prescaler for the ADC. Our ADC clock runs at 15 MHz, and when we set the prescaler to 10, the ADC clock decreases to 1.5 MHz.
ADC Resolution
The H750 has the option to configure the ADC Resolution as well. We can set the Resolution to 8bits, 10bits, 12bits, 14bits or 16bits. The higher the resolution is, the more accurate will be the ADC data, but the ADC will take more time to sample and convert the result.
Here I have configured the resolution to 16bits.
The rest of the configuration is similar to what we have seen in the F446RE. We have the Scan conversion mode, continuous conversion mode, End of Conversion, regular conversion, rank, sampling time etc. So I will cover the ones which are different here.
Left Bit Shift
The Left Bit Shift (LSHIFT) is a way to shift the converted value towards the left. The result may be negative, so the output data is signed. We will keep it disabled for now and might cover it in the future tutorials.
Converted Data Management Mode
The mode specifies what to do with the converted data. We can transfer the converted data using the DMA, or transfer the data to the DFSDM Register (Digital Filter for Sigma-Delta Modulator) or leave the data in the ADC DR (Data Register).
We are not using the DMA transfer right now, so we will leave the data in the DR (Data Register).
ADC Oversampling
We will not cover the oversampling for now, so ignore any configuration related to that. The ADC oversampling technique is covered in a separate post.
STM32 ADC Wiring Diagram
The image below shows the connection between STM32H750 and the Potentiometer.
The pin connection is described in the table below.
Potentiometer Pin | Connected To |
---|---|
VCC | 3.3V on STM32 |
GND | GND on STM32 |
OUT | PA6 (ADC1_INP3) Pin |
Example Code: Polling Mode ADC Read
This STM32 ADC example demonstrates how to read analog input using polling mode. The same code is compatible with all the STM32 MCUs. The code will remain the same for all the STM32 MCUs. If there are any changes, I will specify in this section itself.
Definitions
Let’s define some variables, which we will use in the main function later.
uint16_t ADC_VAL = 0;
int value = 0;
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;
}
We define ADC_VAL as a 16-bit variable, and we use it to store the converted ADC value. Even if we select 10-bit, 12-bit, or 14-bit resolution, we still declare ADC_VAL as a 16-bit variable.
We will use the map function to map the converted ADC value to our desired range. The mapped value will be stored in the value variable, which I have defined as an integer here.
The main function
Below is the main function.
int main()
{
.....
.....
while (1)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
ADC_VAL = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
value = map(ADC_VAL, 0, 65535, 0, 100);
HAL_Delay (500);
}
}
We want to measure the ADC continuously, so we will write our code in the while loop. Below are the steps to get the ADC data in polling method.
- First, START the ADC.
- Next, Poll for the conversion to complete. Here I have set the timeout to 100ms. If the ADC does not finish the conversion within this time, the function will timeout.
- Then, Read the converted value and store it in the ADC_VAL variable.
- Finally, STOP the ADC.
We now have the converted data stored in the ADC_VAL variable. We will use the map function to map the converted value to 0 to 100 range. Since I have set the ADC resolution to 16bits, the maximum value of the ADC_VAL variable will be 216-1 = 65535. Similarly, the maximum value for the 12bits resolution will be 212-1 = 4095 and the same for the 10bits resolution will be 210-1 = 1023.
The while loop will run every 500ms, therefore we will keep getting the updated data continuously.
Result of STM3 ADC Single Channel Polling Mode
The gif below shows the ADC values obtained by moving the potentiometer, in the STM32CubeIDE debugger.
When you move the slider to the right, the ADC_VAL increases towards 65535 and the value variable rises towards 100. Similarly, when you move the slider to the left, the ADC_VAL decreases and the value variable drops towards 0.
Conclusion
In this tutorial we learned how to use STM32 ADC in single channel polling mode with CubeMX and HAL. We configured the clock, selected the channel, and adjusted the resolution and sampling time. After running the example code, we tested the output using a potentiometer and verified the results in debugging mode. Polling mode is easy to understand and works well for simple projects, but it is not efficient for multitasking applications. For advanced use cases, you can later explore ADC with interrupts or DMA.
Next Tutorials in the STM32 ADC Series
STM32 ADC Part 3 – Multiple Channels with DMA Normal Mode
STM32 ADC Part 4 – Multiple Channels with DMA Circular Mode
STM32 ADC PART 5 – Multi‑Channel without DMA
STM32 ADC PART 6 – ADC Conversion Time Explained
STM32 ADC PART 7 – ADC External Trigger Source Selection
STM32 ADC PART 8 – Injected Conversion Mode
STM32 ADC PART 9 – ADC Oversampling Technique
PROJECT DOWNLOAD
Info
You can help with the development by DONATING Below.
To download the project, click the DOWNLOAD button.
STM32 ADC Polling Mode – Common Questions and Answers
Yes, but keep in mind that the CPU will remain busy during conversion. You need to plan carefully if you want to run peripherals like UART or SPI at the same time.
You can reduce noise by adding a small capacitor near the input pin, using proper grounding, or enabling ADC oversampling if your STM32 series supports it.
Polling too often can lead to unnecessary CPU usage and unstable values. It is better to add a small delay or average multiple samples.
Yes, STM32 allows you to change the ADC mode. Many developers start with polling for testing and later move to DMA or interrupts for efficiency.
Different STM32 series have variations in reference voltage, sampling speed, and ADC precision. These differences affect the conversion results.
Support Us by Disabling Adblock
We rely on ad revenue to keep Controllerstech free and regularly updated. If you enjoy the content and find it helpful, please consider whitelisting our website in your ad blocker.
We promise to keep ads minimal and non-intrusive.
Thank you for your support! 💙
Recent Posts
Random Picks
