STM32 ADC Injected Channel Conversion Mode With Example

In this tutorial, we’ll discuss the STM32 ADC Injected Channel Conversion Mode, what makes it different from regular ADC channels, when to consider using an ADC channel as a regular vs injected, and how to configure the STM32 ADC injected channel to trigger on various events.

The practical example we’ll implement in this tutorial is an STM32 power LED dimmer (10W/12v) with shunt resistor current measurement. The driving PWM signal will be configured as center-aligned, and the current measurement ADC channel will be an injected channel with a timer trigger in the middle of the PWM HIGH period. Without further ado, let’s get right into it!

Table of Contents

  1. STM32 ADC Injected Channel Conversion Mode
  2. STM32 ADC Injected Channel Conversion Example Project
  3. STM32 ADC Injected Channel With PWM Trigger Example
  4. Wrap Up

STM32 ADC Injected Channel Conversion Mode

The STM32 ADC gives you, the system designer/programmer, the option to set several analog input channels as “injected channels”. A channel can either be configured as a regular or injected channel at any given time. When configured as an injected ADC channel, it’ll have a higher priority than regular channels and can also suspend any ongoing regular channel conversion when the injected channel/group is triggered.

Below is an example diagram showing you a system where ADC1 is configured to have a regular group (CH0 to CH3) being converted while an injected channel (CH7) is triggered from a hardware source. The ADC suspends the ongoing conversion of the regular channels group, CH1 conversion is omitted, the injected CH7 is immediately sampled and converted, and then the regular group conversion is resumed starting from CH1 which was interrupted at the time of triggered-injection has occurred.

STM32 ADC Injected Channel Conversion Mode

The STM32F103xx, for example, can have up to 16 regular channels as well as up to 4 injected channels per ADC module. This number will vary from one target microcontroller to another, so you need to refer to the MCU’s datasheet to know its actual capabilities.

STM32 ADC Injected Vs Regular Channels

Here is a summary of the features that differentiate the injected channels from regular channels. This may be the answer to your question “Should I configure my channel as a regular or injected channel for XYZ application?”. The injected ADC channels will have the following features:

  • High priority and the ability to suspend an ongoing regular channel conversion to start the inject channel’s conversion immediately upon receiving the trigger signal.
  • Dedicated result buffer registers for every injected channel (4 buffers in the STM32F103xx devices, i.e.). Regular channels share only one buffer, so they can overwrite each other if you’re not using a DMA.

STM32 ADC Auto-Injection Vs Triggered-Injection

The injected ADC channels/group can be configured to be “Triggered” using a configurable trigger source or “Auto” injected after the completion of a regular group conversion process.

Triggered-Injection

In the triggered-injection mode: The injected channel/group starts conversion immediately when a configured trigger source is fired (it can be a timer, EXTI pin, or any other trigger source). If an external injected trigger occurs during the regular group channel conversion, the current conversion is reset and the injected channel sequence is converted in Scan once mode.

Then, the regular group channel conversion is resumed from the last interrupted regular conversion. If a regular event occurs during an injected conversion, it doesn’t interrupt it but the regular sequence is executed at the end of the injected sequence.

Auto-Injection

In the auto-injection mode: the injected group channels are automatically converted after the regular group channels. This can be used to convert a sequence of up to 20 conversions, given that we can have up to 16 regular channels + up to 4 injected channels (in STM32F103xx devices).

STM32 ADC Injected Channels Applications (Use Cases)

The STM32 ADC injected channels conversion is considered a bit more advanced feature that can only be useful when you’re building an advanced application that really requires the features of injected channels over regular ADC channels.

Here we’ll discuss a couple of example projects (use cases) where we can incorporate the STM32 ADC injected channels conversion feature to solve real-world problems that could not have been solved otherwise. Where we need to have a high-priority ADC conversion with specific triggering configurations. This is exactly where the injected mode really shines.

Application #1

The first application example for using ADC injected channels is the 3-phase current measurement for the ESC design shown in the project linked below. In which, I’m using dual shunt resistors to read the phase currents (IU, IV, IW) of a PMSM motor. The current measurement has to be triggered only when the low-side MOSFETs are conducting (turned ON). Reading the ADC channels anytime else will result in meaningless values that’ll cause the system to fail.

The time window for the phase current measurement is changing in width as the 3-phase PWM signals change in terms of the duty cycle. Therefore, we need to use the PWM’s timer to generate a trigger for the ADC in such a way that makes the injected channels start the conversion when the PWM signal going to the low-side MOSFET is HIGH.

STM32 ESC PCB Design (FOC ESC For BLDC Motors)

This article will give more in-depth information about the hardware design of an STM32-based ESC board for BLDC & PMSM motor drive applications.

Application #2

(This is the project we’ll implement in this tutorial)

Another example use case for the ADC injected channel mode is reading the DC current of a high-power LED with a shunt resistor. The ADC injected channel will be hooked up to the shunt resistor to read the voltage developed on it (only while the driver transistor is turned ON). The ADC injected channel has to be triggered when the PWM signal going to the driver BJT is HIGH only.

Can we build this system using a regular channel? Of course, we can. A regular ADC channel triggered by a timer in the middle of the PWM’s HIGH period will do the job. However, we’ll use the ADC’s injected channel mode instead to showcase it!

❕ Note

