{"id":585,"date":"2021-11-22T04:58:06","date_gmt":"2021-11-22T04:58:06","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=585"},"modified":"2021-11-22T04:58:08","modified_gmt":"2021-11-22T04:58:08","slug":"working-with-stm32-and-timers-part-6-output-compare","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=585","title":{"rendered":"Working with STM32 and Timers part 6: Output Compare"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/embedds.com\/wp-content\/uploads\/2010\/12\/250counts_CTCmode.png?ssl=1\" alt=\"\" \/><\/figure><\/div>\n\n\n\n<p>In the pervious guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=430\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=430\" target=\"_blank\">here<\/a>), we took a look how to configure the timer in encoder mode to read the pulses generated by the encoder.<\/p>\n\n\n\n<p>In this guide we cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is output compare mode<\/li><li>Required parts<\/li><li>Code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is output compare mode:<\/h2>\n\n\n\n<p>In this mode, the timer shall count to the maximum level (set by the ARR), the following will happen:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Assigns the corresponding output pin to a programmable value defined by the output compare mode.<\/li><li>Sets a flag in the interrupt status register.<\/li><li>Generates an interrupt if the corresponding interrupt mask is set.<\/li><li>Sends a DMA request if the corresponding enable bit is set.<\/li><\/ul>\n\n\n\n<p>In our case, we will toggle PA5 (TIM2_CH1) based on out setting.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Required parts:<\/h2>\n\n\n\n<p>In this guide, we need only the Nucleo board, in this case STM32F446RE-Nucleo-64. Since the build LED is connected to PA5 which is channel 1 of timer 2<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<p>We start off by enabling clock access to GPIOA:<\/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\t|=\tRCC_AHB1ENR_GPIOAEN;<\/pre><\/div>\n\n\n\n<p>Then set PA5 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;}\">GPIOA-&gt;MODER\t|=\tGPIO_MODER_MODE5_1;\nGPIOA-&gt;MODER\t&amp;= ~GPIO_MODER_MODE5_0;<\/pre><\/div>\n\n\n\n<p>Then we set the type of 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 TIM2_AF 0x01\nGPIOA-&gt;AFR[0] |= (TIM2_AF&lt;&lt;20);<\/pre><\/div>\n\n\n\n<p>Then we enable clock access to the timer2:<\/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;<\/pre><\/div>\n\n\n\n<p>Disable 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     &amp;=~ TIM_CR1_CEN;<\/pre><\/div>\n\n\n\n<p>In order to toggle the pin when a match we need to set OC1M bits in CCMR1 to toggle on match<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"626\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-1024x626.png\" alt=\"\" class=\"wp-image-586\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-1024x626.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-300x183.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-768x469.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-1536x939.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-2048x1252.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-1150x703.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-750x458.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-400x245.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/Screen-Shot-2021-11-22-at-7.42.24-AM-250x153.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From the image, we can set this mode when both bit4 and bit5 are set, hence we can set them 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;}\">TIM2-&gt;CCMR1|=TIM_CCMR1_OC1M_0|TIM_CCMR1_OC1M_1;<\/pre><\/div>\n\n\n\n<p>We enable the channel 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;}\">TIM2-&gt;CCER|=TIM_CCER_CC1E;<\/pre><\/div>\n\n\n\n<p>We set the prescaler and period to get 1 second 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;}\">TIM2-&gt;PSC=16000-1; \/*16 000 000 \/ 16 000 =1 000*\/\nTIM2-&gt;ARR=1000-1; \/*1 000 \/ 1 000 = 1HZ*\/<\/pre><\/div>\n\n\n\n<p>Finally, we enable the timer 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;}\">TIM2-&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;                  \/\/ Device header\n\nint main(void)\n\t{\n\t#define TIM2_AF 0x01\n\tRCC-&gt;AHB1ENR\t|=\tRCC_AHB1ENR_GPIOAEN;\n\tGPIOA-&gt;MODER\t|=\tGPIO_MODER_MODE5_1;\n\tGPIOA-&gt;MODER\t&amp;= ~GPIO_MODER_MODE5_0;\n\tGPIOA-&gt;AFR[0] |= (TIM2_AF&lt;&lt;20); \n\t\n\tRCC-&gt;APB1ENR  |=  RCC_APB1ENR_TIM2EN;\n\tTIM2-&gt;CR1     &amp;=~ TIM_CR1_CEN;\n\tTIM2-&gt;CCMR1|=TIM_CCMR1_OC1M_0|TIM_CCMR1_OC1M_1;\n\tTIM2-&gt;CCER|=TIM_CCER_CC1E;\n\tTIM2-&gt;PSC=16000-1; \/*16 000 000 \/ 16 000 =1 000*\/\n\tTIM2-&gt;ARR=1000-1; \/*1 000 \/ 1 000 = 1HZ*\/\n\tTIM2-&gt;CR1     |= TIM_CR1_CEN;\n\t\n\twhile(1);\n\t}<\/pre><\/div>\n\n\n\n<p>As you noticed, the while one loop is empty since the toggling process is done by hardware level not software<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Demo:<\/h2>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/11\/IMG_7173.mp4\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In the pervious guide (here), we took a look how to configure the timer in encoder mode to read the pulses generated by the encoder. In this guide we cover the following: What is output compare mode Required parts Code Demo 1. What is output compare mode: In this mode, the timer shall count to [&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-585","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\/585"}],"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=585"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/585\/revisions"}],"predecessor-version":[{"id":588,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/585\/revisions\/588"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}