{"id":2055,"date":"2023-10-19T06:52:41","date_gmt":"2023-10-19T06:52:41","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2055"},"modified":"2023-10-19T06:52:44","modified_gmt":"2023-10-19T06:52:44","slug":"stm32-advanced-timers-part-1-generating-pwm-and-complementary-output","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2055","title":{"rendered":"STM32 Advanced Timers Part 1: Generating PWM and Complementary Output"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-medium is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-300x300.jpeg\" alt=\"\" class=\"wp-image-2056\" width=\"521\" height=\"521\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-300x300.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-1024x1024.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-150x150.jpeg 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-768x768.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-1536x1536.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-2048x2048.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-1150x1150.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-750x750.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-400x400.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_139809605-250x250.jpeg 250w\" sizes=\"(max-width: 521px) 100vw, 521px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall take a look at the advanced timer of STM32 and it&#8217;s features and how to configure it to generate PWM signal with complementary output and later we shall introduce a dead time.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Features of advanced timer in STM32.<\/li><li>Complementary output.<\/li><li>Developing the driver.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Features of Advanced Timer in STM32:<\/h2>\n\n\n\n<p>TIM1 timer features include:<\/p>\n\n\n\n<p>\u2022 16-bit up, down, up\/down auto-reload counter.<\/p>\n\n\n\n<p>\u2022 16-bit programmable prescaler allowing dividing (also \u201con the fly\u201d) the counter clock frequency either by any factor between 1 and 65536.<\/p>\n\n\n\n<p>\u2022 Up to 4 independent channels for:<\/p>\n\n\n\n<p>\u2013 Input Capture<\/p>\n\n\n\n<p>\u2013 Output Compare<\/p>\n\n\n\n<p>\u2013 PWM generation (Edge and Center-aligned Mode)<\/p>\n\n\n\n<p>\u2013 One-pulse mode output<\/p>\n\n\n\n<p>\u2022 Complementary outputs with programmable dead-time<\/p>\n\n\n\n<p>\u2022 Synchronization circuit to control the timer with external signals and to interconnect several timers together.<\/p>\n\n\n\n<p>\u2022 Repetition counter to update the timer registers only after a given number of cycles of the counter.<\/p>\n\n\n\n<p>\u2022 Break input to put the timer\u2019s output signals in reset state or in a known state.<\/p>\n\n\n\n<p>\u2022 Interrupt\/DMA generation on the following events:<\/p>\n\n\n\n<p>\u2013 Update: counter overflow\/underflow, counter initialization (by software or internal\/external trigger)<\/p>\n\n\n\n<p>\u2013 Trigger event (counter start, stop, initialization or count by internal\/external trigger)<\/p>\n\n\n\n<p>\u2013 Input capture<\/p>\n\n\n\n<p>\u2013 Output compare<\/p>\n\n\n\n<p>\u2013 Break input<\/p>\n\n\n\n<p>\u2022 Supports incremental (quadrature) encoder and hall-sensor circuitry for positioning purposes<\/p>\n\n\n\n<p>\u2022 Trigger input for external clock or cycle-by-cycle current management.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"962\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-1024x962.png\" alt=\"\" class=\"wp-image-2057\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-1024x962.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-300x282.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-768x721.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-1536x1442.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-2048x1923.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-1150x1080.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-750x704.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-400x376.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.21.44-AM-250x235.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Complementary Output:<\/h2>\n\n\n\n<p>The complementary output of PWM is a method to generate an inverted signal of the original PWM with dead time. This is typical being used in generating PWM signal for gate drive of MOSFETs, synchronous buck-boost converter etc.<\/p>\n\n\n\n<p>The typical output of PWM and it&#8217;s complementary shown in figure below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"547\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-1024x547.png\" alt=\"\" class=\"wp-image-2058\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-1024x547.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-300x160.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-768x410.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-1536x820.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-2048x1094.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-1150x614.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-750x401.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-400x214.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/ef40092dc300d354d9d61c0c5456c25cfe6cab32-250x134.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Developing the Driver:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before we develop the driver, we need to find which pins are connected to TIM1_CH1 and TIM1_CH1N. We can find these information in the datasheet as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"745\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-1024x745.png\" alt=\"\" class=\"wp-image-2060\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-1024x745.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-300x218.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-768x558.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-1536x1117.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-2048x1489.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-1150x836.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-750x545.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-400x291.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.27.52-AM-250x182.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We can find that PA7 and PA8 are for CH1N and CH1 respectively. Also, the alternate function is AF01.<\/p>\n\n\n\n<p>On another hand, we need to find which bus TIM1 is connected to:<\/p>\n\n\n\n<p>This can be also found in the datasheet:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"982\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-982x1024.png\" alt=\"\" class=\"wp-image-2061\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-982x1024.png 982w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-288x300.png 288w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-768x801.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-1472x1536.png 1472w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-1150x1200.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-750x782.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-400x417.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM-250x261.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.34.24-AM.png 1804w\" sizes=\"(max-width: 982px) 100vw, 982px\" \/><\/figure>\n\n\n\n<p>Hence, TIM1 is connected to APB2.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by including the main stm32 header file:<\/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;<\/pre><\/div>\n\n\n\n<p>Create a symbolic name to hold the alternate function:<\/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 TIM1AF\t0x01<\/pre><\/div>\n\n\n\n<p>In main function:<\/p>\n\n\n\n<p>Enable clock access to GPIOA:<\/p>\n\n\n\n<p>Check <a href=\"https:\/\/blog.embeddedexpert.io\/?p=329\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=329\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> for how to enable clock access to GPIOA and set the alternate function.<\/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;}\">int main(void)\n{\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;<\/pre><\/div>\n\n\n\n<p>Set PA7 and PA8 to alternate function:<\/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\/*Configure PA7 and PA8 as alternate mode*\/\n\tGPIOA-&gt;MODER|=(GPIO_MODER_MODE7_1)|(GPIO_MODER_MODE8_1);\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODE7_0)|(GPIO_MODER_MODE8_0);<\/pre><\/div>\n\n\n\n<p>Select which alternate function to be used:<\/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\/*Select which alternate function*\/\n\t\/*Set PA7 to AF01*\/\n\tGPIOA-&gt;AFR[0]|=(TIM1AF&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n\t\/*Set PA8 to AF01*\/\n\tGPIOA-&gt;AFR[1]|=(TIM1AF&lt;&lt;GPIO_AFRH_AFSEL8_Pos);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Thats all for GPIO configuration.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, timer configuration.<\/p>\n\n\n\n<p>Enable clock access to TIM1:<\/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 TIM1*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_TIM1EN;<\/pre><\/div>\n\n\n\n<p>Set Prescaler and ARR to 15 and 100 respectively 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 Prescaler to 16-1 to get 1MHz*\/\n\tTIM1-&gt;PSC=15;\n\n\t\/*Set ARR to 1000 to get 1KHz*\/\n\n\tTIM1-&gt;ARR=1000;<\/pre><\/div>\n\n\n\n<p>This will give us 1KHz PWM signal.<\/p>\n\n\n\n<p>Configure CH1 to be PWM Mode 1 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"816\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-1024x816.png\" alt=\"\" class=\"wp-image-2062\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-1024x816.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-300x239.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-768x612.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-1536x1224.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-1150x917.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-750x598.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-400x319.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM-250x199.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.43.24-AM.png 1804w\" 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;}\">\t\/*Configure CH1 to be PWM channel*\/\n\n\tTIM1-&gt;CCMR1|=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1;<\/pre><\/div>\n\n\n\n<p>Enable channel 1 and the complementary channel:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"230\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-1024x230.png\" alt=\"\" class=\"wp-image-2063\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-1024x230.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-300x67.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-768x172.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-1536x345.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-1150x258.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-750x168.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-400x90.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM-250x56.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.44.38-AM.png 2022w\" 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;}\">\t\/*Enable CH1 and CH1 complementary output*\/\n\n\tTIM1-&gt;CCER|=TIM_CCER_CC1E|TIM_CCER_CC1NE;<\/pre><\/div>\n\n\n\n<p>Enable main output:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"543\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-1024x543.png\" alt=\"\" class=\"wp-image-2064\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-1024x543.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-300x159.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-768x407.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-1536x814.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-2048x1086.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-1150x610.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-750x398.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-400x212.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-19-at-9.46.09-AM-250x133.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 Main output*\/\n\n\tTIM1-&gt;BDTR|=TIM_BDTR_MOE;<\/pre><\/div>\n\n\n\n<p>Set CCR1 to 500 to generate 50% duty cycle:<\/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 Duty cycle to be 500 (50%)*\/\n\tTIM1-&gt;CCR1=500;<\/pre><\/div>\n\n\n\n<p>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;}\">\t\/*Enable TIM1*\/\n\n\tTIM1-&gt;CR1|=TIM_CR1_CEN;<\/pre><\/div>\n\n\n\n<p>Hence, 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;stm32f4xx.h&quot;\n\n\/*\n * PA7-&gt;TIM1_CH1N\n * PA8-&gt;TIM1_CH1\n * *\/\n\n#define TIM1AF\t0x01\n\n\nint main(void)\n{\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Configure PA7 and PA8 as alternate mode*\/\n\tGPIOA-&gt;MODER|=(GPIO_MODER_MODE7_1)|(GPIO_MODER_MODE8_1);\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODE7_0)|(GPIO_MODER_MODE8_0);\n\n\t\/*Select which alternate function*\/\n\t\/*Set PA7 to AF01*\/\n\tGPIOA-&gt;AFR[0]|=(TIM1AF&lt;&lt;GPIO_AFRL_AFSEL7_Pos);\n\t\/*Set PA8 to AF01*\/\n\tGPIOA-&gt;AFR[1]|=(TIM1AF&lt;&lt;GPIO_AFRH_AFSEL8_Pos);\n\n\t\/*Timer configuration*\/\n\n\t\/*Enable clock access to TIM1*\/\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_TIM1EN;\n\n\t\/*Set Prescaler to 16-1 to get 1MHz*\/\n\tTIM1-&gt;PSC=15;\n\n\t\/*Set ARR to 1000 to get 1KHz*\/\n\n\tTIM1-&gt;ARR=1000;\n\n\t\/*Configure CH1 to be PWM channel*\/\n\n\tTIM1-&gt;CCMR1|=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1;\n\n\t\/*Enable CH1 and CH1 complementary output*\/\n\n\tTIM1-&gt;CCER|=TIM_CCER_CC1E|TIM_CCER_CC1NE;\n\n\t\/*Enable Main output*\/\n\n\tTIM1-&gt;BDTR|=TIM_BDTR_MOE;\n\n\t\/*Set Duty cycle to be 500 (50%)*\/\n\tTIM1-&gt;CCR1=500;\n\n\t\/*Enable TIM1*\/\n\n\tTIM1-&gt;CR1|=TIM_CR1_CEN;\n\n\n\twhile(1)\n\t{\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results:<\/h2>\n\n\n\n<p>Using oscilloscope, use should see the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"480\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3.png\" alt=\"\" class=\"wp-image-2065\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3.png 800w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3-300x180.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3-768x461.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3-750x450.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3-400x240.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/DS1Z_QuickPrint3-250x150.png 250w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Two PWM signal with duty cycle of 50% and it&#8217;s complementary output.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall take a look at the advanced timer of STM32 and it&#8217;s features and how to configure it to generate PWM signal with complementary output and later we shall introduce a dead time. In this guide, we shall cover the following: Features of advanced timer in STM32. Complementary output. Developing the [&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-2055","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\/2055"}],"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=2055"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2055\/revisions"}],"predecessor-version":[{"id":2066,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2055\/revisions\/2066"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2055"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2055"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2055"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}