{"id":409,"date":"2021-09-13T05:01:50","date_gmt":"2021-09-13T05:01:50","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=409"},"modified":"2021-09-13T05:01:54","modified_gmt":"2021-09-13T05:01:54","slug":"working-with-stm32-and-uart-part-4-sending-strings-using-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=409","title":{"rendered":"Working with STM32 and UART part 4: Sending Strings using DMA"},"content":{"rendered":"\n<p>In the pervious part (from <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=341\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=341\" target=\"_blank\">here<\/a>), we took a look how to send string in UART using polling mode. <\/p>\n\n\n\n<p>In polling mode, we forced the cpu to send the string character by character using software. In this guide, we shall use DMA (Direct Memory Access) to send the string.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"259\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-1.jpg\" alt=\"\" class=\"wp-image-342\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-1.jpg 441w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-1-300x176.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-1-400x235.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/UART-BUS-between-two-devices-1-250x147.jpg 250w\" sizes=\"(max-width: 441px) 100vw, 441px\" \/><figcaption>UART<\/figcaption><\/figure><\/div>\n\n\n\n<p>In this guide, we will cover the following<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Configure UART for DMA TX<\/li><li>Configure DMA<\/li><li>DMA Send <\/li><li>Code<\/li><li>Result<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1 Configure UART for DMA TX<\/h2>\n\n\n\n<p>In order to configure UART to use DMA, we need to enable the DMA Transmission bit in Control Register 3 (CR3).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"290\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-1024x290.png\" alt=\"\" class=\"wp-image-410\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-1024x290.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-300x85.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-768x218.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-1536x435.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-2048x580.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-1150x326.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-750x213.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-400x113.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.25.14-AM-250x71.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;}\"> USART2-&gt;CR3 |= (1&lt;&lt;7);            \/* enable USART2 transmitter DMA *\/<\/pre><\/div>\n\n\n\n<p>hence, the UART Initialization will be 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;}\">\/*  Initialize UART pins, Baudrate\n    The USART2 is configured to send output to pin PA2 at 9600 Baud.\n *\/\nvoid USART2_init (void) {\n    RCC-&gt;AHB1ENR |= 1;          \/* enable GPIOA clock *\/\n    RCC-&gt;APB1ENR |= 0x20000;    \/* enable USART2 clock *\/\n\n    \/* Configure PA2 for USART2_TX *\/\n    GPIOA-&gt;AFR[0] &amp;= ~0x0F00;\n    GPIOA-&gt;AFR[0] |=  0x0700;   \/* alt7 for USART2 *\/\n    GPIOA-&gt;MODER  &amp;= ~0x0030;\n    GPIOA-&gt;MODER  |=  0x0020;   \/* enable alternate function for PA2 *\/\n\n    USART2-&gt;BRR = 0x0683;       \/* 9600 baud @ 16 MHz *\/\n    USART2-&gt;CR1 = 0x0008;       \/* enable Tx, 8-bit data *\/\n    USART2-&gt;CR2 = 0x0000;       \/* 1 stop bit *\/\n    USART2-&gt;CR3 = 0x0000;       \/* no flow control *\/\n    USART2-&gt;CR1 |= 0x2000;      \/* enable USART2 *\/\n    USART2-&gt;CR3 |= (1&lt;&lt;7);            \/* enable USART2 transmitter DMA *\/\n    USART2-&gt;SR = ~0x40;         \/* clear TC flag *\/\n    USART2-&gt;CR1 |= 0x0040;      \/* enable transmit complete interrupt *\/\n\n    NVIC_EnableIRQ(USART2_IRQn);    \/* USART2 interrupt enable at NVIC *\/\n}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.1  DMA Initialization<\/h2>\n\n\n\n<p>Before we enable clock access, we need to know which DMA and which channel to use in order to use DMA for UART TX.<\/p>\n\n\n\n<p>From DMA section from reference manual of STM32F411, we conclude the we need to use DMA1 Stream6 and channel 4<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"528\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-1024x528.png\" alt=\"\" class=\"wp-image-411\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-1024x528.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-300x155.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-768x396.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-1536x792.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-2048x1056.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-1150x593.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-750x387.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-400x206.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.29.10-AM-250x129.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>First we start by enabling clock access to DMA1 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;AHB1ENR |= RCC_AHB1ENR_DMA1EN;     \/* DMA controller clock enable *\/<\/pre><\/div>\n\n\n\n<p>Then we clear all pending interrupts of DMA1_Stream 6 (HIFCR)<\/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-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/<\/pre><\/div>\n\n\n\n<p>Finally enable interrupt for DMA1_Stream6<\/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;}\">\nNVIC_EnableIRQ(DMA1_Stream6_IRQn);  \/* DMA interrupt enable at NVIC *\/<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.2 DMA Configuration to send data<\/h2>\n\n\n\n<p>First we need clear the Transmission Complete interrupt from status register of USART2 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;}\">USART2-&gt;SR &amp;= ~USART_SR_TC;          \/* clear UART transmit complete interrupt flag *\/<\/pre><\/div>\n\n\n\n<p>Then we disable the stream and wait until the stream is 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;}\">DMA1_Stream6-&gt;CR &amp;= ~1;         \/* disable DMA1 Stream 6 *\/\n while (DMA1_Stream6-&gt;CR &amp; 1) {} \/* wait until DMA1 Stream 6 is disabled *\/<\/pre><\/div>\n\n\n\n<p>We clear the interrupt flags of DMA1_Stream6<\/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-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/<\/pre><\/div>\n\n\n\n<p>Then we set the destination 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;}\">DMA1_Stream6-&gt;PAR = dst;<\/pre><\/div>\n\n\n\n<p>Setting the source 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;}\">DMA1_Stream6-&gt;M0AR = src;<\/pre><\/div>\n\n\n\n<p>Setting how many number of bytes to send 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;}\">DMA1_Stream6-&gt;NDTR = len;<\/pre><\/div>\n\n\n\n<p>Now we choose channel 4 <\/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_Stream6-&gt;CR = 0x08000000;  \/* USART2_TX on DMA1 Stream6 Channel 4 *\/<\/pre><\/div>\n\n\n\n<p>now we select memory size, memory inc and memory to peripheral 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;}\">DMA1_Stream6-&gt;CR |= 0x00000440; \/* data size byte, mem incr, mem-to-peripheral *\/<\/pre><\/div>\n\n\n\n<p>Now we need to enable some interrupt <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Transfer complete interrupt enable<\/li><li>Transfer error interrupt enable<\/li><li>Direct mode error interrupt enable<\/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;}\">DMA1_Stream6-&gt;CR |= 0x16;       \/* enable interrupts DMA_IT_TC | DMA_IT_TE | DMA_IT_DME *\/<\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"345\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-1024x345.png\" alt=\"\" class=\"wp-image-412\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-1024x345.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-300x101.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-768x259.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-1536x518.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-2048x690.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-1150x388.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-750x253.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-400x135.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-7.43.50-AM-250x84.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Finally we enable the DMA 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;}\">DMA1_Stream6-&gt;CR |= 1;          \/* enable DMA1 Stream 6 *\/<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">2.3 Interrupt handler<\/h2>\n\n\n\n<p>For interrupt handler. For DMA, in case of error it will halt the entire mcu and for UART if the TC is triggered , we inform the application that the transmission is finished<\/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 Stream6 interrupt handler\n    This function handles the interrupts from DMA1 controller Stream6. The error interrupts \n    have a placeholder for error handling code. If the interrupt is from DMA data\n    transfer complete, the DMA controller is disabled, the interrupt flags are\n    cleared.\n *\/\nvoid DMA1_Stream6_IRQHandler(void)\n{\n    if (DMA1-&gt;HISR &amp; 0x000C0000)    \/* if an error occurred *\/\n        while(1) {}                 \/* substitute this by error handling *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    DMA1_Stream6-&gt;CR &amp;= ~0x10;      \/* disable DMA1 Stream 6 TCIE *\/\n}\n\n\/*  USART2 interrupt handler\n *  USART2 transmit complete interrupt is used to set the done flag to signal\n *  the other part of the program that the data transfer is done.\n *\/\nvoid USART2_IRQHandler(void)\n{\n    USART2-&gt;SR &amp;= ~0x0040;          \/* clear transmit complete interrupt flag *\/\n    done = 1;                       \/* set the done flag *\/\n\t\n}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code<\/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\n#include &quot;string.h&quot;\n#include &quot;stdio.h&quot;\nvoid USART2_init(void);\nvoid DMA1_init(void);\nvoid DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len);\nint variable;\nint done = 1;\nchar c[]=&quot;hello from stm32f411re \\r\\n&quot;;\nchar message[sizeof(c)];\n    \n\n\nvoid delayMs(int delay)\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\n\nint main (void) {\n \n    \n\n    \n    USART2_init();\n    DMA1_init();\n    \n    while (1) {\n\t\t\t\n\t\t\tint i;\n    int size = strlen(c);\n        \/* prepare the message for transfer *\/\n\t\t\t\n        for (i = 0; i &lt; size; i++)\n            message[i] = c[i];\n        \n        \/* send the message out by USART2 using DMA *\/\n        while (done == 0) {}    \/* wait until DMA data transfer is done *\/\n        done = 0;               \/* clear done flag *\/\n        DMA1_Stream6_setup((unsigned int)message, (unsigned int)&amp;USART2-&gt;DR, size);\n\t\t\t\t\t\t\t\t\t\n    }\n}\n\/*  Initialize UART pins, Baudrate\n    The USART2 is configured to send output to pin PA2 at 9600 Baud.\n *\/\nvoid USART2_init (void) {\n    RCC-&gt;AHB1ENR |= 1;          \/* enable GPIOA clock *\/\n    RCC-&gt;APB1ENR |= 0x20000;    \/* enable USART2 clock *\/\n\n    \/* Configure PA2 for USART2_TX *\/\n    GPIOA-&gt;AFR[0] &amp;= ~0x0F00;\n    GPIOA-&gt;AFR[0] |=  0x0700;   \/* alt7 for USART2 *\/\n    GPIOA-&gt;MODER  &amp;= ~0x0030;\n    GPIOA-&gt;MODER  |=  0x0020;   \/* enable alternate function for PA2 *\/\n\n    USART2-&gt;BRR = 0x0683;       \/* 9600 baud @ 16 MHz *\/\n    USART2-&gt;CR1 = 0x0008;       \/* enable Tx, 8-bit data *\/\n    USART2-&gt;CR2 = 0x0000;       \/* 1 stop bit *\/\n    USART2-&gt;CR3 = 0x0000;       \/* no flow control *\/\n    USART2-&gt;CR1 |= 0x2000;      \/* enable USART2 *\/\n    USART2-&gt;CR3 |= (1&lt;&lt;7);            \/* enable USART2 transmitter DMA *\/\n    USART2-&gt;SR = ~0x40;         \/* clear TC flag *\/\n    USART2-&gt;CR1 |= 0x0040;      \/* enable transmit complete interrupt *\/\n\n    NVIC_EnableIRQ(USART2_IRQn);    \/* USART2 interrupt enable at NVIC *\/\n}\n\n\n\/*  Initialize DMA1 controller\n *  DMA1 controller's clock is enabled and also the DMA interrupt is \n *  enabled in NVIC.\n *\/\nvoid DMA1_init(void) {\n    RCC-&gt;AHB1ENR |= RCC_AHB1ENR_DMA1EN;     \/* DMA controller clock enable *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    \n    \n\t\n    NVIC_EnableIRQ(DMA1_Stream6_IRQn);  \/* DMA interrupt enable at NVIC *\/\n}\n\n\/*  Set up a DMA transfer for USART2 \n *  The USART2 is connected to DMA1 Stream 6. This function sets up the \n *  peripheral register address, memory address, number of transfers,\n *  data size, transfer direction, and DMA interrupts are enabled.\n *  At the end, the DMA controller is enabled and the USART2 transmit\n *  DMA is enabled.\n *\/\nvoid DMA1_Stream6_setup(unsigned int src, unsigned int dst, int len) {\n\t\n\t\tUSART2-&gt;SR &amp;= ~USART_SR_TC;          \/* clear UART transmit complete interrupt flag *\/\n\t\n    DMA1_Stream6-&gt;CR &amp;= ~1;         \/* disable DMA1 Stream 6 *\/\n    while (DMA1_Stream6-&gt;CR &amp; 1) {} \/* wait until DMA1 Stream 6 is disabled *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    DMA1_Stream6-&gt;PAR = dst;\n    DMA1_Stream6-&gt;M0AR = src;\n    DMA1_Stream6-&gt;NDTR = len;\n    DMA1_Stream6-&gt;CR = 0x08000000;  \/* USART2_TX on DMA1 Stream6 Channel 4 *\/\n    DMA1_Stream6-&gt;CR |= 0x00000440; \/* data size byte, mem incr, mem-to-peripheral *\/\n    DMA1_Stream6-&gt;CR |= 0x16;       \/* enable interrupts DMA_IT_TC | DMA_IT_TE | DMA_IT_DME *\/\n    \/\/DMA1_Stream6-&gt;FCR  = 0;         \/* direct mode, no FIFO *\/\n    DMA1_Stream6-&gt;CR |= 1;          \/* enable DMA1 Stream 6 *\/\n\n\t\t\t\n\t\t\t\n\t\t\t\n}\n\n\/*  DMA1 Stream6 interrupt handler\n    This function handles the interrupts from DMA1 controller Stream6. The error interrupts \n    have a placeholder for error handling code. If the interrupt is from DMA data\n    transfer complete, the DMA controller is disabled, the interrupt flags are\n    cleared.\n *\/\nvoid DMA1_Stream6_IRQHandler(void)\n{\n    if (DMA1-&gt;HISR &amp; 0x000C0000)    \/* if an error occurred *\/\n        while(1) {}                 \/* substitute this by error handling *\/\n    DMA1-&gt;HIFCR = 0x003F0000;       \/* clear all interrupt flags of Stream 6 *\/\n    DMA1_Stream6-&gt;CR &amp;= ~0x10;      \/* disable DMA1 Stream 6 TCIE *\/\n}\n\n\/*  USART2 interrupt handler\n *  USART2 transmit complete interrupt is used to set the done flag to signal\n *  the other part of the program that the data transfer is done.\n *\/\nvoid USART2_IRQHandler(void)\n{\n    USART2-&gt;SR &amp;= ~0x0040;          \/* clear transmit complete interrupt flag *\/\n    done = 1;                       \/* set the done flag *\/\n\t\n}\n\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results<\/h2>\n\n\n\n<p>after you compile and upload the code, you will get this<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"531\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-1024x531.png\" alt=\"\" class=\"wp-image-414\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-1024x531.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-300x156.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-768x398.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-1150x597.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-750x389.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-400x208.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM-250x130.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-13-at-8.00.55-AM.png 1326w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In the pervious part (from here), we took a look how to send string in UART using polling mode. In polling mode, we forced the cpu to send the string character by character using software. In this guide, we shall use DMA (Direct Memory Access) to send the string. In this guide, we will cover [&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-409","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\/409"}],"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=409"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions"}],"predecessor-version":[{"id":415,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions\/415"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}