{"id":2363,"date":"2024-02-29T13:48:23","date_gmt":"2024-02-29T13:48:23","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2363"},"modified":"2024-02-29T13:48:26","modified_gmt":"2024-02-29T13:48:26","slug":"working-with-stm32-and-motors-dc-servo-motors","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2363","title":{"rendered":"Working with STM32 and Motors: DC Servo Motors"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"429\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-Motor.jpg\" alt=\"\" class=\"wp-image-2364\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-Motor.jpg 600w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-Motor-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-Motor-400x286.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-Motor-250x179.jpg 250w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure><\/div>\n\n\n\n<p>In this guide series, we shall see how to use STM32 to control various types of motors. The first type of motor is servo motor.<\/p>\n\n\n\n<p>In this guide, we shall cover the following the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is servo motor.<\/li><li>Construction of servo motor.<\/li><li>Connection.<\/li><li>Developing the driver.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is Servo Motor:<\/h2>\n\n\n\n<p>A&nbsp;<strong>servomotor<\/strong>&nbsp;is a&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Rotary_actuator\">rotary actuator<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linear_actuator\">linear actuator<\/a>&nbsp;that allows for precise control of angular or linear position, velocity and acceleration.<sup><a href=\"https:\/\/en.wikipedia.org\/wiki\/Servomotor#cite_note-1\">[1]<\/a><\/sup>&nbsp;It consists of a suitable motor coupled to a sensor for position feedback. It also requires a relatively sophisticated controller, often a dedicated module designed specifically for use with servomotors. (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Servomotor\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia link<\/a>).<\/p>\n\n\n\n<p>The servo motor used in our guide has three wires: red, brown and orange.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Wire color<\/td><td>Function<\/td><\/tr><tr><td>Red<\/td><td>Vcc (4~6V)<\/td><\/tr><tr><td>Brown<\/td><td>GND<\/td><\/tr><tr><td>Orange<\/td><td>Signal<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"284\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1024x284.png\" alt=\"\" class=\"wp-image-393\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1024x284.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-300x83.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-768x213.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1150x319.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-750x208.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-400x111.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-250x69.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM.png 1370w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Construction of Servo Motor:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The construction of the servo motor is shown in the figure below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"500\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons.png\" alt=\"\" class=\"wp-image-2365\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons.png 900w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons-300x167.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons-768x427.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons-750x417.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons-400x222.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/02\/Servo-motor-constructons-250x139.png 250w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure>\n\n\n\n<p>Typically, the servo motor is consist of the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Drive great to decrease the rotation speed and increase the torque output of the motor.<\/li><li>Feedback in form of potentiometer or encoder to get the current position of the putout shaft.<\/li><li>Integrated circuit which compares the desired angle with the current angle and adjust the position accordingly.<\/li><li>Motor which is responsible for the movement of the servo motor and it could be either DC or AC.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall use DC version commonly used by RC vehicles and drones.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Connection:<\/h2>\n\n\n\n<p>In this guide, we need the following<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F411 Nucleo<\/li><li>SG90 microservo<\/li><li>Hock-up wires<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-900x1024.png\" alt=\"\" class=\"wp-image-395\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-900x1024.png 900w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-264x300.png 264w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-768x873.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-1351x1536.png 1351w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-1150x1308.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-750x853.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-400x455.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-250x284.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM.png 1370w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Servo Motor<\/td><td>STM32F411 Nucleo-64<\/td><\/tr><tr><td>Red<\/td><td>5V<\/td><\/tr><tr><td>Brown<\/td><td>GND<\/td><\/tr><tr><td>Orange<\/td><td>PA0<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">4. Developing the Driver:<\/h2>\n\n\n\n<p>Before developing the driver, we need to understand the required pulse to control the servo motor.<\/p>\n\n\n\n<p>In order to control the angle of the servo motor, a PWM signal of frequency 50Hz (20mS period) needed to be applied to the signal pin on the servo motor. to determine the angle of the servo as following:<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>Angle&nbsp;<\/td><td>Duty Cycle (Period)<\/td><\/tr><tr><td>0<\/td><td>5% (1mS)<\/td><\/tr><tr><td>90<\/td><td>7.5% (1.5mS)<\/td><\/tr><tr><td>180<\/td><td>10%(2mS)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"520\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1024x520.png\" alt=\"\" class=\"wp-image-394\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1024x520.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-300x152.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-768x390.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1536x780.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1150x584.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-750x381.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-400x203.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-250x127.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM.png 1560w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>However, in reality, the servo requires signal duration of 0.65ms for 0 position and 2.4ms for 180 degree position with frequency of 50Hz.<\/p>\n\n\n\n<p>After having the basic information, we can start with developing the driver.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>We start off by creating new source and header file with name of servo.c and servo.h respectively.<\/p>\n\n\n\n<p>Within the header file, include the header guard as following:<br><\/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;}\">#ifndef SERVO_H_\n#define SERVO_H_\n\n\n\n\n#endif \/* SERVO_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Within the header guard, include the stdint library 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;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following 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;}\">\/* @Brief This function shall initial GPIOA Pin 0 to control the Servo motor\n * @Param Nothing\n * @Return Nothing\n * *\/\nvoid Servo_Pin_Init(void);<\/pre><\/div>\n\n\n\n<p>The function will initialize PA0 to work as PWM signal and the function takes no argument and returns nothing.<\/p>\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;}\">\/* @Brief This function shall initial TIM2 of STM32F4 to generate 50Hz PWM signal\n * @Param freq which is the bus frequency that connected to TIM2 in MHz\n * @Return Nothing\n * *\/\nvoid Servo_TIM2_Init(uint16_t freq);<\/pre><\/div>\n\n\n\n<p>This function shall setup timer2 to work as PWM mode to generate PWM signal and take frequency as parameter in MHz and returns nothing.<\/p>\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;}\">\/* @Brief This function shall set the angle of the servo motor\n * @Param angle in degrees\n * @Return nothing\n * *\/\nvoid ServoSetAngle(uint8_t angle);<\/pre><\/div>\n\n\n\n<p>This function will set the angle of the servo motor. The function takes angle as argument and returns nothing.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the header 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;}\">#ifndef SERVO_H_\n#define SERVO_H_\n\n\n\n#include &quot;stdint.h&quot;\n\n\/* @Brief This function shall initial GPIOA Pin 0 to control the Servo motor\n * @Param Nothing\n * @Return Nothing\n * *\/\nvoid Servo_Pin_Init(void);\n\n\/* @Brief This function shall initial TIM2 of STM32F4 to generate 50Hz PWM signal\n * @Param freq which is the bus frequency that connected to TIM2 in MHz\n * @Return Nothing\n * *\/\nvoid Servo_TIM2_Init(uint16_t freq);\n\n\n\/* @Brief This function shall set the angle of the servo motor\n * @Param angle in degrees\n * @Return nothing\n * *\/\nvoid ServoSetAngle(uint8_t angle);\n\n\n\n\n#endif \/* SERVO_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In the source file, we start include the following 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;servo.h&quot;<\/pre><\/div>\n\n\n\n<p>Also, include STM32F4xx main 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><\/p>\n\n\n\n<p>Before that, please check <a href=\"https:\/\/blog.embeddedexpert.io\/?p=363\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=363\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> for how to configure the timer in PWM mode.<\/p>\n\n\n\n<p>Declare a macro to hold the alternate function number:<\/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<\/pre><\/div>\n\n\n\n<p>For the GPIO initialization:<\/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 Servo_Pin_Init(void)\n{\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Set PA0 to alternate function*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_1;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0_0;\n\n\t\/*Set the GPIO speed to maximum*\/\n\tGPIOA-&gt;OSPEEDR|=GPIO_OSPEEDER_OSPEEDR0;\n\n\t\/*Set which alternate function *\/\n\tGPIOA-&gt;AFR[0]|=(TIM2_AF&lt;&lt;GPIO_AFRL_AFSEL0_Pos);\n\n}<\/pre><\/div>\n\n\n\n<p>For the timer initialization:<\/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 Servo_TIM2_Init(uint16_t freq)\n{\n\t\/*Enable clock access to TIM2*\/\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN;\n\n\t\/*Set the PSC and ARR values*\/\n\tTIM2-&gt;PSC=freq-1;\n\tTIM2-&gt;ARR=20000-1;\n\n\t\/*Set TIM2_CH1 as PWM *\/\n\n\tTIM2-&gt;CCMR1|=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1;\n\n\t\/*Enable TIM2_CH1*\/\n\tTIM2-&gt;CCER|=TIM_CCER_CC1E;\n\n\t\/*Set TIM2_CH1 to 1ms (1000)*\/\n\tTIM2-&gt;CCR1=650;\n\n\t\/*Enable TIM2*\/\n\n\tTIM2-&gt;CR1|=TIM_CR1_CEN;\n\n}<\/pre><\/div>\n\n\n\n<p>Not that we set the PSC to freq-1 which will reduce the timer frequency to 1MHz (1uS). With ARR value of 20000 which will set the period of 20000 microseconds (20ms). These values will generate 50Hz PWM signal.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>We shall declare local function will convert the angle to duty cycle 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;}\">\/* @Brief This function shall calculate the duty cycle according the required angle\n * @Param angle in degrees\n * @Return duty cycle for the required angle\n * *\/\n\nstatic long angle_to_duty(uint8_t angle)\n{\n  return (9.72*angle +650);\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>For setting the angle:<\/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 ServoSetAngle(uint8_t angle)\n{\n\tif (angle &gt;180){angle=180;}\n\n\t\/*Set the duty cycle according to the calculation*\/\n\tTIM2-&gt;CCR1=angle_to_duty(angle);\n}<\/pre><\/div>\n\n\n\n<p>Hence, the source 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;}\">#include &quot;servo.h&quot;\n\n#include &quot;stm32f4xx.h&quot;\n\n\n#define TIM2_AF 0x01\n\n\nvoid Servo_Pin_Init(void)\n{\n\t\/*Enable clock access to GPIOA*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\n\t\/*Set PA0 to alternate function*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_1;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0_0;\n\n\t\/*Set the GPIO speed to maximum*\/\n\tGPIOA-&gt;OSPEEDR|=GPIO_OSPEEDER_OSPEEDR0;\n\n\t\/*Set which alternate function *\/\n\tGPIOA-&gt;AFR[0]|=(TIM2_AF&lt;&lt;GPIO_AFRL_AFSEL0_Pos);\n\n}\n\n\n\nvoid Servo_TIM2_Init(uint16_t freq)\n{\n\t\/*Enable clock access to TIM2*\/\n\tRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN;\n\n\t\/*Set the PSC and ARR values*\/\n\tTIM2-&gt;PSC=freq-1;\n\tTIM2-&gt;ARR=20000-1;\n\n\t\/*Set TIM2_CH1 as PWM *\/\n\n\tTIM2-&gt;CCMR1|=TIM_CCMR1_OC1M_2|TIM_CCMR1_OC1M_1;\n\n\t\/*Enable TIM2_CH1*\/\n\tTIM2-&gt;CCER|=TIM_CCER_CC1E;\n\n\t\/*Set TIM2_CH1 to 1ms (1000)*\/\n\tTIM2-&gt;CCR1=650;\n\n\t\/*Enable TIM2*\/\n\n\tTIM2-&gt;CR1|=TIM_CR1_CEN;\n\n}\n\n\/* @Brief This function shall calculate the duty cycle according the required angle\n * @Param angle in degrees\n * @Return duty cycle for the required angle\n * *\/\n\nstatic long angle_to_duty(uint8_t angle)\n{\n  return (9.72*angle +650);\n}\n\n\n\n\nvoid ServoSetAngle(uint8_t angle)\n{\n\tif (angle &gt;180){angle=180;}\n\n\t\/*Set the duty cycle according to the calculation*\/\n\tTIM2-&gt;CCR1=angle_to_duty(angle);\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In main.c:<\/p>\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;}\">#include &quot;servo.h&quot;\n#include &quot;delay.h&quot;\nint pos;\nint main(void)\n{\n\n\tServo_Pin_Init();\n\tServo_TIM2_Init(16);\n\tdelay_init(16000000);\n\n\twhile(1)\n\t{\n\t\tfor (pos = 0; pos &lt;= 180; pos += 1)\n\t\t{ \/\/ goes from 0 degrees to 180 degrees\n\t\t    \/\/ in steps of 1 degree\n\t\t\tServoSetAngle(pos);              \/\/ tell servo to go to position in variable 'pos'\n\t\t    delay(15);                       \/\/ waits 15ms for the servo to reach the position\n\t\t}\n\t\tfor (pos = 180; pos &gt;= 0; pos -= 1)\n\t\t{ \/\/ goes from 180 degrees to 0 degrees\n\t\t\tServoSetAngle(pos);              \/\/ tell servo to go to position in variable 'pos'\n\t\t    delay(15);                       \/\/ waits 15ms for the servo to reach the position\n\t\t}\n\n\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p>For the delay function, please refer to <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1644\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1644\" target=\"_blank\">this guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Servo Control using STM32\" width=\"1170\" height=\"658\" src=\"https:\/\/www.youtube.com\/embed\/C01XrTcBo3I?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide series, we shall see how to use STM32 to control various types of motors. The first type of motor is servo motor. In this guide, we shall cover the following the following: What is servo motor. Construction of servo motor. Connection. Developing the driver. Results. 1. What is Servo Motor: A&nbsp;servomotor&nbsp;is a&nbsp;rotary [&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-2363","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\/2363"}],"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=2363"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2363\/revisions"}],"predecessor-version":[{"id":2366,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2363\/revisions\/2366"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}