STM32 ADC Timer Trigger Example & External Trigger Sources

In this tutorial, we’ll discuss the STM32 ADC Timer Trigger & External Trigger Sources For ADC channels’ conversion starting instead of the software-triggered mode that we’ve discussed in previous tutorials. Using the timer as a trigger source for the ADC allows for periodic ADC conversions to achieve whatever ADC sampling rate is required by your application.

The practical example we’ll implement in this tutorial is an STM32 LED dimmer using a potentiometer on an analog input pin and a PWM output to control the brightness of the LED. We’ll read the analog input regular channel in single-conversion mode using the ADC interrupt & we’ll use a Timer TRGO event to trigger the ADC every 20ms (to achieve a 50Hz sampling rate). Without further ado, let’s get right into it!

Table of Contents

  1. STM32 ADC Timer Trigger & External Trigger Sources
  2. STM32 ADC Timer Trigger Example Overview
  3. STM32 ADC Timer Trigger Example
  4. Wrap Up

STM32 ADC Timer Trigger & External Trigger Sources

The default option to trigger the STM32 ADC to start the conversion process is the Software Trigger source. Therefore, we had to manually call the HAL_ADC_Start() function whenever we wanted to start a new ADC conversion. However, the ADC can also be automatically triggered by internal or external trigger sources in the STM32 microcontroller itself.

This can be really useful to set the ADC conversion to occur periodically using a timer trigger to achieve a desired ADC sampling rate. Or to trigger the ADC conversion to start at a specific time relative to some output PWM signal (a very important feature for advanced measurement systems).

Below is the ADC block diagram as found in the datasheet for STM32F103xx target microcontrollers. It shows us that both the ADC regular channels and the injected channels can be triggered by internal hardware sources or external trigger pins.


1. STM32 ADC Timer Trigger Sources

As stated earlier, the timer trigger source can be very helpful to automatically set the ADC sampling rate with very little CPU intervention. The timer’s trigger output (TRGO) event can be configured to any one of the options shown below.


2. STM32 ADC External Trigger Sources

The external EXTI_x pins can be used to trigger the ADC to start the conversion on the rising or falling edge of the associated external GPIO pin. This feature can be really useful if we’d like to sync multiple ADCs in different microcontrollers so they start the conversion process at the exact same time. There are so many other applications for this feature as we’ll see in future STM32 projects.

❕ Note

Consider using DMA (Direct Memory Access) for efficient data transfer from the ADC data buffer register to memory. This can reduce the CPU overhead and ensure a smoother flow of data, especially in applications where a high ADC sampling rate is needed.

STM32 ADC Timer Trigger Example Overview

In this example project, we’ll create an STM32 LED Dimmer using ADC & PWM to read an analog input of a potentiometer to control the brightness of a PWM output going to an LED. This demo will run the STM32 ADC in Regular Channel Single-Conversion Timer-Triggered Mode With ADC Interrupt Enabled. In the ADC ISR, we’ll read the conversion result into a global buffer and toggle a GPIO pin to measure the ADC sampling rate.

Example Project Steps Summary:

  • Set up a new project with a system clock @ 72MHz
  • Set up an Analog input pin (Channel 7) in Regular Single-Conversion Mode With Timer3 TRGO event as a trigger source
  • Set up Timer2 in PWM mode with output on channel 1 (The LED pin)
  • Set up Timer3 to generate an update event as a TRGO @ 20ms (50Hz rate) (so the ADC sampling rate will also be 50Hz)
  • Set up a GPIO pin as an output pin, so we can toggle it in the ADC’s ISR to measure the ADC sampling rate

STM32 ADC Timer Trigger Example

In this example project, we’ll set up an ADC input regular channel (CH7) in single-conversion mode to be triggered by Timer3 which generates a TRGO event @ 20ms time intervals, so the ADC will sample the input channel @ 50Hz sampling rate. The ADC conversion completion will trigger an ADC interrupt event. In the ADC ISR handler, we’ll read and store the ADC reading into a global buffer variable and toggle a GPIO pin to measure the sampling rate using a DSO (digital storage oscilloscope).

