{"id":319,"date":"2021-08-12T06:01:13","date_gmt":"2021-08-12T06:01:13","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=319"},"modified":"2022-01-14T02:45:04","modified_gmt":"2022-01-14T02:45:04","slug":"working-with-adc-and-stm32-part-4-multi-channel-continuous-conversion-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=319","title":{"rendered":"Working with ADC and STM32 part 4: Multi Channel Continuous Conversion with DMA"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"323\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-1024x323.png\" alt=\"\" class=\"wp-image-320\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-1024x323.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-300x95.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-768x243.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-1150x363.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-750x237.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-400x126.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_-250x79.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/1200px-ADC_Symbol.svg_.png 1200w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>ADC Symbol <\/figcaption><\/figure>\n\n\n\n<p class=\"has-text-align-left\">In the previous ADC guides (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=200\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=200\" target=\"_blank\">part 1<\/a>, <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=224\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=224\" target=\"_blank\">part 2<\/a>, and <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=235\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=235\" target=\"_blank\">part 3<\/a>), we talked about how to configure the ADC to read a single channel in three different modes, polling, continuous with polling and interrupt. Those can be valid for simple application like temperature control of a room or heat-sink. However, in case multiple channel, ADC in interrupt is not recommended and requires careful management to acquire the data in correct sequence. This is when DMA come to solve the issue. In this guide, we shall look at the DMA and how to configure it to acquire the data from two channel.<\/p>\n\n\n\n<p>In this guide we will cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is DMA<\/li><li>Why should we use DMA when dealing with multiple channel in ADC<\/li><li>Configuring the ADC and DMA<\/li><li>Required parts, schematics and connection<\/li><li>Code<\/li><li>Result<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is DMA<\/h2>\n\n\n\n<p>DMA which stands for Direct Memory Access is part of MCU that handle data transfer from peripheral to memory without invoking CPU at all which relief cpu to do something else, like processing the acquired adc vlaue for dsp processing etc<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-1024x576.jpeg\" alt=\"\" class=\"wp-image-321\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-1024x576.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-300x169.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-768x432.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-1536x864.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-1150x647.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-750x422.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-400x225.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2-250x141.jpeg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/d5573030-464f-4801-8de7-75c126d7f9a2.jpeg 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>DMA (From digikey)<\/figcaption><\/figure>\n\n\n\n<p>DMA can be operate in three different mode, Memory to Memory (moving one variable from one location to another), memory to peripheral (send string from memory to PC through UART) and peripheral to memory like in our case acquiring data from adc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Why should we use DMA when dealing with multiple channel in ADC<\/h2>\n\n\n\n<p>Let say you want ti acquire data from adc from 3-channel in continuous mode. Since each conversion requires 15 cycles for 12-bit since the adc clock is the core frequency over (16MHz\/2=8MHz), thats means generating interrupts at rate near half mega hertz which will effect the performance of the mcu. Hence, using DMA in such case makes sense. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.1 Configure the ADC  <\/h2>\n\n\n\n<p>To configure the ADC, first we enable GPIO clock access to the required pins (PA0 and PA1) in our case<\/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&lt;br&gt;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">RCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; <\/pre><\/div>\n\n\n\n<p>then enabling adc clock<\/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;}\">RCC-&gt;APB2ENR|=RCC_APB2ENR_ADC1EN;<\/pre><\/div>\n\n\n\n<p>After than we will configure PA0 and PA1 as analog inputs and PA5 as output<\/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;}\">GPIOA-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_0|GPIO_MODER_MODE1_1|GPIO_MODER_MODE5_0;<\/pre><\/div>\n\n\n\n<p>Setting the length of conversion to be 2 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;}\">ADC1-&gt;SQR1|=(1&lt;&lt;20);<\/pre><\/div>\n\n\n\n<p>Set the sequence to be PA0 to be first and PA1 to seconds (from part 1)<\/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;}\">ADC1-&gt;SQR3=(0U&lt;&lt;0)|(1U&lt;&lt;5);<\/pre><\/div>\n\n\n\n<p>Then enable continuous conversion, dma, scan mode and let the dma to be the controller<\/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;}\">ADC1-&gt;CR1=ADC_CR1_SCAN;\n\t\nADC1-&gt;CR2|=ADC_CR2_DMA|ADC_CR2_DDS|ADC_CR2_CONT;<\/pre><\/div>\n\n\n\n<p>For now, we keep ADC disabled and enable it later <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.2 Configuring the DMA<\/h2>\n\n\n\n<p>We start by enabling DMA clock access<\/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;}\">RCC-&gt;AHB1ENR\t\t\t\t|=RCC_AHB1ENR_DMA2EN;<\/pre><\/div>\n\n\n\n<p>Then disable the channel and wait until disabled <\/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;}\">DMA2_Stream0-&gt;CR    &amp;=~DMA_SxCR_EN;\n\t\t\nwhile(DMA2_Stream0-&gt;CR ==DMA_SxCR_EN){;}<\/pre><\/div>\n\n\n\n<p>The we configure the DMA as following<\/p>\n\n\n\n<p>Setting the dma to circular mode, memory and peripheral size of 16 bit and memory increment <\/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;}\">DMA2_Stream0-&gt;CR\t\t|=DMA_SxCR_CIRC|DMA_SxCR_MSIZE_0|DMA_SxCR_PSIZE_0|DMA_SxCR_MINC;<\/pre><\/div>\n\n\n\n<p>Then selecting peripheral source to be the ADC1-&gt;DR<\/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;}\">DMA2_Stream0-&gt;PAR\t\t =(uint32_t)(&amp;(ADC1-&gt;DR));<\/pre><\/div>\n\n\n\n<p>then selecting memory location <\/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;}\">DMA2_Stream0-&gt;M0AR \t =(uint32_t )(&amp;adc_data);<\/pre><\/div>\n\n\n\n<p>Selecting how may transfer to be transferred (2 in this case)<\/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;}\">DMA2_Stream0-&gt;NDTR\t =sizeof(adc_data)\/sizeof(adc_data[0]);<\/pre><\/div>\n\n\n\n<p>Enable the stream<\/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;}\">DMA2_Stream0-&gt;CR\t\t|=DMA_SxCR_EN;<\/pre><\/div>\n\n\n\n<p>Finally enable ADC and started 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;}\">ADC1-&gt;CR2|=1;\nADC1-&gt;CR2|=ADC_CR2_SWSTART;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 Required parts<\/h2>\n\n\n\n<p>In this guide we will need the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F411RE Nucleo <\/li><li>2x 1KOhm potentiometers<\/li><li>Breadboard<\/li><li>Hookup wires<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 Connection<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"879\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-879x1024.png\" alt=\"\" class=\"wp-image-324\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-879x1024.png 879w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-257x300.png 257w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-768x895.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-1318x1536.png 1318w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-1150x1340.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-750x874.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-400x466.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM-250x291.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.53.29-AM.png 1526w\" sizes=\"(max-width: 879px) 100vw, 879px\" \/><figcaption>connection<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">5 Code and results<\/h2>\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;}\">#include &quot;stm32f4xx.h&quot;                  \/\/ Device header\nuint16_t adc_data[2]; \t                \/\/ array to hold adc_data\t\nvoid delayMs(int delay) \/\/inefficient delay for led blinking\n\n{\n\nint i;\n\nfor(; delay&gt;0 ;delay--)\n\n{\n\nfor(i =0; i&lt;3195;i++);\n\n}\n\n}\n\n\nint main(void)\n\t{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \n\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_ADC1EN; \n\t\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0|GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_0|GPIO_MODER_MODE1_1|GPIO_MODER_MODE5_0; \n\t\n\tADC1-&gt;SQR1|=(1&lt;&lt;20);\n\n\tADC1-&gt;SQR3=(0U&lt;&lt;0)|(1U&lt;&lt;5);\n\n\tADC1-&gt;CR1=ADC_CR1_SCAN;\n\t\n\tADC1-&gt;CR2|=ADC_CR2_DMA|ADC_CR2_DDS|ADC_CR2_CONT;\n\t\n\tRCC-&gt;AHB1ENR\t\t\t\t|=RCC_AHB1ENR_DMA2EN;\n\t\t\n\tDMA2_Stream0-&gt;CR    &amp;=~DMA_SxCR_EN;\n\t\t\n\twhile(DMA2_Stream0-&gt;CR ==DMA_SxCR_EN){;}\n\t\t\n\tDMA2_Stream0-&gt;CR\t\t|=DMA_SxCR_CIRC|DMA_SxCR_MSIZE_0|DMA_SxCR_PSIZE_0|DMA_SxCR_MINC;\n\t\n\tDMA2_Stream0-&gt;PAR\t\t =(uint32_t)(&amp;(ADC1-&gt;DR));\n\n\tDMA2_Stream0-&gt;M0AR \t =(uint32_t )(&amp;adc_data);\n\n\tDMA2_Stream0-&gt;NDTR\t =sizeof(adc_data);\n\n\n\tDMA2_Stream0-&gt;CR\t\t|=DMA_SxCR_EN;\t\n\n\tADC1-&gt;CR2|=1;\n\t\n\tDMA2_Stream0-&gt;CR |= (1&lt;&lt;0);  \/\/ EN =1\n\n\tADC1-&gt;CR2|=ADC_CR2_SWSTART;\n\n\n\twhile(1)\n\t\t{\n      \/\/blinking led to demonisterate the dma capability \n\t\tGPIOA-&gt;ODR^=GPIO_ODR_OD5;\n\t\tdelayMs(1000);\n\t\t}\n\t\n\t}\n\t<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"388\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-1024x388.png\" alt=\"\" class=\"wp-image-325\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-1024x388.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-300x114.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-768x291.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-1150x436.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-750x284.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-400x152.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM-250x95.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-12-at-8.52.26-AM.png 1520w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>results<\/figcaption><\/figure>\n\n\n\n<p>After you applied the code, rotate the pot and notice how they are changed without needing to update the value in the code.<\/p>\n\n\n\n<p>This is how dma works in background without effecting the cpu performance.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous ADC guides (part 1, part 2, and part 3), we talked about how to configure the ADC to read a single channel in three different modes, polling, continuous with polling and interrupt. Those can be valid for simple application like temperature control of a room or heat-sink. However, in case multiple channel, [&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-319","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\/319"}],"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=319"}],"version-history":[{"count":5,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/319\/revisions"}],"predecessor-version":[{"id":698,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/319\/revisions\/698"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}