{"id":1418,"date":"2022-12-21T04:53:59","date_gmt":"2022-12-21T04:53:59","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1418"},"modified":"2022-12-21T04:54:02","modified_gmt":"2022-12-21T04:54:02","slug":"getting-started-with-stm32f103-uart-transmitter-with-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1418","title":{"rendered":"Getting Started with STM32F103: UART Transmitter with DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><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><\/p>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1415\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1415\" target=\"_blank\">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 transmit 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 TX in UART.<\/li><li>Configure the DMA.<\/li><li>Send 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 TX in UART:<\/h2>\n\n\n\n<p>To enable DMA Transmit for UART, the DMAT in Control Register 3 of USART2 (USART_CR3) need to be set:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"304\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-1024x304.png\" alt=\"\" class=\"wp-image-1420\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-1024x304.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-300x89.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-768x228.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-1536x455.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-2048x607.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-1150x341.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-750x222.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-400x119.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.31.03-AM-250x74.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 DMA for TX part(DMAT)*\/\n\tUSART2-&gt;CR3|=USART_CR3_DMAT;<\/pre><\/div>\n\n\n\n<p>Thats all for UART part.<\/p>\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 size-large\"><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;}\">\t\/*Enable clock access to DMA1*\/\n\n\tRCC-&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 channel7 is responsible for USART2_TX:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"474\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-1024x474.png\" alt=\"\" class=\"wp-image-1422\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-1024x474.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-300x139.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-768x355.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-1536x711.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-2048x948.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-1150x532.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-750x347.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-400x185.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.39.21-AM-250x116.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 memory.<\/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=\"357\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-1024x357.png\" alt=\"\" class=\"wp-image-1423\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-1024x357.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-300x105.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-768x268.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-1536x535.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-2048x714.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-1150x401.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-750x261.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-400x139.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.42.23-AM-250x87.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;}\">DMA1_Channel7-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE;<\/pre><\/div>\n\n\n\n<p>Enable DMA1_Channel7 interrupt in NVIC:<\/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_Channel7_IRQn);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Set the peripheral address to be USART2-&gt;DR 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\/*Set the peripheral address to be USART2-&gt;DR*\/\n\tDMA1_Channel7-&gt;CPAR=(uint32_t)&amp;USART2-&gt;DR;<\/pre><\/div>\n\n\n\n<p>For the interrupt handler:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Check if the interrupt source is transfer complete, if it is,<\/li><li>Set done to 1.<\/li><li>Disable the DMA channel.<\/li><li>Clear the pending interrupt flag.<\/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;}\">\n\nvoid DMA1_Channel7_IRQHandler(void)\n{\n\tif((DMA1-&gt;ISR &amp;DMA_ISR_TCIF7))\n\t{\n\t\t\/*Set done to 1.*\/\n\t\tdone=1;\n\n\t\t\/*Disable DMA1_Channel7*\/\n\t\tDMA1_Channel7-&gt;CCR&amp;=~DMA_CCR_EN;\n\n\t\t\/*Clear the pending interrupt flag*\/\n\t\tDMA1-&gt;IFCR|=DMA_IFCR_CTCIF7;\n\t}\n\n}\n\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. Send data using DMA:<\/h2>\n\n\n\n<p>To send the data, We need the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Clear the pending flag.<\/li><li>Set the memory address to be the buffer to be send.<\/li><li>Set the length to be the length of the data to be send.<\/li><li>Enable the DMA channel.<\/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;}\">\nvoid uart_dma_transmit(char *data, uint16_t length)\n{\n\t\/*Clear transfer complete flag *\/\n\tDMA1-&gt;IFCR|=DMA_IFCR_CTCIF7;\n\t\/*Set the memory address to be the data buffer *\/\n\tDMA1_Channel7-&gt;CMAR=(uint32_t)data;\n\t\/*Set the number of transfer*\/\n\tDMA1_Channel7-&gt;CNDTR=length;\n\n\t\/*Enable DMA1_channel7 stream*\/\n\tDMA1_Channel7-&gt;CCR|=DMA_CCR_EN;\n\n}\n<\/pre><\/div>\n\n\n\n<p>Within while(1), we can call the function 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;}\">uint16_t len=sprintf(data_send,&quot;Counter value=%d\\r\\n&quot;,counter++);\n\t\tuart_dma_transmit(data_send,len);\n\t\twhile(done==0);\n\t\tdone=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\n#include &quot;stdio.h&quot;\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(char 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\n\nvolatile uint8_t done=0;\n\nchar data_send[100];\n\nuint8_t counter;\n\nvoid uart_dma_transmit(char *data, uint16_t length)\n{\n\t\/*Clear transfer complete flag *\/\n\tDMA1-&gt;IFCR|=DMA_IFCR_CTCIF7;\n\t\/*Set the memory address to be the data buffer *\/\n\tDMA1_Channel7-&gt;CMAR=(uint32_t)data;\n\t\/*Set the number of transfer*\/\n\tDMA1_Channel7-&gt;CNDTR=length;\n\n\t\/*Enable DMA1_channel7 stream*\/\n\tDMA1_Channel7-&gt;CCR|=DMA_CCR_EN;\n\n}\n\n\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 TX part(DMAT)*\/\n\tUSART2-&gt;CR3|=USART_CR3_DMAT;\n\n\t\/*Set baudrate *\/\n\tuart_set_baudrate(USART2,Perpher_CLK,Baudrate);\n\n\n\n\t\/* DMA Section*\/\n\n\t\/*Enable clock access to DMA1*\/\n\n\tRCC-&gt;AHBENR|=RCC_AHBENR_DMA1EN;\n\n\t\/* Configure DMA as following:\n\t * Memory increment mode.\n\t * Direction read from memory.\n\t * Transfer complete interrupt.\n\t * *\/\n\n\tDMA1_Channel7-&gt;CCR|=DMA_CCR_MINC|DMA_CCR_DIR|DMA_CCR_TCIE;\n\n\t\/*Enable DMA1_Channel interrupt in NVIC*\/\n\tNVIC_EnableIRQ(DMA1_Channel7_IRQn);\n\t\/*Set the peripheral address to be USART2-&gt;DR*\/\n\tDMA1_Channel7-&gt;CPAR=(uint32_t)&amp;USART2-&gt;DR;\n\n\t\/\/Enable UART\n\tUSART2-&gt;CR1 |= USART_CR1_UE;\n\n\n\n\twhile(1)\n\t{\n\t\tuint16_t len=sprintf(data_send,&quot;Counter value=%d\\r\\n&quot;,counter++);\n\t\tuart_dma_transmit(data_send,len);\n\t\twhile(done==0);\n\t\tdone=0;\n\n\t}\n}\n\n\nvoid DMA1_Channel7_IRQHandler(void)\n{\n\tif((DMA1-&gt;ISR &amp;DMA_ISR_TCIF7))\n\t{\n\t\t\/*Set done to 1.*\/\n\t\tdone=1;\n\n\t\t\/*Disable DMA1_Channel7*\/\n\t\tDMA1_Channel7-&gt;CCR&amp;=~DMA_CCR_EN;\n\n\t\t\/*Clear the pending interrupt flag*\/\n\t\tDMA1-&gt;IFCR|=DMA_IFCR_CTCIF7;\n\t}\n\n}\n\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Results:<\/h2>\n\n\n\n<p>After connected FTDI USB-TTL converter with RX pin of FTDI to PA2, open your favourite serial terminal program, set the baudrate to 115200 and you should get the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"701\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-1024x701.png\" alt=\"\" class=\"wp-image-1424\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-1024x701.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-300x205.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-768x525.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-1150x787.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-750x513.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-400x274.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM-250x171.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/12\/Screenshot-2022-12-21-at-7.53.26-AM.png 1178w\" 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 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 transmit data. In this guide, we shall cover the following: Enable DMA for TX in UART. Configure the DMA. Send 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-1418","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\/1418"}],"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=1418"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1418\/revisions"}],"predecessor-version":[{"id":1425,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1418\/revisions\/1425"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1418"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1418"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1418"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}