{"id":3671,"date":"2025-08-07T09:24:13","date_gmt":"2025-08-07T09:24:13","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3671"},"modified":"2025-08-07T09:24:16","modified_gmt":"2025-08-07T09:24:16","slug":"stm32-adc-application-part-8-oversampling","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3671","title":{"rendered":"STM32 ADC Application Part\u00a08: Oversampling"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1536\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM.png\" alt=\"\" class=\"wp-image-3673\" style=\"width:840px;height:auto\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-300x200.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-1024x683.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-768x512.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-1150x767.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-750x500.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-400x267.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/ChatGPT-Image-Aug-7-2025-at-11_40_10-AM-250x167.png 250w\" sizes=\"(max-width: 1536px) 100vw, 1536px\" \/><\/figure>\n\n\n\n<p>This guide focuses on implementing\u00a0<strong>ADC oversampling<\/strong>\u00a0on STM32 to improve resolution and reduce noise in analog signal acquisition. It explains the oversampling principle, hardware configuration, and how to leverage STM32&#8217;s built-in support for hardware averaging.<\/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 oversampling.<\/li>\n\n\n\n<li>STM32CubeIDE setup for non-oversampling.<\/li>\n\n\n\n<li>Setup oversampling and calculation.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is Oversampling:<\/h2>\n\n\n\n<p>Oversampling is a powerful technique used in analog-to-digital conversion to improve the effective resolution and accuracy of ADC measurements without requiring higher-resolution hardware. In STM32 microcontrollers, including the STM32F4 series, oversampling involves taking multiple samples of the input signal at a faster rate and then averaging them to produce a single result with reduced noise and enhanced precision. This is especially useful in applications where signals are noisy or require high accuracy, such as in sensor measurements or audio processing.<\/p>\n\n\n\n<p>The STM32 ADC hardware supports built-in oversampling capabilities (in some models) or it can be implemented in firmware when native support is limited. The principle relies on sampling the same analog input multiple times in quick succession and combining these readings\u2014typically through summation and division (averaging) or bit shifting\u2014to achieve a higher effective number of bits (ENOB). For instance, oversampling by a factor of 4 can theoretically increase the resolution by one extra bit. However, it&#8217;s important to ensure that the ADC input signal bandwidth is limited to avoid aliasing and that the acquisition window (sample time) is properly configured to maintain signal integrity.<\/p>\n\n\n\n<p>To enable efficient and accurate oversampling, the sampling time of each ADC channel must be carefully selected to accommodate the source impedance and allow sufficient charging time for the internal sampling capacitor. Longer sample times can stabilize slow-changing or high-impedance signals, which is crucial when multiple oversampled readings are being taken consecutively.<\/p>\n\n\n\n<p>In this guide, we\u2019ll walk through how oversampling works in theory, what configuration options are available on STM32L4 devices, and what considerations to take into account regarding timing, conversion speed, and data handling. We&#8217;ll also include a block diagram of the oversampling process and provide guidance on setting up timers and DMA for more efficient sampling. The firmware development and implementation will be covered in a dedicated section.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. STM32CubeIDE Setup for Non-oversampling:<\/h2>\n\n\n\n<p>Open STM32CubeIDE after selecting the workspace and create new project as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"355\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1024x355.jpg\" alt=\"\" class=\"wp-image-2940\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1024x355.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-300x104.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-768x266.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1536x532.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-2048x709.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-1150x398.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-750x260.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-400x139.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-26-00-250x87.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Select the MCU (Ensure that you are selecting a one with oversampling like STM32L476RG):<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"832\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1024x832.jpg\" alt=\"\" class=\"wp-image-2941\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1024x832.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-300x244.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-768x624.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1536x1248.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-2048x1664.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-1150x934.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-750x609.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-400x325.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/10\/2024-10-26_16-27-14-250x203.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Give the project a name:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"813\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-813x1024.jpg\" alt=\"\" class=\"wp-image-3674\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-813x1024.jpg 813w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-238x300.jpg 238w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-768x968.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-750x945.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-400x504.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49-250x315.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_09-49-49.jpg 984w\" sizes=\"(max-width: 813px) 100vw, 813px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Once the project has been created, STM32CubeMX window shall appear.<\/p>\n\n\n\n<p>In Clock configuration, increase the system frequency to maximum and increase ADC clock to high value as follows (For STM32L476RG):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"641\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-1024x641.jpg\" alt=\"\" class=\"wp-image-3675\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-1024x641.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-300x188.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-768x480.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-1536x961.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-2048x1281.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-1150x719.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-750x469.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-400x250.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-49-23-250x156.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, Configure the ADC as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable any channel in single ended (Not all STM32 supports differential ADC input).<\/li>\n\n\n\n<li>Set conversion mode to continuous.<\/li>\n\n\n\n<li>Enable DMA continuous request (After enabling the DMA).<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"839\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-1024x839.jpg\" alt=\"\" class=\"wp-image-3676\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-1024x839.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-300x246.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-768x629.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-1536x1258.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-1150x942.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-750x614.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-400x328.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23-250x205.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-52-23.jpg 1978w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, enable configure the DMA as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"910\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-1024x910.jpg\" alt=\"\" class=\"wp-image-3677\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-1024x910.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-300x267.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-768x683.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-1150x1022.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-750x667.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-400x356.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23-250x222.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_11-56-23.jpg 1514w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Also, enable any random pin as output (PA5 in this guide)<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for the configuration. Save the project and this will generate the project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Once the project is generated, main.c shall be opened.<\/p>\n\n\n\n<p>In main.c in user code begin PV, declare the following array:<\/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_data[100]={0};<\/pre><\/div>\n\n\n\n<p>The array shall hold 100 ADC samples (Needed to reduce the interrupt and measure time using GPIO toggle).<\/p>\n\n\n\n<p>Next, in user code begin 0 declare the following 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\t\tHAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);\n}<\/pre><\/div>\n\n\n\n<p>Once the ADC has completed the 100 sample, ADC_ConvCpltCallback shall be called, within the callback, toggle the GPIO (PA5 in this case).<\/p>\n\n\n\n<p>In user code begin 2 in main function, start the adc in the DMA mode:<\/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_DMA(&amp;hadc1, &amp;adc_data, 100);<\/pre><\/div>\n\n\n\n<p>Save, build and debug the project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Add adc_data to the live expression and you should see the array are filling with ADC values as follows:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Here, the pin is connected to 3V3 and as you can see, we are getting 4020ish which is near the 4095 full ADC range.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"868\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-868x1024.jpg\" alt=\"\" class=\"wp-image-3678\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-868x1024.jpg 868w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-254x300.jpg 254w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-768x906.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-750x885.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-400x472.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18-250x295.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-40-18.jpg 1146w\" sizes=\"(max-width: 868px) 100vw, 868px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>From the toggle pin:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"630\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4.png\" alt=\"\" class=\"wp-image-3679\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS4-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From the STM32L476 reference manual:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"344\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-1024x344.jpg\" alt=\"\" class=\"wp-image-3680\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-1024x344.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-300x101.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-768x258.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-1536x516.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-2048x688.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-1150x386.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-750x252.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-400x134.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-07-54-250x84.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>At 12-bit, the ADC need 12.5 ADC cycles to complete the conversion, also each channel requires 2.5 cycles (by default, can be changed in the configuration) which means total of 15 cycles.<\/p>\n\n\n\n<p>By doing 15\/32MHz, we get 0.468uS conversion time, since we are filling 100 samples, the time needed is 46.8 which is as shown in the oscilloscope screenshot.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Setup Oversampling and Calculation:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Open ADC_Oversample.ioc from project explorer and configure the ADC as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Enable oversampling.<\/li>\n\n\n\n<li>Set shift right to 2bit.<\/li>\n\n\n\n<li>Oversampling ratio to 64<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"288\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-1024x288.jpg\" alt=\"\" class=\"wp-image-3683\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-1024x288.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-300x84.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-768x216.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-1150x323.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-750x211.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-400x112.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34-250x70.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_12-13-34.jpg 1494w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>To calculate the effective number of bit, the following formula is used:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"690\" height=\"120\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_1.avif\" alt=\"\" class=\"wp-image-3681\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_1.avif 690w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_1-300x52.avif 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_1-400x70.avif 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_1-250x43.avif 250w\" sizes=\"(max-width: 690px) 100vw, 690px\" \/><\/figure>\n\n\n\n<p><a href=\"https:\/\/controllerstech.com\/wp-content\/uploads\/2025\/02\/adc9_1.avif\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><\/p>\n\n\n\n<p>X is the ADC resolution (12-bit) OSR which is oversample ration (64 in this case) and M number of shifted bits which is 2.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"585\" height=\"120\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_7.avif\" alt=\"\" class=\"wp-image-3682\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_7.avif 585w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_7-300x62.avif 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_7-400x82.avif 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/adc9_7-250x51.avif 250w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><\/figure>\n\n\n\n<p> <\/p>\n\n\n\n<p>This will give us 16-bit effective resolution.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Save the project and this will generate the project.<\/p>\n\n\n\n<p>Build the project and start a debug session and you should see the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-885x1024.jpg\" alt=\"\" class=\"wp-image-3684\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-885x1024.jpg 885w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-259x300.jpg 259w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-768x888.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-750x868.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-400x463.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49-250x289.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/2025-08-07_10-42-49.jpg 1148w\" sizes=\"(max-width: 885px) 100vw, 885px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As you can see, we are getting the 16-bit ADC resolution despite the ADC is 12-bit.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>However, this has a negative effect on the speed of the ADC.<\/p>\n\n\n\n<p>From the oscilloscope screenshot:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"630\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6.png\" alt=\"\" class=\"wp-image-3685\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6-300x185.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6-768x473.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6-750x461.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6-400x246.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2025\/08\/RigolDS6-250x154.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Note that the time has increased to 3ms to finish the 100 sample. Which means the ADC has been slowed down by a factor of 64 which is related to oversample ratio.<\/p>\n\n\n\n<p>This means, the ADC has to sample the channel 64 times before moving to the next conversion.<\/p>\n\n\n\n<p>Thats all.<\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This guide focuses on implementing\u00a0ADC oversampling\u00a0on STM32 to improve resolution and reduce noise in analog signal acquisition. It explains the oversampling principle, hardware configuration, and how to leverage STM32&#8217;s built-in support for hardware averaging. In this guide, we shall cover the following: 1. What is Oversampling: Oversampling is a powerful technique used in analog-to-digital conversion [&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-3671","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\/3671"}],"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=3671"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3671\/revisions"}],"predecessor-version":[{"id":3686,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3671\/revisions\/3686"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3671"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3671"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3671"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}