{"id":3007,"date":"2024-11-17T04:13:36","date_gmt":"2024-11-17T04:13:36","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3007"},"modified":"2024-11-17T04:13:38","modified_gmt":"2024-11-17T04:13:38","slug":"getting-started-with-stm32h5-arm-cortex-m33-adc-multi-channel-continuous-conversion-with-dma-and-timer-trigger","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3007","title":{"rendered":"Getting Started with STM32H5 ARM Cortex M33: ADC Multi Channel Continuous Conversion with DMA and Timer Trigger"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"725\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-1024x725.webp\" alt=\"\" class=\"wp-image-3008\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-1024x725.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-300x212.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-768x544.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-750x531.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-400x283.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3-250x177.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/STM32-u5-1-1-3.webp 1141w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In the previous guide (<a href=\"https:\/\/blog.embeddedexpert.io\/?p=2994\" data-type=\"link\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2994\">here<\/a>), we took a look at why we should use DMA to acquire data from ADC in multichannel and let the ADC trigger itself each time the conversion is completed. In this guide, we shall use timer to trigger the ADC to start the conversion which will allow the ADC to sample at fixed interval depending on the requirement of your application.<\/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>Continuous conversion vs timer triggered.<\/li>\n\n\n\n<li>STM32CubeMX setup.<\/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. Continuous Conversion vs Timer Triggered: <\/h2>\n\n\n\n<p>The&nbsp;<strong>difference between timer-triggered ADC and continuous conversion ADC<\/strong>&nbsp;in STM32H5 lies in how and when ADC conversions are initiated, and their respective use cases. Here\u2019s a detailed comparison:<\/p>\n\n\n\n<p><strong>1. Continuous Conversion Mode<\/strong><\/p>\n\n\n\n<p>In&nbsp;<strong>continuous conversion mode<\/strong>, the ADC keeps converting data continuously without any external trigger after a single start command.<\/p>\n\n\n\n<p><strong>How It Works:<\/strong><\/p>\n\n\n\n<p>\u2022 The ADC is started, and it automatically begins a new conversion as soon as the previous one finishes.<\/p>\n\n\n\n<p>\u2022 No external trigger or timer is needed.<\/p>\n\n\n\n<p>\u2022 Conversion is governed by the ADC clock and internal settings like sampling time.<\/p>\n\n\n\n<p><strong>Advantages:<\/strong><\/p>\n\n\n\n<p>\u2022 <strong>Simple implementation<\/strong>: Easy to configure and use.<\/p>\n\n\n\n<p>\u2022 <strong>Real-time updates<\/strong>: Ideal for monitoring analog signals that change continuously, like temperature or voltage.<\/p>\n\n\n\n<p>\u2022 <strong>Low latency<\/strong>: Results are updated as fast as the ADC can operate.<\/p>\n\n\n\n<p><strong>Disadvantages:<\/strong><\/p>\n\n\n\n<p>\u2022 <strong>Uncontrolled timing<\/strong>: The sampling rate is constant but not synchronized to external events.<\/p>\n\n\n\n<p>\u2022 <strong>High power consumption<\/strong>: Continuous operation may consume more power, especially if results are not always needed.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<p>\u2022 Applications that require&nbsp;<strong>high-speed, continuous signal sampling<\/strong>, such as waveform monitoring.<\/p>\n\n\n\n<p>\u2022 Systems where precise timing of conversions is not critical.<\/p>\n\n\n\n<p><strong>2. Timer-Triggered Conversion Mode<\/strong><\/p>\n\n\n\n<p>In&nbsp;<strong>timer-triggered mode<\/strong>, an external timer or other peripheral triggers the ADC to start a conversion at specific intervals.<\/p>\n\n\n\n<p><strong>How It Works:<\/strong><\/p>\n\n\n\n<p>\u2022 A timer (e.g., TIMx) generates a trigger signal at a fixed frequency.<\/p>\n\n\n\n<p>\u2022 The ADC conversion starts only when the trigger signal occurs.<\/p>\n\n\n\n<p>\u2022 The timer determines the sampling frequency, ensuring synchronization.<\/p>\n\n\n\n<p><strong>Advantages:<\/strong><\/p>\n\n\n\n<p>\u2022 <strong>Precise timing<\/strong>: Conversions are synchronized with the timer, providing deterministic sampling intervals.<\/p>\n\n\n\n<p>\u2022 <strong>Event-driven operation<\/strong>: ADC only converts data when triggered, saving power compared to continuous mode.<\/p>\n\n\n\n<p>\u2022 <strong>Flexibility<\/strong>: Can synchronize ADC with other peripherals or external events.<\/p>\n\n\n\n<p><strong>Disadvantages:<\/strong><\/p>\n\n\n\n<p>\u2022 <strong>Slightly complex setup<\/strong>: Requires configuration of both the timer and the ADC trigger.<\/p>\n\n\n\n<p>\u2022 <strong>Latency<\/strong>: ADC waits for a timer trigger, which could introduce latency in systems requiring immediate conversion.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<p>\u2022 Applications requiring&nbsp;<strong>regular sampling at precise intervals<\/strong>, such as data acquisition systems.<\/p>\n\n\n\n<p>\u2022 Synchronizing ADC sampling with events like PWM signals or communication protocols.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. STM32CubeMX Setup:<\/h2>\n\n\n\n<p>Open adc_single.ioc file as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"572\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1024x572.jpg\" alt=\"\" class=\"wp-image-2963\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1024x572.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-300x167.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-768x429.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1536x857.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-2048x1143.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-1150x642.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-750x419.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-400x223.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-10-30_15-35-13-250x141.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next from the ADC1 parameters setting, disable continuous conversion mode as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-811x1024.jpg\" alt=\"\" class=\"wp-image-3009\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-811x1024.jpg 811w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-238x300.jpg 238w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-768x969.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-1217x1536.jpg 1217w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-1150x1451.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-750x946.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-400x505.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57-250x315.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-23-57.jpg 1558w\" sizes=\"(max-width: 811px) 100vw, 811px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, In External Trigger conversion source:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the source to be TIM8 Trigger out even.<\/li>\n\n\n\n<li>Edge is set to rising edge.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1005\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-1005x1024.jpg\" alt=\"\" class=\"wp-image-3010\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-1005x1024.jpg 1005w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-294x300.jpg 294w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-768x783.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-1507x1536.jpg 1507w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-2009x2048.jpg 2009w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-1150x1172.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-750x764.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-400x408.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-24-58-250x255.jpg 250w\" sizes=\"(max-width: 1005px) 100vw, 1005px\" \/><\/figure>\n\n\n\n<p>This will allow the ADC to be triggered using timer8 of STM32H5.<\/p>\n\n\n\n<p>Next from clock configuration, we need to find the frequencies of the timers:<\/p>\n\n\n\n<p>By default, STM32H563Zi is running at 32MHz. Hence, the timers are 32MHz in speed.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"502\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1024x502.jpg\" alt=\"\" class=\"wp-image-3011\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1024x502.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-300x147.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-768x376.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1536x753.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-2048x1004.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1150x564.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-750x368.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-400x196.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-250x123.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>After we got the frequency, from pinout and configuration, select timers and tim8 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"909\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-1024x909.jpg\" alt=\"\" class=\"wp-image-3012\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-1024x909.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-300x266.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-768x682.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-1536x1363.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-2048x1818.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-1150x1021.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-750x666.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-400x355.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-26-38-250x222.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Enable the timer by setting clock source to be internal as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"905\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-1024x905.jpg\" alt=\"\" class=\"wp-image-3013\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-1024x905.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-300x265.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-768x679.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-1536x1358.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-1150x1017.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-750x663.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-400x354.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10-250x221.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-27-10.jpg 1984w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Configure the timer with the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Prescaller value of 32000-1 which will reduce the speed to 1KHz.<\/li>\n\n\n\n<li>The counter period to 1000-1 which will give us 1 second.<\/li>\n\n\n\n<li>Trigger event selection to update event.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"851\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-851x1024.jpg\" alt=\"\" class=\"wp-image-3014\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-851x1024.jpg 851w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-249x300.jpg 249w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-768x924.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-1277x1536.jpg 1277w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-1150x1384.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-750x902.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-400x481.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01-250x301.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-01.jpg 1536w\" sizes=\"(max-width: 851px) 100vw, 851px\" \/><\/figure>\n\n\n\n<p>Also, from System Core NVIC, make sure that ADC1 and GPDMA1 Channel 0 interrupts are enabled.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"742\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-1024x742.jpg\" alt=\"\" class=\"wp-image-3015\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-1024x742.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-300x217.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-768x556.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-1536x1113.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-1150x833.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-750x543.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-400x290.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40-250x181.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-28-40.jpg 1888w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Thats all for the STM32CubeMX setup.<\/p>\n\n\n\n<p>Save the project and this will generate the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Firmware Development:<\/h2>\n\n\n\n<p>In main.c file, in user code begin PV (Private variable), declare the following variable as volatile:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">volatile uint8_t adc_done;<\/pre><\/div>\n\n\n\n<p>In STM32H5xx_hal_adc.c source file, there is a function that can be called each time the ADC generate interrupt as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"714\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1024x714.jpg\" alt=\"\" class=\"wp-image-2966\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1024x714.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-300x209.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-768x536.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1536x1071.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-2048x1428.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-1150x802.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-750x523.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-400x279.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-03_06-47-52-250x174.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The function called:<\/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;&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)<\/pre><\/div>\n\n\n\n<p>This function shall be called each time when the ADC finish conversion.<\/p>\n\n\n\n<p>In user code begin 4 (at the end of main.c), we shall declare the function as following:<\/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;&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\tadc_done=1;\n\n}<\/pre><\/div>\n\n\n\n<p>This function shall only set the adc_done to 1 to indicate that the ADC finished conversion.<\/p>\n\n\n\n<p>In user code begin 2 in the main function:<\/p>\n\n\n\n<p>Start timer8 in base mode to generate the timing event only as following:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">HAL_TIM_Base_Start(&amp;htim8);<\/pre><\/div>\n\n\n\n<p>Launch the ADC in DMA mode similar to the previous guide:<\/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;&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, (uint32_t)&amp;adc_value, 2);<\/pre><\/div>\n\n\n\n<p>In user code begin 3 in while 1 loop, we can print the result when the ADC finishes conversion as following:<\/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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">if(adc_done==1)\n{\n  for (uint16_t i=0;i&lt;2;i++)\n  {\n    printf(&quot;ADC Value[%d] =%d\\r\\n&quot;,i,adc_value[i]);\n  }\n  adc_done=0;\n}<\/pre><\/div>\n\n\n\n<p>Check if the adc_done is set to 1 which means there is new data, if there is, print the new data and set the variable to 0. This will print the results only when the ADC has finished conversion of all channels.<\/p>\n\n\n\n<p>Thats all for the firmware.<\/p>\n\n\n\n<p>Save, build and run the project on your board as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"28\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-1024x28.jpg\" alt=\"\" class=\"wp-image-3016\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-1024x28.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-300x8.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-768x21.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-1536x43.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-1150x32.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-750x21.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-400x11.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3-250x7.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-07-12_15-03-3.jpg 1734w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results:<\/h2>\n\n\n\n<p>Open your favourite serial terminal application and set the baudrate to be 115200 and you should get the following to be printed each 1 second:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"733\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-1024x733.jpg\" alt=\"\" class=\"wp-image-3017\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-1024x733.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-1150x823.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-750x537.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-400x286.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-35-26.jpg 1168w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at why we should use DMA to acquire data from ADC in multichannel and let the ADC trigger itself each time the conversion is completed. In this guide, we shall use timer to trigger the ADC to start the conversion which will allow the ADC to [&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-3007","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\/3007"}],"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=3007"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3007\/revisions"}],"predecessor-version":[{"id":3018,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3007\/revisions\/3018"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3007"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3007"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}