{"id":949,"date":"2022-05-18T13:57:28","date_gmt":"2022-05-18T13:57:28","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=949"},"modified":"2022-05-18T13:57:31","modified_gmt":"2022-05-18T13:57:31","slug":"working-with-stm32f7-and-adc-part-3-multi-channel-continuous-conversion-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=949","title":{"rendered":"Working with STM32F7 and ADC part 3: Multi channel Continuous Conversion with DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"323\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-1024x323.png\" alt=\"\" class=\"wp-image-225\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-1024x323.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-300x95.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-768x243.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-1150x363.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-750x237.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-400x126.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1-250x79.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/07\/1200px-ADC_Symbol.svg_-1.png 1200w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=611\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=611\" target=\"_blank\">here<\/a>),  we took a look at single channel continuous conversion interrupt driven ADC configuration. In this guide, we shall see how to configure the ADC to work in multiple channel with DMA.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<p>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\"><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\" \/><\/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\u00a0<\/h2>\n\n\n\n<p>First thing, we need to figure out which pins to use, since here the board is used is Nucleo-144,<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"858\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-858x1024.png\" alt=\"\" class=\"wp-image-951\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-858x1024.png 858w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-251x300.png 251w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-768x916.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-1287x1536.png 1287w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-1150x1372.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-750x895.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-400x477.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM-250x298.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.28.59-PM.png 1450w\" sizes=\"(max-width: 858px) 100vw, 858px\" \/><\/figure>\n\n\n\n<p>Since we want to use A0 and A1 of arduino connector and they are PA3 and PC0<\/p>\n\n\n\n<p>To configure the ADC, first we enable GPIO clock access to the required pins PA3 and PC0 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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\/*Enable clock access to GPIOA and GPIOC*\/\nRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN;<\/pre><\/div>\n\n\n\n<p>The configure the pins as analog mode:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"656\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-1024x656.png\" alt=\"\" class=\"wp-image-952\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-1024x656.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-300x192.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-768x492.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-1536x984.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-1150x737.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-750x481.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-400x256.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM-250x160.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.33.40-PM.png 1698w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">\t\/*Configure the pins in ADC mode*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODER3;\n\tGPIOC-&gt;MODER|=GPIO_MODER_MODER0;<\/pre><\/div>\n\n\n\n<p>Now, we enable clock access to ADC1:<\/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;}\">\t\/*Enable clock access to ADC1*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_ADC1EN;<\/pre><\/div>\n\n\n\n<p>Enable scan mode to read multichannel:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"362\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-1024x362.png\" alt=\"\" class=\"wp-image-953\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-1024x362.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-300x106.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-768x271.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-1536x543.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-2048x724.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-1150x406.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-750x265.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-400x141.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.35.13-PM-250x88.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\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;}\">\t\/*Enable scan mode*\/\n\tADC1-&gt;CR1|=ADC_CR1_SCAN;<\/pre><\/div>\n\n\n\n<p>Then we set DMA, DDS, CON and set length to 2 and rank to be channel3 and channel 10 and enable the ADC. However, we shall not start the conversion yet, 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;}\">\tADC1-&gt;CR1|=ADC_CR1_SCAN;\n\t\/*Enable continuous\/ DMA and DDS*\/\n\tADC1-&gt;CR2|=ADC_CR2_CONT|ADC_CR2_DDS|ADC_CR2_DMA;\n\t\/*Set length to 2 channels*\/\n\tADC1-&gt;SQR1|=(1&lt;&lt;20);\n\t\/*Set ch3 first first and ch10 second in the conversion sequence*\/\n\tADC1-&gt;SQR3|=(3&lt;&lt;0)|(10&lt;&lt;5);\n\t\/*Enable the ADC*\/\n\tADC1-&gt;CR2|=ADC_CR2_ADON;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3.2 Configuring the DMA:<\/h2>\n\n\n\n<p>First we need to find which stream and channel to use:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"342\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-1024x342.png\" alt=\"\" class=\"wp-image-954\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-1024x342.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-300x100.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-768x256.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-1536x512.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-2048x683.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-1150x384.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-750x250.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-400x133.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.40.35-PM-250x83.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From the table, we shall use DMA2_Stream0 Channel 0:<\/p>\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;}\">\t\/*Enable clock access to DMA2*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA2EN;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Then disable the channel and wait until disabled\u00a0<\/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;}\">\t\/*Disable the strsam*\/\n\tDMA2_Stream0-&gt;CR&amp;=~DMA_SxCR_EN;\n\t\/*Wait until the stream is disabled *\/\n\twhile(DMA_SxCR_EN==(DMA2_Stream0-&gt;CR&amp;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;}\">\t\/*Set memory size to half-word*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_MSIZE_0;\n\t\/*Set peripheral size to half word*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_PSIZE_0;\n\t\/*Enable memory increment*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_MINC;\n\t\/*Enable circular mode*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_CIRC;\n\t\/*Set peripheral is the controller*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_PFCTRL;<\/pre><\/div>\n\n\n\n<p>Then selecting peripheral source to be the ADC1-&gt;DRC, set memory location to adc_data array and length to 2 <\/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;}\">\/*Set number of transfer to 2*\/\n\tDMA2_Stream0-&gt;NDTR=2;\n\t\/*Set peripheral address to ADC1-&gt;DR*\/\n\tDMA2_Stream0-&gt;PAR=(uint32_t)&amp;(ADC1-&gt;DR);\n\t\/*Set memory address to adc_data*\/\n\tDMA2_Stream0-&gt;M0AR=(uint32_t)&amp;(adc_data);\n\t\/*Enable the DMA stream*\/<\/pre><\/div>\n\n\n\n<p>Finally enable the DMA stream and start coversion:<\/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;}\">\t\/*Enable the DMA stream*\/\n\tDMA2_Stream0-&gt;CR|=DMA_SxCR_EN;\n\t\/*Start ADC conversion*\/\n\tADC1-&gt;CR2|=ADC_CR2_SWSTART;<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3.3: Getting the data:<\/h2>\n\n\n\n<p>We shall use a function that return the desired value for the specific channel:<\/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;}\">\nuint16_t ReadChannel(adc_Channel_t ch)\n\t{\n\treturn adc_data[ch];\n\t}\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3.4: Header file:<\/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;}\">\n#ifndef ADC_DMA_H_\n#define ADC_DMA_H_\n\n#include &quot;stdint.h&quot;\n\ntypedef enum\n\t\t{\n\t\tA0=0,\n\t\tA1=1\n\t\t}adc_Channel_t;\n\nvoid adc_dma_2ch_init();\nuint16_t  ReadChannel(adc_Channel_t ch);\n#endif \/* ADC_DMA_H_ *\/\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Connection:<\/h2>\n\n\n\n<p>We shall use the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F767-Nucleo-144<\/li><li>2x 1KOhm potentiometer<\/li><li>Breadboard<\/li><li>Hookup wires<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1009\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-1024x1009.png\" alt=\"\" class=\"wp-image-956\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-1024x1009.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-300x296.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-768x757.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-1536x1514.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-2048x2019.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-1150x1134.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-750x739.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-400x394.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.53.09-PM-250x246.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/ADC_DMA.zip\">ADC_DMA<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/ADC_DMA.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Results:<\/p>\n\n\n\n<p>Compile and upload the code to your board, open serial terminal and set the baudrate to 115200 and rotate the pot and you should see something similar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"721\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-1024x721.png\" alt=\"\" class=\"wp-image-958\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-1024x721.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-300x211.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-768x540.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-1150x809.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-750x528.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-400x282.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM-250x176.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/05\/Screen-Shot-2022-05-18-at-4.55.58-PM.png 1168w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we took a look at single channel continuous conversion interrupt driven ADC configuration. In this guide, we shall see how to configure the ADC to work in multiple channel with DMA. In this guide, we shall cover the following: we talked about how to configure the ADC to read a [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,11,7,12],"tags":[],"class_list":["post-949","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-peripheral-drivers","category-state-machine","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/949"}],"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=949"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/949\/revisions"}],"predecessor-version":[{"id":959,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/949\/revisions\/959"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=949"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=949"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=949"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}