The STM32 ADC Injected channel conversion mode is a bit more complex to use than regular ADC channels as you’ll see in the example project for this tutorial. Make sure your application really needs it before you consider using an ADC channel as injected instead of a regular one.


STM32 ADC Injected Channel Conversion Example Project

In this example project, we’ll use an STM32 microcontroller to control the brightness of a high-power LED (10W/12v) while monitoring the DC current going through the LED. For this application, we’ll set up a center-aligned PWM output signal to control a BJT that drives the LED on and off.

We’ll use a shunt power resistor (1Ω) to measure the current going through the load by reading the voltage developed across the shunt resistor’s terminals. Below is a simplified diagram showing you an overview of the system we’ll be building today.

STM32-ADC-Injected-Channel-Conversion-Mode-Example-With-PWM-Center-Aligned-Trigger-For-Current-Measurement

The voltage on the shunt resistor will reflect the current going through the load as we all know. But this is only valid while the BJT transistor is conducting or in other words: during the PWM’s HIGH poriod. That’s why we need to set up the PWM in center-aligned mode, and configure the ADC analog input channel as injected channel with a timer trigger to start the ADC conversion at the middle of the PWM’s HIGH period.

STM32-PWM-Center-Aligned-Triggering-ADC-Injected-Channel

We’ll add a regular ADC channel to read a potentiometer that will be used for controlling the LED’s brightness. We’ll also add a UART serial output to send the measured load current to the PC over the serial port for visualization and validation. And that’s everything we’re going to implement in this project.

Example Project Steps Summary:

  • Set up a new project with a system clock @ 72MHz
  • Set up an Analog input pin (Channel 7) in Regular Continuous-Conversion Mode (for the potentiometer).
  • Set up an Analog input pin (Channel 4) in Injected Discontinuous-Conversion Mode With Timer2 TRGO event as a trigger source (for the shunt resistor current measurement).
  • Set up Timer2 in PWM mode with output on channel 2 (The BJT driver control pin).
  • Set up Timer2 with output on channel 1 (OC1 set it as TRGO trigger output event).
  • Set up a GPIO pin as an output pin, so we can toggle it in the injected ADC’s ISR to check the timing of the trigger compared to the PWM output signal.
  • Set up the UART1 module in TX (Asynchronous) mode to print the measured current messages over the serial port to the PC.

STM32 ADC Injected Channel With PWM Trigger Example

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 in continuous conversion mode. Enable Channel-4 as an injected channel in discontinuous mode with Timer2 TRGO event as a trigger source. In the NVIC tab, enable the ADC1 global interrupt.

STM32-ADC-Injected-Channel-Mode-Configuration-CubeMX

Step #3

For Timer2, we’ll enable PWM output on CH2 and output compare with no output on CH1. The PWM output mode will be set as Center-Aligned mode1.

We’ll set the ARR register (MAX PWM period) to 4095 just to match the ADC’s resolution so we can write the potentiometer reading directly as a duty cycle for the PWM output. Finally, choose the TRGO event to be “OC1 Event“. And that’s all about it.

STM32-PWM-Center-Aligned-Trigger-For-ADC-Injected-Channel

Step #4

Configure UART1 To Operate @115200bps in TX-only mode (Asynchronous). Which will be used to send messages over the serial port to the PC.

STM32-DC-Current-Measurement-UART-Configuration

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.

STM32-Blue-Pill-Proteus-Library-Simulation-Clock-Configuration

Step #7

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

Step #8

In the STM32CubeIDE project navigator, right-click the project’s name, and select properties. We need to do the following configuration to enable printing floating-point variables using the STDIO sprintf() function.

STM32-ADC-Injected-Mode-PWM-Center-Aligned-Example-Current-Measurement

STM32 ADC Injected Channel With PWM Trigger Example Code

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

STM32 ADC Timer Trigger Example Testing

There are so many things going on in the demo video that you need to keep your eye on. Here is a brief description of what each element is doing in this footage:

Yellow Trace: GPIO (B1) showing the ADC trigger timing relative to the PWM signal. This is not ideal of course as we’re toggling the pin in the injected ADC channel’s ISR after the completion of the conversion not at the time of the trigger’s arrival. But it’s close enough to validate what we’ve designed the system for.

Blue Trace: the center-aligned PWM output signal that drives the BJT to control the power LED’s brightness.

Multimeter: Measures the DC current going through the power LED.

Serial Monitor: It shows the UART messages sent from the STM32 microcontroller that displays the DC current measured by the microcontroller’s ADC from the shunt resistor with the injected channel configuration that’s triggered in the middle of the PWM HIGH period.

❕ Note

We should acknowledge that the measured current in the given code is technically called the “instantaneous current” not the DC current going through the load. To get that DC current measurement, we need to integrate the measured instantaneous current over time. This can be done in hardware (using a capacitor or integrator circuit) or in software (by implementing a digital integrator).

This part has been omitted from the given example code to make it much simpler and easier to skim through the code. You can modify the given code to match your needs anyway.


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
2BreadBoardAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1PotentiometersAmazonAliExpresseBay
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 injected-channel conversion with a selectable trigger source. We’ve also discussed the differences between regular vs injected ADC channels and when to consider using each of them. The great flexibility and options given by the STM32 ADC’s hardware make it so powerful but also more complex to set it up the way you want or make you wonder which mode is the best for my XYZ application.

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
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 Reply