{"id":1486,"date":"2023-01-19T14:01:41","date_gmt":"2023-01-19T14:01:41","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1486"},"modified":"2023-01-19T14:01:44","modified_gmt":"2023-01-19T14:01:44","slug":"getting-started-with-stm32f103-timer-in-encoder-mode","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1486","title":{"rendered":"Getting Started with STM32F103: Timer in encoder mode"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-1024x683.jpeg\" alt=\"\" class=\"wp-image-1487\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-1024x683.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-300x200.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-768x512.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-1536x1024.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-2048x1365.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-1150x767.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-750x500.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-400x267.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/AdobeStock_54931129-250x167.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Rotary encoder, isolated on white background with clipping path<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In the previous guide of the timer in STM32F1(<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1468\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1468\" target=\"_blank\">here<\/a>), we took a look how to configure the timer to operate in Encoder mode, in this guide, we shall use the timer to measure the number of pulses generated by the encoder.<\/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><br>What is encoder<\/li><li>Required parts and connection<\/li><li>Configure pins and timer to read encoder<\/li><li>Download the code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 What is encoder:<\/h2>\n\n\n\n<p>A&nbsp;<strong>rotary encoder<\/strong>, also called a&nbsp;<strong>shaft encoder<\/strong>, is an&nbsp;electro-mechanical&nbsp;device that converts the&nbsp;angular&nbsp;position or motion of a shaft or axle to analog or digital output signals.&nbsp;<\/p>\n\n\n\n<p>Rotary encoders are used in a wide range of applications that require monitoring or control, or both, of mechanical systems, including industrial controls,&nbsp;robotics,&nbsp;photographic lenses,&nbsp;computer input devices such as optomechanical&nbsp;mice&nbsp;and&nbsp;trackballs, controlled stress&nbsp;rheometers, and rotating&nbsp;radar&nbsp;platforms.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 Encoder types:<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Mechanical<\/strong>: Also known as conductive encoders. A series of circumferential copper tracks etched onto a PCB is used to encode the information via contact brushes sensing the conductive areas. Mechanical encoders areeconomical but susceptible to mechanical wear. They are common in human interfaces such as&nbsp;digital multimeters<\/li><li><strong>Optical<\/strong>: This uses a light shining onto a&nbsp;photodiode&nbsp;through slits in a metal or glass disc. Reflective versions also exist. This is one of the most common technologies. Optical encoders are very sensitive to dust.<\/li><li><strong>On-Axis Magnetic<\/strong>: This technology typically uses a specially magnetized 2 pole neodymium magnet attached to the motor shaft. Because it can be fixed to the end of the shaft, it can work with motors that only have 1 shaft extending out of the motor body. The accuracy can vary from a few degrees to under 1 degree. Resolutions can be as low as 1 degree or as high as 0.09 degree (4000 CPR, Count per Revolution).&nbsp;Poorly designed internal interpolation can cause output jitter, but this can be overcome with internal sample averaging.<\/li><li><strong>Off-Axis Magnetic<\/strong>: This technology typically employs the use of rubber bonded ferrite magnets attached to a metal hub. This offers flexibility in design and low cost for custom applications. Due to the flexibility in many off axis encoder chips they can be programmed to accept any number of pole widths so the chip can be placed in any position required for the application. Magnetic encoders operate in harsh environments where optical encoders would fail to work. (from wikipedia)<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1.3 Encoder Output:<\/h2>\n\n\n\n<p>In out case, the encoder shall generate pulses on both DT and CLK lines in a certain manner that can be read by the timer of stm32. In the figure below, is the output from shaft encoder when rotating clockwise. Clk is yellow and DT is Blue.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"480\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1.png\" alt=\"\" class=\"wp-image-432\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1.png 800w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1-300x180.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1-768x461.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1-750x450.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1-400x240.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint1-250x150.png 250w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption>Clockwise rotation<\/figcaption><\/figure>\n\n\n\n<p>When the shaft encoder rotate clockwise, CLK like pulled high first then DT line which indicates there is rotation.<\/p>\n\n\n\n<p>When the counter clock rotation occurs, the DT line is pulled high first then the CLK line.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"480\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/DS1Z_QuickPrint2.png\" alt=\"\" class=\"wp-image-433\" \/><figcaption>Counter clockwise rotation<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">2.1 Required Parts:<\/h2>\n\n\n\n<p>In this guide, we will need the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F103C8 (Blue pill).<\/li><li>Shaft encoder (4 wire).<\/li><li>TTL to USB converter.<\/li><\/ul>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1008\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-1024x1008.png\" alt=\"\" class=\"wp-image-1488\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-1024x1008.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-300x295.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-768x756.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-1536x1511.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-1150x1132.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-750x738.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-400x394.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM-250x246.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.45.17-PM.png 1872w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table><tbody><tr><td>Encoder Pin<\/td><td>STM32F767 Nucleo-144<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>+<\/td><td>3V3<\/td><\/tr><tr><td>DT<\/td><td>PA0<\/td><\/tr><tr><td>CLK<\/td><td>PA1<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">3.1 Pin configuration:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>First create a source and header file with name of encoder.c and encoder.h respectively.<\/p>\n\n\n\n<p>Within the header file, declare the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>void encoder_init(uint16_t max_value).<\/li><li>uint16_t encoder_read(void):<\/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#ifndef ENCODER_H_\n#define ENCODER_H_\n#include &quot;stdint.h&quot;\n\n\nvoid encoder_init(uint16_t max_value);\nuint16_t encoder_read(void);\n\n#endif \/* ENCODER_H_ *\/\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Within the source file and encoder_init(), we shall start the initialization sequence.<\/p>\n\n\n\n<p>In order to read the encoder, we need to configure PA0 and PA1 as input floating:<\/p>\n\n\n\n<p>To do this, first enable 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;APB2ENR|=RCC_APB2ENR_IOPAEN;<\/pre><\/div>\n\n\n\n<p>Then set MODE and CONF to input floating:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"889\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-1024x889.png\" alt=\"\" class=\"wp-image-1489\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-1024x889.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-300x261.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-768x667.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-1536x1334.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-1150x999.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-750x651.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-400x347.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM-250x217.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.48.07-PM.png 1872w\" 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;}\">\/*Configure PA0 as Output Alternate Push\/Pull *\/\nGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE0;\nGPIOA-&gt;CRL|=(GPIO_CRL_CNF0_0);\nGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF0_1);\n\/*Configure PA1 as Output Alternate Push\/Pull*\/\nGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE1;\nGPIOA-&gt;CRL|=(GPIO_CRL_CNF1_0);\nGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF1_1);\n<\/pre><\/div>\n\n\n\n<p>Thats all for GPIO.<\/p>\n\n\n\n<p>Next, configuring timer:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.2 Timer configuration:<\/h2>\n\n\n\n<p>In order to config the timer to read encoder, the following steps are required:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"370\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-1024x370.png\" alt=\"\" class=\"wp-image-436\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-1024x370.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-300x108.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-768x277.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-1536x555.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-1150x415.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-750x271.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-400x145.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM-250x90.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-20-at-8.11.24-AM.png 1910w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>First we start by enabling clock access to TIM2 of stm32:<\/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 timer2*\/\nRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN;<\/pre><\/div>\n\n\n\n<p>Set the max value to be the max value passed by the user:<\/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;}\">\/*Configure timer2*\/\nTIM2-&gt;ARR=max_value-1;<\/pre><\/div>\n\n\n\n<p>then set bit CC1S and CC2S 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_CC1S_0 | TIM_CCMR1_CC2S_0 );<\/pre><\/div>\n\n\n\n<p>Then set both channel to input:<\/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 &amp;= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);<\/pre><\/div>\n\n\n\n<p>Now, we tell the TIM to operate in encoder mode 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;SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;<\/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;}\">TIM2-&gt;CR1 |= TIM_CR1_CEN;<\/pre><\/div>\n\n\n\n<p>To read the encoder, just read the count register:<\/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 encoder_read(void){\n\n\treturn  TIM2-&gt;CNT;\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the encoder.c file 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;}\">\/*\n * encoder.c\n *\n *  Created on: Jan 19, 2023\n *      Author: hussamaldean\n *\/\n\n\n#include &quot;encoder.h&quot;\n#include &quot;stm32f1xx.h&quot;\n\nvoid encoder_init(uint16_t max_value)\n{\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_IOPAEN;\n\n\t\/*Configure PA0 as Output Alternate Push\/Pull *\/\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE0;\n\tGPIOA-&gt;CRL|=(GPIO_CRL_CNF0_0);\n\tGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF0_1);\n\n\t\/*Configure PA1 as Output Alternate Push\/Pull*\/\n\n\tGPIOA-&gt;CRL&amp;=~GPIO_CRL_MODE1;\n\tGPIOA-&gt;CRL|=(GPIO_CRL_CNF1_0);\n\tGPIOA-&gt;CRL&amp;=~(GPIO_CRL_CNF1_1);\n\n\n\t\/*Enable clock access to timer2*\/\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN;\n\n\t\/*Configure timer2*\/\n\tTIM2-&gt;ARR=max_value-1;\n\n\tTIM2-&gt;CCMR1 |= (TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0 );\n\tTIM2-&gt;CCER &amp;= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);\n\tTIM2-&gt;SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;\n\tTIM2-&gt;CR1 |= TIM_CR1_CEN;\n\n\n}\n\nuint16_t encoder_read(void){\n\n\treturn  TIM2-&gt;CNT;\n}\n<\/pre><\/div>\n\n\n\n<p>In main.c code:<\/p>\n\n\n\n<p>call the init function within the main function and in while loop compare the current value with the previous value 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#include &quot;encoder.h&quot;\n#include &quot;uart.h&quot;\n\n\n\nuint16_t encoder_read_previous;\n\nint main(void)\n{\n\tuart2_init();\n\tencoder_init(10);\n\tprintf(&quot;hello from stm32\\r\\n&quot;);\n\twhile(1)\n\t{\n\n\t\tif(encoder_read()!=encoder_read_previous)\n\t\t{\n\t\t\tencoder_read_previous=encoder_read();\n\t\t\tprintf(&quot;Encoder counts = %d\\r\\n&quot;,encoder_read());\n\n\t\t}\n\n\t}\n}\n<\/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>you may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Timer_Encoder.zip\">Timer_Encoder<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Timer_Encoder.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Results:<\/h2>\n\n\n\n<p>Burn the code on the board and open serial terminal and set the baudrate to 115200 and rotate the encoder 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=\"739\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-1024x739.png\" alt=\"\" class=\"wp-image-1491\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-1024x739.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-300x217.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-768x554.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-1536x1109.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-1150x830.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-750x541.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-400x289.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM-250x180.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/01\/Screenshot-2023-01-19-at-4.39.57-PM.png 1856w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide of the timer in STM32F1(here), we took a look how to configure the timer to operate in Encoder mode, in this guide, we shall use the timer to measure the number of pulses generated by the encoder. In this guide, we shall cover the following: What is encoder Required parts and [&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-1486","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\/1486"}],"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=1486"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1486\/revisions"}],"predecessor-version":[{"id":1492,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1486\/revisions\/1492"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}