{"id":1504,"date":"2023-01-25T04:23:30","date_gmt":"2023-01-25T04:23:30","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1504"},"modified":"2023-01-25T04:23:34","modified_gmt":"2023-01-25T04:23:34","slug":"getting-started-with-stm32f103-uart-receiver-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1504","title":{"rendered":"Getting Started with STM32F103: UART Receiver with DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"724\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-1024x724.jpeg\" alt=\"\" class=\"wp-image-1419\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-1024x724.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-300x212.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-768x543.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-1536x1086.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-2048x1448.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-1150x813.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-750x530.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-400x283.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/AdobeStock_316544570-1-250x177.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1415\" target=\"_blank\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1415\">here<\/a>), we took a look how to configure the UART to receive a character using interrupt and echo back the received character. In this guide, we shall use DMA to recieve data.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable DMA for RX in UART.<\/li><li>Configure the DMA.<\/li><li>Receive data using DMA.<\/li><li>Code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Enable DMA for RX in UART:<\/h2>\n\n\n\n<p>We shall continue from the polling mode from <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1395\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1395\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>To enable Receiver in DMA mode, we need to set DMAR in CR3 (Control register 3) of USART2 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"259\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-1024x259.png\" alt=\"\" class=\"wp-image-1505\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-1024x259.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-300x76.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-768x194.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-1536x388.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-2048x517.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-1150x290.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-750x189.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-400x101.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.06.38-AM-250x63.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Make sure that the UART is disable 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;}\">\tUSART2-&gt;CR1 &amp;= ~USART_CR1_UE;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Configure the DMA:<\/h2>\n\n\n\n<p>Before we start configuring the DMA, we need to enable clock access to it. To find which bus the DMA is connected to, we need to check the block diagram of STM32F103 in the datasheet which states that DMA is connected to AHB bus:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"542\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-1024x542.png\" alt=\"\" class=\"wp-image-1421\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-1024x542.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-300x159.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-768x407.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-1536x814.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-2048x1085.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-1150x609.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-750x397.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-400x212.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.34.32-AM-250x132.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, we can enable it 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;}\">RCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;<\/pre><\/div>\n\n\n\n<p>Then we need to know which channel is for UART2_TX, from the reference manual, we can find that channel6 is responsible for USART2_RX:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"463\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-1024x463.png\" alt=\"\" class=\"wp-image-1506\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-1024x463.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-300x136.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-768x347.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-1536x694.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-2048x925.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-1150x520.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-750x339.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-400x181.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.10.54-AM-250x113.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, the channel shall be configured as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Memory increment mode.<\/li><li>Direction is read from peripheral.<\/li><li>Circular mode<\/li><li>Transfer Complete interrupt.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"343\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-1024x343.png\" alt=\"\" class=\"wp-image-1507\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-1024x343.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-300x101.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-768x257.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-1536x515.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-2048x686.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-1150x385.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-750x251.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-400x134.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-25-at-7.12.28-AM-250x84.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/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_Channel6-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_CIRC|DMA_CCR_TCIE;<\/pre><\/div>\n\n\n\n<p>Since we enabled the transfer complete interrupt, we shall enable it in the NVIC also 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;}\">NVIC_EnableIRQ(DMA1_Channel6_IRQn);<\/pre><\/div>\n\n\n\n<p>Set the peripheral address to be USART2-&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;}\">\t\/*Set the peripheral address to be USART2-&gt;DR*\/\n\tDMA1_Channel6-&gt;CPAR=(uint32_t)&amp;USART2-&gt;DR;<\/pre><\/div>\n\n\n\n<p>Set the memory address to be the data to be hold:<\/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 rc_data_size 5\nuint8_t rc_data[rc_data_size];\n\nDMA1_Channel6-&gt;CMAR=(uint32_t)rc_data;<\/pre><\/div>\n\n\n\n<p>Number of transfer to be the size of the array:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">DMA1_Channel6-&gt;CNDTR=rc_data_size;<\/pre><\/div>\n\n\n\n<p>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_Channel6-&gt;CCR|=DMA_CCR_EN;<\/pre><\/div>\n\n\n\n<p>Finally enable the UART:<\/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 UART\nUSART2-&gt;CR1 |= USART_CR1_UE;<\/pre><\/div>\n\n\n\n<p>For the interrupt handler:<\/p>\n\n\n\n<p>First check if the source transfer completed, if it is true, set done to 1 and clear the pending flag 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;}\">\nvoid DMA1_Channel6_IRQHandler(void)\n{\n\tif(DMA1-&gt;ISR &amp;DMA_ISR_TCIF6)\n\t{\n\t\tdone=1;\n\t\tDMA1-&gt;IFCR=DMA_IFCR_CTCIF6;\n\t}\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Receive Data using DMA:<\/h2>\n\n\n\n<p>In while 1 loop, just wait for done to 1 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;}\">while(done==0);<\/pre><\/div>\n\n\n\n<p>Once all characters are received, print them:<\/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;}\">printf(&quot;Received data:\\&quot;%s\\&quot;\\r\\n&quot;,rc_data);<\/pre><\/div>\n\n\n\n<p>reset done back to zero:<\/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;}\">done=0;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Code:<\/h2>\n\n\n\n<p>The entire 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#include &quot;stdio.h&quot;\n\n\n#define Perpher_CLK 8000000\n#define Baudrate\t115200\n\n\n\nstatic uint16_t compute_uart_bd(uint32_t PeriphClk, uint32_t BaudRate)\n{\n\treturn ((PeriphClk + (BaudRate\/2U))\/BaudRate);\n}\n\n\nstatic void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk,  uint32_t BaudRate)\n{\n\tUSARTx-&gt;BRR =  compute_uart_bd(PeriphClk,BaudRate);\n}\n\n\n\n\n\nvoid uart2_write(int ch)\n{\n  \/*Make sure the transmit data register is empty*\/\n\twhile(!(USART2-&gt;SR &amp; USART_SR_TXE)){}\n\n  \/*Write to transmit data register*\/\n\tUSART2-&gt;DR\t=  (ch &amp; 0xFF);\n}\n\n\/*Retargeting printf*\/\nint __io_putchar(int ch){uart2_write(ch); return ch;}\n\n\n#define rc_data_size 5\nuint8_t rc_data[rc_data_size];\n\nvolatile uint8_t done=0;\n\n\nint main(void)\n{\n\n\t\/*UART2 Pin configures*\/\n\n\t\/\/enable clock access to GPIOA\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPAEN;\n\t\/\/Enable clock access to alternate function\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_AFIOEN;\n\n\t\/*Confgiure PA2 as output maximum speed to 50MHz\n\t * and alternate output push-pull mode*\/\n\tGPIOA-&gt;CRL|=GPIO_CRL_MODE2;\n\n\tGPIOA-&gt;CRL|=GPIO_CRL_CNF2_1;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF2_0;\n\n\n\t\/*Configure PA3 as Input floating*\/\n\n\t\/*Set mode to be input*\/\n\tGPIOA-&gt;CRL &amp;=~(GPIO_CRL_MODE3);\n\tGPIOA-&gt;CRL|=GPIO_CRL_CNF3_0;\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_CNF3_1;\n\n\n\n\n\t\/*Don't remap the pins*\/\n\tAFIO-&gt;MAPR&amp;=~AFIO_MAPR_USART2_REMAP;\n\n\n\t\/*USART2 configuration*\/\n\n\t\/\/enable clock access to USART2\n\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_USART2EN;\n\n\t\/\/Transmit Enable\n\tUSART2-&gt;CR1 |= USART_CR1_TE;\n\n\t\/\/Enable receiver\n\tUSART2-&gt;CR1 |= USART_CR1_RE;\n\n\n\t\/*Enable DMA for receiver*\/\n\tUSART2-&gt;CR3|=USART_CR3_DMAR;\n\n\t\/*Set baudrate *\/\n\tuart_set_baudrate(USART2,Perpher_CLK,Baudrate);\n\n\t\/*DMA configuration*\/\n\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;\n\n\tDMA1_Channel6-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_CIRC|DMA_CCR_TCIE;\n\n\tNVIC_EnableIRQ(DMA1_Channel6_IRQn);\n\n\t\/*Set the peripheral address to be USART2-&gt;DR*\/\n\tDMA1_Channel6-&gt;CPAR=(uint32_t)&amp;USART2-&gt;DR;\n\n\tDMA1_Channel6-&gt;CMAR=(uint32_t)rc_data;\n\n\tDMA1_Channel6-&gt;CNDTR=rc_data_size;\n\n\tDMA1_Channel6-&gt;CCR|=DMA_CCR_EN;\n\n\n\t\/\/Enable UART\n\tUSART2-&gt;CR1 |= USART_CR1_UE;\n\n\n\n\twhile(1)\n\t{\n\t\twhile(done==0);\n\t\tprintf(&quot;Received data:\\&quot;%s\\&quot;\\r\\n&quot;,rc_data);\n\t\tdone=0;\n\n\n\t}\n}\n\nvoid DMA1_Channel6_IRQHandler(void)\n{\n\tif(DMA1-&gt;ISR &amp;DMA_ISR_TCIF6)\n\t{\n\t\tdone=1;\n\t\tDMA1-&gt;IFCR=DMA_IFCR_CTCIF6;\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Demo:<\/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-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Full Duplex UART using DMA on STM32L053\" width=\"1170\" height=\"878\" src=\"https:\/\/www.youtube.com\/embed\/vp9bwbstzps?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\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 UART to receive a character using interrupt and echo back the received character. In this guide, we shall use DMA to recieve data. In this guide, we shall cover the following: Enable DMA for RX in UART. Configure the DMA. Receive data [&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-1504","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\/1504"}],"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=1504"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1504\/revisions"}],"predecessor-version":[{"id":1508,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1504\/revisions\/1508"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}