We’ll also set up Timer2 in PWM mode to generate a PWM signal to control an LED’s brightness using the reading of the ADC input channel (from a potentiometer). The Timer3 will continuously trigger the ADC regular channel to start the conversion every 20ms, so we don’t need to continuously start the ADC manually in the main while(1) loop.

And now, let’s build this system step-by-step

Step #1

Open STM32CubeMX, create a new project, and select the target microcontroller.

Step #2

Configure The ADC1 Peripheral, Enable the regular Channel-7, and select the Timer3 TRGO event as a trigger source. In the NVIC tab, enable the ADC1 global interrupt.


Step #3

For Timer3, we need to enable the internal clock for the timer (72MHz). Next, we need to set it in such a way that it generates an update event every 20ms to achieve the desired 50Hz ADC sampling rate. For this, you can use our STM32 Timer Calculator to get the required values for the Prescaler (PSC) and Auto-Reload Register (ARR) in order to achieve the 20ms update time interval. You’ll get PSC=23 & ARR=59999 from the calculator.

Finally, choose the TRGO event to be “Update Event“. And that’s all about it.


Step #4

Configure Timer2 To Operate In PWM Mode With Output On CH1 (for the LED brightness control).

STM32 ADC Read Example HAL Code

Step #5

Go to the RCC clock configuration page and enable the HSE external crystal oscillator input.

STM32 RCC External Clock Selection CubeMX

Step #6

Go to the clock configurations page, and select the HSE as a clock source, PLL output, and type in 72MHz for the desired output system frequency. Hit the “ Enter” key, and let the application solve for the required PLL dividers/multipliers to achieve the desired clock rate.


Step #7

Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.

STM32 ADC Timer Trigger Example Code

Here is The Application Code For This LAB (main.c)

STM32 ADC Timer Trigger Code Explanation

We need to start the Timer3 module by calling the HAL_TIM_Base_Start(&htim3) function so it can trigger the ADC every 20ms. And we also need to start the ADC in interrupt mode at least once before the while(1) loop. Afterward, the ADC will be automatically triggered by the Timer3 module and we don’t need to call any function to start/trigger the ADC.

In the while(1) loop, we’ll continuously update the PWM output’s duty cycle with the latest value in the ADC_RES buffer.

Finally, in the ADC interrupt handler (ISR), we’ll read and store the ADC conversion result into the global buffer variable and toggle the GPIO (B0) pin to measure the ADC sampling rate (frequency).



STM32 ADC Timer Trigger Example Testing

Yellow Trace: GPIO (B0) showing ADC sampling period of 20ms (50Hz), it’s double the measured signal’s frequency because we’re toggling the pin once every ADC conversion interrupt so the signal’s period = 2 ADC conversion cycles.

Blue Trace: the LED PWM output signal.

Required Parts For STM32 Examples

All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:

QTY.Component NameAmazon.comAliExpresseBay
1STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz)AmazonAliExpresseBay
1Nucleo-L432KC (ARM Cortex-M4 @ 80MHz)AmazonAliExpresseBay
1ST-Link V2 DebuggerAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1Micro USB CableAmazonAliExpresseBay

★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.

Wrap Up

In conclusion, we’ve explored how to set up the STM32 ADC to be triggered by a hardware timer module to achieve periodic ADC conversions without CPU intervention. Using this technique any ADC sampling rate can be easily achieved. This works for regular and/or injected ADC channels in any mode you’d like to use. You can also use interrupts or DMA to handle the ADC conversion completion events. For high ADC sampling rate applications, the DMA will be a much better choice than the interrupt-based reading scheme.

You can build on top of the examples provided in this tutorial and/or explore the other parts of the STM32 ADC tutorials series for more information about the other STM32 ADC operating modes and conversion schemes.

This Tutorial is Part of The Following Multi-Part Tutorial Series:

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment