In this tutorial, we’ll discuss how the STM32 Internal Analog Comparator works, and how to use the STM32 Comparator with the timer in input capture mode for signal measurement. The STM32 comparator’s output can be externally and/or internally routed to different peripherals which opens the door for a wide range of applications and design ideas as we shall see in this tutorial.
The practical example project we’ll implement in this tutorial will be a very good starting point for your STM32 Comparator-based project. Without further ado, let’s get right into it!
Table of Contents
- STM32 Comparator
- STM32 Comparator Example (With Interrupt + Timer ICU)
- STM32 Comparator + Timer Input Capture Project
- Wrap Up
STM32 Comparator
The STM32 comparator peripheral is a hardware analog comparator integrated inside the STM32 microcontroller itself. This analog comparator can be configured to operate in different modes which makes it so flexible and suitable for a wide range of applications.
STM32 Internal Analog Comparator Main Features
- Each comparator has configurable (Vin+ & Vin-) inputs used for flexible voltage selection: (Multiplexed I/O pins, DAC CH1 & CH2, Internal reference voltage, and three submultiple values (1/4, 1/2, 3/4) provided by scaler (buffered voltage divider)
- Programmable hysteresis
- Programmable speed/consumption
- The outputs can be redirected to an I/O or to timer inputs for triggering & Break events for fast PWM shutdowns
- Comparator outputs with blanking source
- The two comparators can be combined in a window comparator
- Each comparator has interrupt generation capability with wake-up from Sleep and Stop modes (through the EXTI controller)
STM32 Internal Analog Comparator Functional Description
Let’s now discuss the detailed functionality of the STM32 internal analog comparators, how they work, and what are the possible configurations and operating modes for the analog comparators.
1. STM32 Analog Comparator Block Diagram & Pins
This is the block diagram for the STM32 analog comparators showing its input signal sources and output internal routing options.
The I/Os used as comparator inputs must be configured in analog mode in the GPIO registers. The comparator output can be connected to the I/Os using the alternate function channel given in the “Alternate function mapping” table in the datasheet. The output can also be internally redirected to a variety of timer inputs for the following purposes:
- Emergency shut-down of PWM signals, using BKIN and BKIN2 inputs
- Cycle-by-cycle current control, using OCREF_CLR inputs
- Input capture for timing measures
It is possible to have the comparator output simultaneously redirected internally and externally.
2. STM32 Analog Comparator Hysteresis
The STM32 analog comparator includes a programmable hysteresis to avoid aggressive fluctuating output transitions in case of noisy input signals.
3. STM32 Analog Comparator (Window Comparartor) Mode
Two embedded comparators can be utilized to create a window comparator. The monitored analog voltage is connected to the non-inverting (Vin+) inputs of comparators connected together and the upper and lower threshold voltages are connected to the inverting (Vin-) inputs of the comparators.
STM32 Comparator Applications
The STM32 analog comparator can be used in so many applications just like a standalone analog comparator but it’s integrated inside the microcontroller itself. Here are some common applications for the integrated STM32 analog comparator peripheral:
- Sensors Interfacing
- Signal Conditioning
- Analog Voltage Monitoring
- ZCD (Zero-Crossing Detectors)
- Motor driver applications
- Oscillator / Timing Applications
- and much more…
STM32 Comparator Example (With Interrupt + Timer ICU)
In this example project, we’ll set up the STM32 internal analog comparator to compare the (Vin+), which is coming from a signal generator, against the internal (Vref/4 = 0.825v). Therefore the comparator’s digital output will toggle on the zero-crossing points of the input sinusoidal waveform.
We’ll internally route the comparator’s output (rising edges) as a trigger source for Timer1 which will operate in “input capture” mode. Therefore, an input capture event will be fired on the rising edges of the signal. By taking 2 time stamps for every consecutive ICU event, we’ll easily be able to find out the input signal’s period (T) and, consequently solve for the frequency (F = 1/T).
The resulting frequency measurement will be printed on an I2C LCD. Below is a functional and connection diagram that shows you how this project is working and how things are wired up.
Example Project Diagram
Example Project Steps Summary:
- Set up a new project, system clock, and enable SWD (serial wire debug)
- Set up 1x Analog Comparator
- Set up 1x Timer in ICU mode with trigger source (COMP1_OUT)
- Set up 1x I2C communication port @ standard speed for interfacing with the I2C_LCD16x2
Highly Recommended References Needed For This Project:
This article will give you more in-depth information about the STM32 I2C LCD 16×2 library, how it works, and how to integrate it into your projects.
This article will give you more in-depth information about the STM32 Timer modules input capture mode with a frequency counter project example showing you how to set up an ICU for signal frequency measurement.
STM32 Comparator + Timer Input Capture Project
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
Enable COMP1 with IN+, external output pin, and (IN- = Vref/4)
Step #3
Enable Timer1 in Trigger Mode with ICU on CH1 with the configurations shown below.
Enable Timer1 overflowe (update) interrupt & input chapture1 interrupt as well.
Step #4
Enable the I2C1 peripheral with the default settings as is.
Step #5
Set up system clock, and enable SWD (serial wire debug).
Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.
Step #6
Integrate the I2C_LCD16x2 library as explained in this STM32 I2C_LCD16x2 Tutorial.
STM32 Analog Comparator + Timer Input Capture Example Code
Here is The Application Code For This LAB (main.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
/* * LAB Name: STM32 Analog Comparator + Timer Input Capture Example * Author: Khaled Magdy * For More Info Visit: www.DeepBlueMbedded.com */ #include "main.h" #include <stdio.h> #include "../../ECUAL/I2C_LCD/I2C_LCD.h" #define IDLE 0 #define DONE 1 #define F_CLK 80000000UL #define MyI2C_LCD I2C_LCD_1 COMP_HandleTypeDef hcomp1; TIM_HandleTypeDef htim1; I2C_HandleTypeDef hi2c1; volatile uint8_t State = IDLE; volatile uint32_t T1 = 0; volatile uint32_t T2 = 0; volatile uint32_t Ticks = 0; volatile uint16_t TIM1_OVC = 0; volatile uint32_t Freq = 0; char FreqString[16] = {'\0'}; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_COMP1_Init(void); static void MX_TIM1_Init(void); static void MX_I2C1_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_COMP1_Init(); MX_TIM1_Init(); MX_I2C1_Init(); HAL_COMP_Start(&hcomp1); HAL_TIM_Base_Start_IT(&htim1); HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); I2C_LCD_Init(MyI2C_LCD); while (1) { if(Freq != 0) { sprintf(FreqString, "%lu Hz", Freq); I2C_LCD_Clear(MyI2C_LCD); I2C_LCD_SetCursor(MyI2C_LCD, 0, 0); I2C_LCD_WriteString(MyI2C_LCD, "Measured Frequency:"); I2C_LCD_SetCursor(MyI2C_LCD, 0, 1); I2C_LCD_WriteString(MyI2C_LCD, FreqString); HAL_Delay(300); } } } void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) { if(State == IDLE) { T1 = TIM1->CCR1; TIM1_OVC = 0; State = DONE; } else if(State == DONE) { T2 = TIM1->CCR1; Ticks = (T2 + (TIM1_OVC * 65536)) - T1; Freq = (uint32_t)(F_CLK/Ticks); State = IDLE; } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) { TIM1_OVC++; } |
STM32 Comparator Frequency Measurement Example Testing
The function generator is sending a sine waveform to the STM32 (Comp. IN+ pin). In my test setup, the COMP_OUT digital pin is plotted on the scope’s Yellow Trace, and the input sinusoidal waveform is shown on the Blue Trace.
The measured signal’s frequency is displayed on the I2C_LCD by the STM32 microcontroller.
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 Name | Amazon.com | AliExpress | eBay |
1 | I2C LCD 16×2 Display | Amazon | AliExpress | eBay |
1 | STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz) | Amazon | AliExpress | eBay |
1 | Nucleo-L432KC (ARM Cortex-M4 @ 80MHz) | Amazon | AliExpress | eBay |
1 | ST-Link V2 Debugger | Amazon | AliExpress | eBay |
2 | BreadBoard | Amazon | AliExpress | eBay |
1 | LEDs Kit | Amazon & Amazon | AliExpress | eBay |
1 | Resistors Kit | Amazon & Amazon | AliExpress | eBay |
1 | Capacitors Kit | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Jumper Wires Pack | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Push Buttons | Amazon & Amazon | AliExpress | eBay |
1 | Potentiometers | Amazon | AliExpress | eBay |
1 | Micro USB Cable | Amazon | AliExpress | eBay |
★ 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 the STM32 internal Analog Comparator works, what are the possible operating modes that you can configure it to, and how to route the comparator’s output internally and/or externally and use it for measurements with timer modules or EXTI interrupts.
You can build on top of the example provided in this tutorial and/or explore all of our STM32 Tutorials.