{"id":4017,"date":"2025-12-03T14:02:25","date_gmt":"2025-12-03T14:02:25","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=4017"},"modified":"2025-12-03T14:02:49","modified_gmt":"2025-12-03T14:02:49","slug":"stm32-adc-application-part-9-differential-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=4017","title":{"rendered":"STM32 ADC Application Part\u00a010: Differential Mode"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-1024x683.png\" alt=\"\" class=\"wp-image-4029\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM-250x167.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/ChatGPT-Image-Dec-3-2025-at-04_26_23-PM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Differential mode in the STM32 ADC allows measurements based on the voltage difference between two input pins rather than a single-ended signal referenced to ground. This approach greatly improves noise immunity, increases measurement accuracy for small signals, and is ideal for applications involving sensors or signals with common-mode interference.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What is differential mode.<\/li>\n\n\n\n<li>STM32CubeMX Setup.<\/li>\n\n\n\n<li>Importing project to STM32CubeIDE.<\/li>\n\n\n\n<li>Firmware development.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is Differential Mode:<\/h2>\n\n\n\n<p>Differential mode in the STM32 ADC allows the converter to measure the voltage difference between two input pins instead of referencing all measurements to ground. This technique significantly enhances noise immunity, improves accuracy for low-level signals, and enables the ADC to reject common-mode interference that appears equally on both inputs.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Differential ADCs are generally used in applications requiring high precision, noise reduction, and increased dynamic range. In this tutorial we will specifically focus on just measuring the voltage difference between the two differential inputs. The ADC data will be based on this differential voltage, which we will later convert into the voltage.<\/p>\n\n\n\n<p>Not all the STM32 devices support differential ADC. I am going to use the STM32L476RG Nucleo board. However, some explanation will be related to 16-bit ADC.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>As mentioned in the reference manual both the differential inputs should be biased at\u00a0<strong>Vref\/2<\/strong>. The\u00a0<strong>Vref<\/strong>\u00a0is a custom reference voltage which can be provided externally, but the\u00a0<strong>hardware on the board should be configured<\/strong>\u00a0accordingly. By default the\u00a0<strong>Vref<\/strong>\u00a0is connected to the VDDA (&amp; VCC), therefore the Vref is 3.3V.<\/p>\n\n\n\n<p>Biasing means that instead of fluctuating around 0V, the signals should be centred around 1.65V.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_1.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_1.avif\" alt=\"Differential ADC explained\" class=\"wp-image-147288\" \/><\/a><\/figure>\n\n\n\n<p>We should also take care of the Common mode voltage (CMV). This&nbsp;<strong>Common-mode voltage&nbsp;<\/strong>is the average voltage of two input signals in a differential system. This voltage only has a small range in STM32. You can see it in the image from datasheet of the device.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_2.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_2.avif\" alt=\"Common mode input voltage\" class=\"wp-image-147290\" \/><\/a><\/figure>\n\n\n\n<p>You can see the common mode voltage varies by only 10% from&nbsp;<strong>Vref\/2&nbsp;<\/strong>voltage. So if the Vref is at 3.3V, the common mode voltage can vary from around 1.48 V to 1.82V.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_3.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_3.avif\" alt=\"CMV Range\" class=\"wp-image-147291\" \/><\/a><\/figure>\n\n\n\n<p>When choosing the input voltages on both the differential pairs make sure the average of both voltages lies within this range. It does not mean that it will not work outside this range rather the result outside this range is unpredictable. In certain cases it might work while in other cases it won\u2019t.<\/p>\n\n\n\n<p>The ADC will convert the voltage difference between both the input pins as per the formula shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_4.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_4.avif\" alt=\"Converted voltage\" class=\"wp-image-147292\" \/><\/a><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If the\u00a0<strong>V<sub>INN<\/sub>\u00a0= 0<\/strong>\u00a0and\u00a0<strong>V<sub>INP<\/sub>\u00a0= V<sub>REF<\/sub><\/strong>, the ADC value will be equal to the\u00a0<strong>MAXIMUM<\/strong>.\u00a0<\/li>\n\n\n\n<li>Whereas when\u00a0<strong>V<sub>INN<\/sub>\u00a0= V<sub>REF<\/sub><\/strong>\u00a0and\u00a0<strong>V<sub>INP<\/sub>\u00a0= 0<\/strong>, the ADC value will be equal to the<strong>\u00a00<\/strong>.\u00a0<\/li>\n\n\n\n<li>When\u00a0<strong>V<sub>INN<\/sub>\u00a0= V<sub>INP<\/sub><\/strong>, the ADC value will be exactly\u00a0<strong>HALF the MAXIMUM<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p>Below is the image showing the range of ADC value based on the differential inputs. The&nbsp;<strong>V<sub>DIFF<\/sub><\/strong>&nbsp;is the voltage difference between the input signals.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_5.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/03\/adc11_5.avif\" alt=\"Voltage Range\" class=\"wp-image-147293\" \/><\/a><\/figure>\n\n\n\n<p>We will write our code in such a way that the ADC&nbsp;<strong>MAXIMUM<\/strong>&nbsp;(65535) indicates a&nbsp;<strong>+3.3V<\/strong>&nbsp;while the ADC&nbsp;<strong>MINIMUM<\/strong>&nbsp;(0) indicates a&nbsp;<strong>-3.3V<\/strong>. Also the ADC&nbsp;<strong>MAX\/2<\/strong>&nbsp;(32768) will indicate&nbsp;<strong>0V<\/strong>.<\/p>\n\n\n\n<p>Reference: <a href=\"https:\/\/controllerstech.com\/stm32-adc-11-adc-differential-mode\/\" data-type=\"link\" data-id=\"https:\/\/controllerstech.com\/stm32-adc-11-adc-differential-mode\/\" target=\"_blank\" rel=\"noreferrer noopener\">Controllerstech<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. STM32CubeMX Setup:<\/h2>\n\n\n\n<p>Open STM32CubeMX as start a new project as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"662\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-1024x662.jpg\" alt=\"\" class=\"wp-image-3990\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-1024x662.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-300x194.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-768x497.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-1536x993.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-2048x1324.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-1150x744.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-750x485.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-400x259.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_11-04-37-250x162.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Search for your STM32 MCU, select the MCU and click on Start New Project as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"724\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-1024x724.jpg\" alt=\"\" class=\"wp-image-4018\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-1024x724.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-300x212.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-768x543.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-1536x1087.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-2048x1449.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-1150x814.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-750x531.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-400x283.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-15-13-250x177.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, from Analog, select ADC1 and set IN5 as differential and configure the ADC as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable Continuous Conversion.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"593\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-1024x593.jpg\" alt=\"\" class=\"wp-image-4019\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-1024x593.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-300x174.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-768x445.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-1536x889.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-2048x1185.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-1150x666.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-750x434.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-400x232.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-40-05-250x145.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, from NVIC tab, enable ADC interrupt as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"954\" height=\"874\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52.jpg\" alt=\"\" class=\"wp-image-4020\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52.jpg 954w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52-300x275.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52-768x704.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52-750x687.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52-400x366.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-42-52-250x229.jpg 250w\" sizes=\"(max-width: 954px) 100vw, 954px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, from Project manager<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Give the project a name.<\/li>\n\n\n\n<li>Set the project location.<\/li>\n\n\n\n<li>Toolchain\/IDE STM32CubeIDE.<\/li>\n\n\n\n<li>Click on generate project.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"593\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-1024x593.jpg\" alt=\"\" class=\"wp-image-4023\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-1024x593.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-300x174.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-768x445.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-1536x889.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-2048x1185.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-1150x666.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-750x434.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-400x232.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_16-43-54-2-250x145.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Thats all for STM32CubeMX configuration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Importing project to STM32CubeIDE:<\/h2>\n\n\n\n<p>Open STM32CubeIDE, select your workspace and click on Launch.<\/p>\n\n\n\n<p>From the IDE, click File and select STM32 Project Create\/Import as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"873\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1024x873.jpg\" alt=\"\" class=\"wp-image-3997\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1024x873.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-300x256.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-768x655.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-1150x981.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-750x640.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-400x341.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21-250x213.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_16-57-21.jpg 1524w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, from Import STM32 Project, select STM32CubeMX\/STM32CubeIDE Project and click on Next as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"769\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1024x769.jpg\" alt=\"\" class=\"wp-image-3998\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1024x769.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-300x225.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-768x577.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-1150x863.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-750x563.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-400x300.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37-250x188.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/11\/2025-11-26_17-00-37.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, select the folder that contains the .ioc file and click on Finish as follows:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"652\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-1024x652.jpg\" alt=\"\" class=\"wp-image-4024\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-1024x652.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-300x191.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-768x489.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-1536x977.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-1150x732.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-750x477.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-400x255.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24-250x159.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-19-24.jpg 1760w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Firmware Development:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Open main.c file<\/p>\n\n\n\n<p>In main.c file,  in user code begin PV, declare the following variables:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint16_t ADC_VAL;\nint voltage;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>ADC_VAL is the raw adc value measure by ADC in differential mode for IN5.<\/p>\n\n\n\n<p>Voltage, is the difference voltage between INP and INN.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>For ADC conversion completed function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)\n{\n\n\tADC_VAL = HAL_ADC_GetValue(&amp;hadc1);\n\tvoltage = (3300*2*ADC_VAL\/4095)-3300;\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin 2 in main function, start the ADC in interrupt mode as follows:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_ADC_Start_IT(&amp;hadc1);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Results:<\/h2>\n\n\n\n<p>Start a debugging session and add ADC_VAL and voltage to live expression.<\/p>\n\n\n\n<p>When 3.3V is applied to IN5_P and 0 to IN5_N:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"233\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-1024x233.jpg\" alt=\"\" class=\"wp-image-4025\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-1024x233.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-300x68.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-768x175.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-1150x261.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-750x171.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-400x91.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25-250x57.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-24-25.jpg 1170w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>When 3.3V is applied to IN5_N and 0 to IN5_P:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"251\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-1024x251.jpg\" alt=\"\" class=\"wp-image-4026\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-1024x251.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-300x74.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-768x188.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-1150x282.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-750x184.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-400x98.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01-250x61.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-25-01.jpg 1174w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>When 2.5V is applied to IN5_P and 2V to IN5_N:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"236\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-1024x236.jpg\" alt=\"\" class=\"wp-image-4027\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-1024x236.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-300x69.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-768x177.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-1150x265.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-750x173.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-400x92.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06-250x58.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-31-06.jpg 1170w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>When 2.5V is applied to IN5_N and 2V to IN5_P:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"210\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-1024x210.jpg\" alt=\"\" class=\"wp-image-4028\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-1024x210.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-300x62.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-768x158.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-1150x236.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-750x154.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-400x82.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28-250x51.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/12\/2025-12-03_10-34-28.jpg 1170w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Note that we are able to measure the difference between two points without any issue.<\/p>\n\n\n\n<p>Also, my function generator can provide up to 2.45 rather than 2.5V which explains less voltage than 500mV difference in both case.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Differential mode in the STM32 ADC allows measurements based on the voltage difference between two input pins rather than a single-ended signal referenced to ground. This approach greatly improves noise immunity, increases measurement accuracy for small signals, and is ideal for applications involving sensors or signals with common-mode interference. In this guide, we shall cover [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-4017","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4017"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4017"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4017\/revisions"}],"predecessor-version":[{"id":4031,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/4017\/revisions\/4031"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}