{"id":689,"date":"2022-01-10T04:39:54","date_gmt":"2022-01-10T04:39:54","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=689"},"modified":"2022-01-10T04:39:56","modified_gmt":"2022-01-10T04:39:56","slug":"working-with-stm32-and-timers-update-pwm-duty-cycle-using-dma","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=689","title":{"rendered":"Working with STM32 and Timers: Update PWM duty cycle using DMA"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"681\" height=\"323\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/PWM-signal-with-its-two-basic-time-periods.png\" alt=\"\" class=\"wp-image-364\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/PWM-signal-with-its-two-basic-time-periods.png 681w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/PWM-signal-with-its-two-basic-time-periods-300x142.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/PWM-signal-with-its-two-basic-time-periods-400x190.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/PWM-signal-with-its-two-basic-time-periods-250x119.png 250w\" sizes=\"(max-width: 681px) 100vw, 681px\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=363\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=363\" target=\"_blank\">here<\/a>), we took a look at how to configure the timer in PWM and we were able to update the duty cycle of the PWM to fade two LEDs using polling mode. In this guide, we shall look how to configure timer to update the duty cycle using DMA (Direct Memory Access).<\/p>\n\n\n\n<p>In this guide, we will cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Configure the timer in PWM.<\/li><li>Configure the DMA.<\/li><li>Code.<\/li><li>Demo<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Configure the Timer in PWM Mode:<\/h2>\n\n\n\n<p>We start off by configuring the GPIO (check the topic here):<\/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;}\">void GPIO_Init(void)\n{\n\t#define AF01 0x01\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOBEN;\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1;\n\tGPIOA-&gt;AFR[0]|=(0x01&lt;&lt;0)|(0x01&lt;&lt;4);\n\n}<\/pre><\/div>\n\n\n\n<p>Then we enable clock access to timer2 and configure the prescaler and ARR  value:<\/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;APB1ENR|=RCC_APB1ENR_TIM2EN; \/\/enable clock access tto tim2\nTIM2-&gt;PSC=0; \/\/set prescaller to 0 (no divider)\nTIM2-&gt;ARR=1600; \/\/set the maximum count value\nTIM2-&gt;CNT=0; \/\/seset the current count<\/pre><\/div>\n\n\n\n<p>Now, in order to make the timer work with the DMA, we need to configure CCDS: Capture\/compare DMA selection in Control Register 2 (CR2):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"240\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-1024x240.png\" alt=\"\" class=\"wp-image-690\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-1024x240.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-300x70.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-768x180.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-1536x361.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-2048x481.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-1150x270.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-750x176.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-400x94.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.17.07-AM-250x59.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>CCDS: Capture\/compare DMA selection<\/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;}\">TIM2-&gt;CR2|=TIM_CR2_CCDS;<\/pre><\/div>\n\n\n\n<p>From DMA\/Interrupt enable register, we need to enable the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"240\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-1024x240.png\" alt=\"\" class=\"wp-image-691\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-1024x240.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-300x70.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-768x180.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-1536x361.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-2048x481.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-1150x270.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-750x176.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-400x94.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.18.08-AM-250x59.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>UDE: Update DMA request enable<\/li><li>CC1DE: Capture\/Compare 1 DMA request enable<\/li><li>CC2DE: Capture\/Compare 2 DMA request enable<\/li><li>TDE: Trigger DMA request 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;}\">TIM2-&gt;DIER|=(TIM_DIER_UDE)|TIM_DIER_CC1DE|TIM_DIER_CC2DE;\nTIM2-&gt;DIER|=TIM_DIER_TDE;<\/pre><\/div>\n\n\n\n<p>Finally enable the PWM 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;}\">TIM2-&gt;CCMR1=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1|TIM_CCMR1_OC2M_2|TIM_CCMR1_OC2M_1; \/\/configure the pins as PWM\nTIM2-&gt;CCER|=TIM_CCER_CC1E|TIM_CCER_CC2E; \/\/enbale channel1 and channel2<\/pre><\/div>\n\n\n\n<p>Please note that we didn&#8217;t start the timer yet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Configuring the DMA:<\/h2>\n\n\n\n<p>Before configuring the DMA, we need to know which DMA, stream and channel to use.<\/p>\n\n\n\n<p>From the reference manual, DMA section, we can find DMA request map <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"440\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-1024x440.png\" alt=\"\" class=\"wp-image-692\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-1024x440.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-300x129.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-768x330.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-1536x660.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-2048x880.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-1150x494.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-750x322.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-400x172.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.22.49-AM-250x107.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, we need to use DMA1, Stream5 and Stream6 and channel 3<\/p>\n\n\n\n<p>We can 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;<\/pre><\/div>\n\n\n\n<p>The disable the stream and wait until it 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;}\">RCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA1EN;\nDMA1_Stream5-&gt;CR&amp;=DMA_SxCR_EN;\nwhile((DMA1_Stream5-&gt;CR)&amp;DMA_SxCR_EN){;}\n\nDMA1_Stream6-&gt;CR&amp;=DMA_SxCR_EN;\nwhile((DMA1_Stream6-&gt;CR)&amp;DMA_SxCR_EN){;}<\/pre><\/div>\n\n\n\n<p>Then we can configure both stream as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"363\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-1024x363.png\" alt=\"\" class=\"wp-image-693\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-1024x363.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-300x106.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-768x272.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-1536x544.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-2048x726.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-1150x408.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-750x266.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-400x142.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.27.02-AM-250x89.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Channel 3<\/li><li>Memory size to 32<\/li><li>Peripheral size to 32<\/li><li>Memory increment mode<\/li><li>Circular mode<\/li><li>Direction memory to peripheral <\/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;}\">#define CH3   ((1&lt;&lt;26)|(1&lt;&lt;25))\n#define M_SI32 (1&lt;&lt;14)\n#define P_SI32 (1&lt;&lt;12)\n#define M_INC  (1&lt;&lt;10)\n#define Cir    (1&lt;&lt;8)\n#define M2P    (1&lt;&lt;6)\nDMA1_Stream5-&gt;CR|=CH3|M_SI32|P_SI32|M_INC|Cir|M2P;\nDMA1_Stream6-&gt;CR|=CH3|M_SI32|P_SI32|M_INC|Cir|M2P;\n\n\n\n<\/pre><\/div>\n\n\n\n<p>Set number of transfer to 200 (in this case):<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">DMA1_Stream5-&gt;NDTR=(uint16_t)200;\nDMA1_Stream6-&gt;NDTR=(uint16_t)200;<\/pre><\/div>\n\n\n\n<p>Peripheral address to be CCR1 for Stream5<\/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_Stream5-&gt;PAR=(uint32_t)(&amp;TIM2-&gt;CCR1);<\/pre><\/div>\n\n\n\n<p>CCR2 for 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_Stream6-&gt;PAR=(uint32_t)(&amp;TIM2-&gt;CCR2);<\/pre><\/div>\n\n\n\n<p>Memory address to be lookup table 1 for Stream5<\/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_Stream5-&gt;M0AR=(uint32_t)(&amp;lookUp1);<\/pre><\/div>\n\n\n\n<p>lookup table 2 for 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_Stream6-&gt;M0AR=(uint32_t)(&amp;lookUp2);<\/pre><\/div>\n\n\n\n<p>Enable both 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|=DMA_SxCR_EN;\n\nDMA1_Stream5-&gt;CR|=DMA_SxCR_EN;<\/pre><\/div>\n\n\n\n<p>and Finally enable the timer:<\/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;}\">TIM2-&gt;CR1|=1; \/\/enable timer<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<p>Hence the entire code shall be like this:<\/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;stm32f4xx.h&quot;                  \/\/ Device header\n\n#define CH3   ((1&lt;&lt;26)|(1&lt;&lt;25))\n#define M_SI32 (1&lt;&lt;14)\n#define P_SI32 (1&lt;&lt;12)\n#define M_INC  (1&lt;&lt;10)\n#define Cir    (1&lt;&lt;8)\n#define M2P    (1&lt;&lt;6)\n#define PFCTRL (1&lt;&lt;5)\n\/\/ Look up tables with 200 entries each, normalised to have max value of 1600 which is the period of the PWM loaded into register ICR1.\nuint32_t lookUp1[] = {0,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494 ,542 ,589 ,635 ,681\n\t,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233 ,1264\n\t,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561\n\t,1572 ,1580 ,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561\n\t,1550 ,1536 ,1522 ,1505 ,1488 ,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264\n\t,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981 ,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635\n\t,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0};\n\nuint32_t lookUp2[] = {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0\n\t,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,50 ,100 ,151 ,201 ,250 ,300 ,349 ,398 ,446 ,494\n\t,542 ,589 ,635 ,681 ,726 ,771 ,814 ,857 ,899 ,940 ,981 ,1020 ,1058 ,1095 ,1131 ,1166 ,1200 ,1233\n\t,1264 ,1294 ,1323 ,1351 ,1377 ,1402 ,1426 ,1448 ,1468 ,1488 ,1505 ,1522 ,1536 ,1550 ,1561 ,1572 ,1580\n\t,1587 ,1593 ,1597 ,1599 ,1600 ,1599 ,1597 ,1593 ,1587 ,1580 ,1572 ,1561 ,1550 ,1536 ,1522 ,1505 ,1488\n\t,1468 ,1448 ,1426 ,1402 ,1377 ,1351 ,1323 ,1294 ,1264 ,1233 ,1200 ,1166 ,1131 ,1095 ,1058 ,1020 ,981\n\t,940 ,899 ,857 ,814 ,771 ,726 ,681 ,635 ,589 ,542 ,494 ,446 ,398 ,349 ,300 ,250 ,201 ,151 ,100 ,50 ,0,0};\n\n\n\n\nvoid GPIO_Init(void);\nvoid Timer2_init(void);\n\n\n\n\nint main()\n\n\n\t{\n\tGPIO_Init();\n\tTimer2_init();\n\n\twhile(1)\n\t\t{\n\n\n\t\t}\n\n\n\t}\n\n\n\n\n\n\nvoid GPIO_Init(void)\n{\n\t#define AF01 0x01\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOBEN;\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_1|GPIO_MODER_MODE1_1;\n\tGPIOA-&gt;AFR[0]|=(0x01&lt;&lt;0)|(0x01&lt;&lt;4);\n\n}\nvoid  Timer2_init(void){\n\n\/\/init timer;\nRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN; \/\/enable clock access tto tim2\nTIM2-&gt;PSC=0; \/\/set prescaller to 0 (no divider)\nTIM2-&gt;ARR=1600; \/\/set the maximum count value\nTIM2-&gt;CNT=0; \/\/seset the current count\nTIM2-&gt;CR2|=TIM_CR2_CCDS;\nTIM2-&gt;DIER|=(TIM_DIER_UDE)|TIM_DIER_CC1DE|TIM_DIER_CC2DE;\nTIM2-&gt;DIER|=TIM_DIER_TDE;\nTIM2-&gt;CCMR1=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1|TIM_CCMR1_OC2M_2|TIM_CCMR1_OC2M_1; \/\/configure the pins as PWM\nTIM2-&gt;CCER|=TIM_CCER_CC1E|TIM_CCER_CC2E; \/\/enbale channel1 and channel2\n\n\/\/init dma\n\n\nRCC-&gt;AHB1ENR|=RCC_AHB1ENR_DMA1EN;\nDMA1_Stream5-&gt;CR&amp;=DMA_SxCR_EN;\nwhile((DMA1_Stream5-&gt;CR)&amp;DMA_SxCR_EN){;}\nDMA1_Stream5-&gt;CR|=CH3|M_SI32|P_SI32|M_INC|Cir|M2P;\nDMA1_Stream5-&gt;NDTR=(uint16_t)200;\n\nDMA1_Stream5-&gt;PAR=(uint32_t)(&amp;TIM2-&gt;CCR1);\n\nDMA1_Stream5-&gt;M0AR=(uint32_t)(&amp;lookUp1);\n\n\nDMA1_Stream6-&gt;CR&amp;=DMA_SxCR_EN;\nwhile((DMA1_Stream6-&gt;CR)&amp;DMA_SxCR_EN){;}\nDMA1_Stream6-&gt;CR|=CH3|M_SI32|P_SI32|M_INC|Cir|M2P;\nDMA1_Stream6-&gt;NDTR=(uint16_t)200;\n\nDMA1_Stream6-&gt;PAR=(uint32_t)(&amp;TIM2-&gt;CCR2);\n\nDMA1_Stream6-&gt;M0AR=(uint32_t)(&amp;lookUp2);\n\n\nDMA1_Stream6-&gt;CR|=DMA_SxCR_EN;\n\n\nDMA1_Stream5-&gt;CR|=DMA_SxCR_EN;\nTIM2-&gt;CR1|=1; \/\/enable timer\n}\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Demo:<\/h2>\n\n\n\n<p>When you probe both PA0 and PA1 using an oscilloscope, 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=\"615\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-1024x615.png\" alt=\"\" class=\"wp-image-694\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-1024x615.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-300x180.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-768x461.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-1150x690.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-750x450.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-400x240.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM-250x150.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/01\/Screen-Shot-2022-01-10-at-7.38.19-AM.png 1536w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\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 at how to configure the timer in PWM and we were able to update the duty cycle of the PWM to fade two LEDs using polling mode. In this guide, we shall look how to configure timer to update the duty cycle using DMA (Direct Memory [&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-689","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\/689"}],"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=689"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions"}],"predecessor-version":[{"id":695,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions\/695"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}