{"id":246,"date":"2021-08-05T07:44:40","date_gmt":"2021-08-05T07:44:40","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=246"},"modified":"2021-08-05T07:44:43","modified_gmt":"2021-08-05T07:44:43","slug":"systick-timer-blinking-an-led-without-a-delay","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=246","title":{"rendered":"SysTick Timer : Blinking an LED without a delay"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-medium_image\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"411\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-400x411.png\" alt=\"\" class=\"wp-image-250\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-400x411.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-292x300.png 292w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-768x789.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-750x771.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled-250x257.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Untitled.png 938w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure><\/div>\n\n\n\n<p>In previous two guides (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=83\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=83\" target=\"_blank\">Understanding GPIOs<\/a> and <a href=\"https:\/\/blog.embeddedexpert.io\/?p=79\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=79\">Understanding the Systick Timer<\/a>) we explained how to use GPIOs in both input mode and output mode and how to use SysTick timer to generate delay.<\/p>\n\n\n\n<p>Delay is a function thats block the cpu for certain of time and can&#8217;t move beyond this point until the delay time is elapsed. This can be cause unpredictable system behavior in certain situations where the main loop must be as fast as possible and you want to toggle the led every second to inform the use that the main loop is working without any issue. Hence, we will be using the Systick Timer in interrupt mode to generate an interrupt every 1 milliseconds and increment an counter.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>We will cover in this guid the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Configuring the GPIO PA5 as output.<\/li><li>Configure SysTick in interrupt mode.<\/li><li>Required parts.<\/li><li>Code.<\/li><li>Code explanation.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. Configuring PA5 as output<\/h2>\n\n\n\n<p>Since STM32F411RE Nucelo has built-in LED which is connected to PA5 as mention in the reference manual of Nucelo-64. Hence we the Following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Enable clock access to GPIOA<\/li><li>Set PA5 as Output<\/li><\/ul>\n\n\n\n<p>In order to enable clock access to GPIO Port A, we need to locate which bus is the GPIOA is connected to. This information can be found in the datasheet of the STM32F411RE.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"777\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-777x1024.png\" alt=\"\" class=\"wp-image-252\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-777x1024.png 777w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-228x300.png 228w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-768x1012.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-1166x1536.png 1166w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-1150x1515.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-750x988.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-400x527.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM-250x329.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.04.34-AM.png 1448w\" sizes=\"(max-width: 777px) 100vw, 777px\" \/><figcaption>STM32F411xC\/xE block diagram<\/figcaption><\/figure>\n\n\n\n<p>As the figure, the GPIO Port A is connected to AHB1 (Advanced High-performance Bus ) Bus. After that we need to enable the clock access to the port by heading to reference manual and check the clock enable of AHB1 register.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"399\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-1024x399.png\" alt=\"\" class=\"wp-image-253\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-1024x399.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-300x117.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-768x300.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-1536x599.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-2048x799.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-1150x449.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-750x293.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-400x156.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.11.21-AM-250x98.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Then we need to configure pin PA5 as output. The pin can be set as output using MODER register which can be found in GPIO section.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"455\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-1024x455.png\" alt=\"\" class=\"wp-image-254\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-1024x455.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-300x133.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-768x341.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-1536x683.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-2048x910.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-1150x511.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-750x333.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-400x178.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/Screen-Shot-2021-08-05-at-10.14.00-AM-250x111.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We need to set MODER5 as output hence bit number 10.<\/p>\n\n\n\n<p>Then we can use ODR (Output Data Register) to turn on\/off the led<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Configure SysTick Timer in Interrupt mode<\/h2>\n\n\n\n<p>In order to configure Systick Timer in interrupt mode, we need the following steps<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Disable Systick Timer (SysTick-&gt;CTRL=0;).<\/li><li>load value 16000-1 for 1mS operation (SysTick-&gt;LOAD=16000-1;).<\/li><li>Select clock source to processor clock, enable interrupt and start counter (SysTick-&gt;CTRL=7;) <\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">3. Required part<\/h2>\n\n\n\n<p>Here we only need STM32F411RE Nucleo-64 since it has built-in led to test the functionality.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.  Code<\/h2>\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#include &quot;stdint.h&quot;\n#define rate 1000\nuint64_t previous; \/\/variable to store the time\nvolatile uint64_t ms,rms; \/\/ms current millis, rms return current ms when millis() function is called\n\nuint64_t millis(void)\n\t{\n\t__disable_irq();\n\trms=ms; \/\/store current ms in rms\n\t__enable_irq();\n\treturn rms;\n\t}\nint main(void)\n\t{\n\t__disable_irq();\n\t\n\tSysTick-&gt;LOAD=16000-1;\n\tSysTick-&gt;VAL=0;\n\tSysTick-&gt;CTRL=7; \/\/0b00000111;\n\tRCC-&gt;AHB1ENR |=RCC_AHB1ENR_GPIOAEN;\n\tGPIOA-&gt;MODER|= GPIO_MODER_MODER5_0; \/\/PA5 as output\n\t__enable_irq();\n\t\n\t\n\t\n\t\nwhile(1)\n\t{\n\tif(millis()-previous&gt;rate) \/\/if current time is elapsed, execute the if condition \n\t\t{\n\t\tGPIOA-&gt;ODR^=GPIO_ODR_OD5;\n\t\tprevious=millis();\n\t\t}\n\t\n\t}\t\n\t\n\t\n\t}\n\t\n\t\nvoid SysTick_Handler(void){\nms++;\n}<\/pre><\/div>\n\n\n\n<p>Compile and upload the code to the Nucleo-64 board and you will see that the led is blinking every second.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/08\/IMG_6034.mp4\"><\/video><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code Explanation <\/h2>\n\n\n\n<p>we starting by including the required 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;                  \/\/ Device header\n#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>then declare some required variables and constants. The reason behind using volatile is to opt-out compiler optimization and this value can be changed during code execution .<\/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 rate 1000 \/\/rate of toggling \nuint64_t previous; \/\/variable to store the time\nvolatile uint64_t ms,rms; \/\/ms current millis, rms return current ms when millis() function is called\n<\/pre><\/div>\n\n\n\n<p>Now the millis function to return the time in milliseconds <\/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;}\">uint64_t millis(void)\n\t{\n\t__disable_irq(); \/\/disable all interruot\n\trms=ms; \/\/store current ms in rms\n\t__enable_irq(); \/\/enable all interrupt\n\treturn rms; \/\/return the value\n\t}<\/pre><\/div>\n\n\n\n<p>Main 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\t{\n\t__disable_irq();\n\tSysTick-&gt;LOAD=16000-1;\n\tSysTick-&gt;VAL=0;\n\tSysTick-&gt;CTRL=7; \/\/0b00000111;\n\tRCC-&gt;AHB1ENR |=RCC_AHB1ENR_GPIOAEN;\/\/enable clock access to port a\n\tGPIOA-&gt;MODER|= GPIO_MODER_MODER5_0; \/\/PA5 as output\n\t__enable_irq();\n\t\n\t\n\t\n\t\nwhile(1)\n\t{\n\tif(millis()-previous&gt;rate) \/\/if current time is elapsed, execute the if condition \n\t\t{\n\t\tGPIOA-&gt;ODR^=GPIO_ODR_OD5; \/\/toggle the led\n\t\tprevious=millis(); \/\/store current time \n\t\t}\n\t\n\t}\t\n\t\n\t}\n\t<\/pre><\/div>\n\n\n\n<p>Lastly, SysTick interrupt handler<\/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\nvoid SysTick_Handler(void){\nms++;\n}<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>In previous two guides (Understanding GPIOs and Understanding the Systick Timer) we explained how to use GPIOs in both input mode and output mode and how to use SysTick timer to generate delay. Delay is a function thats block the cpu for certain of time and can&#8217;t move beyond this point until the delay time [&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-246","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\/246"}],"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=246"}],"version-history":[{"count":4,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/246\/revisions"}],"predecessor-version":[{"id":257,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/246\/revisions\/257"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}