{"id":1443,"date":"2023-01-01T04:05:44","date_gmt":"2023-01-01T04:05:44","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1443"},"modified":"2023-01-01T04:05:48","modified_gmt":"2023-01-01T04:05:48","slug":"getting-started-with-stm32f103-adc-multi-channel-continuous-conversion-mode-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1443","title":{"rendered":"Getting Started with STM32F103: ADC Multi Channel Continuous Conversion Mode with DMA"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-1024x768.jpeg\" alt=\"\" class=\"wp-image-1444\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-1024x768.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-300x225.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-768x576.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-1536x1152.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-2048x1536.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-1150x863.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-750x563.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-400x300.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_56488870-250x188.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1437\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1437\" target=\"_blank\">here<\/a>), we took a look how to configure the ADC to work in continuous mode with single channel attached. In this guide we shall use DMA to acquire ADC data from two channels using DMA.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<p><\/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>Required parts, schematics and connection<\/li><li>Configuring the ADC and DMA<\/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<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Required parts and connection:<\/h2>\n\n\n\n<p>The following are required:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F103C8.<\/li><li>2x 10KOhm potentiometer.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"957\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-1024x957.png\" alt=\"\" class=\"wp-image-1445\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-1024x957.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-300x280.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-768x718.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-1536x1435.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-1150x1075.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-750x701.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-400x374.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM-250x234.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.25.23-AM.png 1708w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">4. Configuring ADC and DMA:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by setting PA0 and PA1 as analog input:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable clock access:<\/li><\/ul>\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 GPIOA\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPAEN;<\/pre><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>Set PA0 and PA1 to analog mode:<\/li><\/ul>\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 PA0 to analog Mode*\/\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF0;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE0;\n\n\n\t\/*Set PA1 to analog Mode*\/\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF1;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE1;\n<\/pre><\/div>\n\n\n\n<p>Thats all for the pins section.<\/p>\n\n\n\n<p>Now, we shall configure the ADC:<\/p>\n\n\n\n<p>We start off by enabling clock access to the 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>Set trigger mode to be software trigger:<\/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 the trigger to be software mode*\/\n\tADC1-&gt;CR2 |= (7UL &lt;&lt; ADC_CR2_EXTSEL_Pos);<\/pre><\/div>\n\n\n\n<p>Enable continuous 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;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\/*Enable Continuous mode *\/\n\n\tADC1-&gt;CR2|=ADC_CR2_CONT;<\/pre><\/div>\n\n\n\n<p>Since we need multiple channel, we shall set scan bit in CR1 (Control Register 1) to 1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"374\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-1024x374.png\" alt=\"\" class=\"wp-image-1446\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-1024x374.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-300x110.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-768x281.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-1536x562.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-2048x749.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-1150x420.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-750x274.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-400x146.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.38.02-AM-250x91.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>Also, enable DMA mode in CR2:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"374\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-1024x374.png\" alt=\"\" class=\"wp-image-1447\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-1024x374.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-300x110.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-768x281.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-1536x562.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-2048x749.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-1150x420.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-750x274.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-400x146.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.39.20-AM-250x91.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;}\">\/*Enable DMA for ADC*\/\nADC1-&gt;CR2|=ADC_CR2_DMA;<\/pre><\/div>\n\n\n\n<p>In scan mode, we need to tell the ADC the length of the sequence to be converted, which is in this case is 2:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"546\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-1024x546.png\" alt=\"\" class=\"wp-image-1448\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-1024x546.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-300x160.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-768x409.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-1536x819.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-2048x1092.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-1150x613.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-750x400.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-400x213.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.40.33-AM-250x133.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, we can set the length to two 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;}\">#define ADC_Channels \t0x01\n\t\/*Set length to 2*\/\n\tADC1-&gt;SQR1|=(ADC_Channels&lt;&lt;ADC_SQR1_L_Pos);<\/pre><\/div>\n\n\n\n<p>Then we shall set the sequence to be channel0 then channel1 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"318\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-1024x318.png\" alt=\"\" class=\"wp-image-1449\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-1024x318.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-300x93.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-768x239.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-1536x478.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-2048x637.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-1150x358.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-750x233.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-400x124.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.43.30-AM-250x78.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;}\">#define ADC_CH0\t\t\t0x00 \/\/PA0\n#define ADC_CH1\t\t\t0x01 \/\/PA1\n\n\t\/*Sample sequence\n\t * PA0 then PA1\n\t * *\/\n\tADC1-&gt;SQR3|=(ADC_CH0&lt;&lt;ADC_SQR3_SQ1_Pos)|(ADC_CH1&lt;&lt;ADC_SQR3_SQ2_Pos);<\/pre><\/div>\n\n\n\n<p>Thats the configuration for ADC for now, noticed that we haven&#8217;t yet enable it since we need to configure the DMA before launching the ADC.<\/p>\n\n\n\n<p>For the DMA Configuration, we need first to enable clock access to DMA 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;}\">\t\/*Enable Clock access to DMA1*\/\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;<\/pre><\/div>\n\n\n\n<p>From DMA1 request map in reference manual, we find that DMA1_Channel1 is responsible for ADC1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"471\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-1024x471.png\" alt=\"\" class=\"wp-image-1450\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-1024x471.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-300x138.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-768x353.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-1536x706.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-2048x942.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-1150x529.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-750x345.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-400x184.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.46.48-AM-250x115.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>After that, the channel configuration as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Memory and peripheral size to 16-bit (half word).<\/li><li>Memory increment mode.<\/li><li>Circular mode.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"950\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-1024x950.png\" alt=\"\" class=\"wp-image-1451\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-1024x950.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-300x278.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-768x713.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-1536x1425.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-2048x1900.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-1150x1067.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-750x696.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-400x371.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-01-at-6.49.28-AM-250x232.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;}\">\tDMA1_Channel1-&gt;CCR|=DMA_CCR_MSIZE_0|DMA_CCR_PSIZE_0|DMA_CCR_MINC\n\t\t\t|DMA_CCR_CIRC;<\/pre><\/div>\n\n\n\n<p>Set number if transfers to be 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;}\">DMA1_Channel1-&gt;CNDTR=2;<\/pre><\/div>\n\n\n\n<p>Set the peripheral address to be 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;}\">DMA1_Channel1-&gt;CPAR=(uint32_t)(&amp;ADC1-&gt;DR);<\/pre><\/div>\n\n\n\n<p>Set the memory address to be the array of two that will hold the ADC values:<\/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;}\">DMA1_Channel1-&gt;CMAR=(uint32_t)(adc_data);<\/pre><\/div>\n\n\n\n<p>One last step before final step is to  enable the DMA 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;}\">DMA1_Channel1-&gt;CCR|=DMA_CCR_EN;<\/pre><\/div>\n\n\n\n<p>Finally, enable the ADC and start conversion:<\/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;}\">\/*Power up the adc*\/\n\tADC1-&gt;CR2|=ADC_CR2_ADON;\n\n\t\/*Wait a little bit*\/\n\n\tfor (int i=0;i&lt;1000;i++);\n\t\/*Launch the ADC*\/\n\tADC1-&gt;CR2|=ADC_CR2_ADON;\n\n\t\/*Launch the ADC conversion*\/\n\tADC1-&gt;CR2|=ADC_CR2_SWSTART;<\/pre><\/div>\n\n\n\n<p>And while loop is empty<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\n\n\n\n<p>Hence, the code 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;}\">#include &quot;stm32f1xx.h&quot;\n\n\n\nuint16_t adc_data[2];\n\n#define ADC_Channels \t0x01\n\n#define ADC_CH0\t\t\t0x00 \/\/PA0\n#define ADC_CH1\t\t\t0x01 \/\/PA1\n\n\nint main()\n{\n\t\/*Enable clock access to GPIOA*\/\n\t\/\/enable clock access to GPIOA\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPAEN;\n\t\/*Set PA0 to analog Mode*\/\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF0;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE0;\n\n\n\t\/*Set PA1 to analog Mode*\/\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF1;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE1;\n\n\n\n\t\/*Enable clock access to ADC1*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_ADC1EN;\n\n\t\/*Set the trigger to be software mode*\/\n\tADC1-&gt;CR2 |= (7UL &lt;&lt; ADC_CR2_EXTSEL_Pos);\n\n\t\/*Enable Continuous mode *\/\n\n\tADC1-&gt;CR2|=ADC_CR2_CONT;\n\n\t\/*Enable scan mode*\/\n\tADC1-&gt;CR1|=ADC_CR1_SCAN;\n\n\t\/*Enable DMA for ADC*\/\n\tADC1-&gt;CR2|=ADC_CR2_DMA;\n\n\t\/*Set length to 2*\/\n\tADC1-&gt;SQR1|=(ADC_Channels&lt;&lt;ADC_SQR1_L_Pos);\n\n\t\/*Sample sequence\n\t * PA0 then PA1\n\t * *\/\n\tADC1-&gt;SQR3|=(ADC_CH0&lt;&lt;ADC_SQR3_SQ1_Pos)|(ADC_CH1&lt;&lt;ADC_SQR3_SQ2_Pos);\n\n\t\/*DMA Related stuff*\/\n\n\t\/*Enable Clock access to DMA1*\/\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;\n\n\t\/*DMA1_Channel1 is for ADC1*\/\n\n\tDMA1_Channel1-&gt;CCR|=DMA_CCR_MSIZE_0|DMA_CCR_PSIZE_0|DMA_CCR_MINC\n\t\t\t|DMA_CCR_CIRC;\n\n\tDMA1_Channel1-&gt;CNDTR=2;\n\n\tDMA1_Channel1-&gt;CPAR=(uint32_t)(&amp;ADC1-&gt;DR);\n\n\tDMA1_Channel1-&gt;CMAR=(uint32_t)(adc_data);\n\n\tDMA1_Channel1-&gt;CCR|=DMA_CCR_EN;\n\n\t\/*Power up the adc*\/\n\tADC1-&gt;CR2|=ADC_CR2_ADON;\n\n\t\/*Wait a little bit*\/\n\n\tfor (int i=0;i&lt;1000;i++);\n\t\/*Launch the ADC*\/\n\tADC1-&gt;CR2|=ADC_CR2_ADON;\n\n\t\/*Launch the ADC conversion*\/\n\tADC1-&gt;CR2|=ADC_CR2_SWSTART;\n\n\n\n\t\/*Blink PC13 to demonstrates DMA capabilities*\/\n\t\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPCEN;\n\n\tGPIOC-&gt;CRH|=GPIO_CRH_MODE13;\n\tGPIOC-&gt;CRH&amp;=~(GPIO_CRH_CNF13);\n\n\n\n\twhile(1)\n\t{\n\t\tGPIOC-&gt;ODR^=GPIO_ODR_ODR13;\n\t\tfor(int i=0;i&lt;100000;i++);\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Multichannel ADC with DMA on STM32F103\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/w-5O5lzzD-Y?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/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 how to configure the ADC to work in continuous mode with single channel attached. In this guide we shall use DMA to acquire ADC data from two channels using DMA. In this guide, we shall cover the following: What is DMA Why should we use DMA [&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-1443","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\/1443"}],"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=1443"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1443\/revisions"}],"predecessor-version":[{"id":1452,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1443\/revisions\/1452"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}