{"id":3102,"date":"2024-12-27T14:05:01","date_gmt":"2024-12-27T14:05:01","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=3102"},"modified":"2024-12-27T14:05:04","modified_gmt":"2024-12-27T14:05:04","slug":"getting-started-with-stm32h5-arm-cortex-m33-timer-interrupt","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=3102","title":{"rendered":"Getting Started with STM32H5 ARM Cortex M33:\u00a0Timer Interrupt"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"725\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-1024x725.webp\" alt=\"\" class=\"wp-image-3103\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-1024x725.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-300x212.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-768x544.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-750x531.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-400x283.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3-250x177.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/STM32-u5-1-1-3.webp 1141w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall use timer to generate interrupt for precise time control for our application.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>What in timer interrupt.<\/li>\n\n\n\n<li>STM32CubeMX setup.<\/li>\n\n\n\n<li>Firmware development.<\/li>\n\n\n\n<li>Results.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is Timer Interrupt:<\/h2>\n\n\n\n<p>A&nbsp;<strong>timer interrupt<\/strong>&nbsp;in a microcontroller is a mechanism where the microcontroller generates an interrupt signal based on events associated with a timer peripheral. These events can include reaching a specific count, an overflow, or a match between the timer count and a predefined value. The timer interrupt allows the microcontroller to execute a specific task (Interrupt Service Routine, ISR) in response to the timer event without continuously polling the timer status.<\/p>\n\n\n\n<p><strong>How Timer Interrupt Works<\/strong><\/p>\n\n\n\n<p>1. <strong>Timer Peripheral<\/strong>:<\/p>\n\n\n\n<p>\u2022 A timer is a hardware module in the microcontroller that increments or decrements a counter at a fixed rate, derived from the system clock or a prescaled clock.<\/p>\n\n\n\n<p>2. <strong>Event Generation<\/strong>:<\/p>\n\n\n\n<p>\u2022 As the timer runs, it can trigger events such as:<\/p>\n\n\n\n<p>\u2022 Overflow (counter rolls back to zero).<\/p>\n\n\n\n<p>\u2022 Match with a specific compare value.<\/p>\n\n\n\n<p>\u2022 A trigger input or external signal.<\/p>\n\n\n\n<p>3. <strong>Interrupt Request (IRQ)<\/strong>:<\/p>\n\n\n\n<p>\u2022 When the specified event occurs, the timer generates an interrupt request (IRQ) to the CPU.<\/p>\n\n\n\n<p>4. <strong>Interrupt Service Routine (ISR)<\/strong>:<\/p>\n\n\n\n<p>\u2022 The microcontroller pauses its main program to execute a small function (ISR) associated with the timer interrupt.<\/p>\n\n\n\n<p>5. <strong>Return to Main Program<\/strong>:<\/p>\n\n\n\n<p>\u2022 After the ISR finishes, the CPU resumes executing the main program from where it left off.<\/p>\n\n\n\n<p><strong>Why Use Timer Interrupts?<\/strong><\/p>\n\n\n\n<p>1. <strong>Precise Timing<\/strong>:<\/p>\n\n\n\n<p>\u2022 Timer interrupts provide highly accurate timing, independent of the program\u2019s execution state.<\/p>\n\n\n\n<p>2. <strong>Non-blocking Delays<\/strong>:<\/p>\n\n\n\n<p>\u2022 Unlike software delays, a timer interrupt allows the microcontroller to perform other tasks while waiting for the timer event.<\/p>\n\n\n\n<p>3. <strong>Periodic Tasks<\/strong>:<\/p>\n\n\n\n<p>\u2022 Execute tasks at regular intervals (e.g., sampling a sensor every 1 ms).<\/p>\n\n\n\n<p>4. <strong>Event Timing<\/strong>:<\/p>\n\n\n\n<p>\u2022 Measure durations or count specific events (e.g., pulses in an encoder).<\/p>\n\n\n\n<p><strong>Key Components of Timer Interrupts<\/strong><\/p>\n\n\n\n<p>1. <strong>Timer Counter<\/strong>:<\/p>\n\n\n\n<p>\u2022 The main register that counts up or down based on the timer\u2019s clock.<\/p>\n\n\n\n<p>2. <strong>Prescaler<\/strong>:<\/p>\n\n\n\n<p>\u2022 Divides the clock frequency to adjust the timer\u2019s counting speed.<\/p>\n\n\n\n<p>3. <strong>Compare Registers<\/strong>:<\/p>\n\n\n\n<p>\u2022 Define specific count values that trigger interrupts.<\/p>\n\n\n\n<p>4. <strong>Interrupt Flags<\/strong>:<\/p>\n\n\n\n<p>\u2022 Indicate the occurrence of a timer event and need to be cleared in the ISR.<\/p>\n\n\n\n<p>5. <strong>NVIC (Nested Vectored Interrupt Controller)<\/strong>:<\/p>\n\n\n\n<p>\u2022 Manages the priority and execution of interrupts.<\/p>\n\n\n\n<p><strong>Applications of Timer Interrupts<\/strong><\/p>\n\n\n\n<p>1. <strong>Real-Time Clock<\/strong>:<\/p>\n\n\n\n<p>\u2022 Generate accurate time intervals (e.g., 1-second ticks).<\/p>\n\n\n\n<p>2. <strong>PWM Generation<\/strong>:<\/p>\n\n\n\n<p>\u2022 Create precise Pulse Width Modulation signals for motor control or LED dimming.<\/p>\n\n\n\n<p>3. <strong>Frequency Measurement<\/strong>:<\/p>\n\n\n\n<p>\u2022 Measure signal frequency by counting pulses within a fixed time.<\/p>\n\n\n\n<p>4. <strong>Sensor Sampling<\/strong>:<\/p>\n\n\n\n<p>\u2022 Read data from sensors at regular intervals.<\/p>\n\n\n\n<p>5. <strong>Debouncing<\/strong>:<\/p>\n\n\n\n<p>\u2022 Avoid false triggers in button presses by implementing debouncing logic.<\/p>\n\n\n\n<p>6. <strong>Communication Protocols<\/strong>:<\/p>\n\n\n\n<p>\u2022 Time-critical operations like UART bit sampling or SPI communication.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. STM32CubeMX Configuration:<\/h2>\n\n\n\n<p>Create new project with name of Timer_Interrupt. For how to create new project for STM32H5, please refer to this guide <a href=\"https:\/\/blog.embeddedexpert.io\/?p=2789\" data-type=\"link\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2789\">here<\/a>.<\/p>\n\n\n\n<p>After the project creation, enable TIM2 and TIM3 as following:<\/p>\n\n\n\n<p>Enabling TIM2:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"670\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-1024x670.jpg\" alt=\"\" class=\"wp-image-3105\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-1024x670.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-300x196.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-768x502.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-1536x1005.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-1150x752.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-750x491.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-400x262.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20-250x164.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-39-20.jpg 1920w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>From timers, select TIM2 and set the clock source to be internal.<\/p>\n\n\n\n<p>In similar manner, enable the clock to TIM3.<\/p>\n\n\n\n<p>Next from clock configuration, we need to find the frequencies of the timers:<\/p>\n\n\n\n<p>By default, STM32H563Zi is running at 32MHz. Hence, the timers are 32MHz in speed.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"502\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1024x502.jpg\" alt=\"\" class=\"wp-image-3011\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1024x502.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-300x147.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-768x376.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1536x753.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-2048x1004.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-1150x564.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-750x368.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-400x196.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/11\/2024-11-17_06-25-54-250x123.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, we can configure TIM2 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-756x1024.jpg\" alt=\"\" class=\"wp-image-3107\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-756x1024.jpg 756w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-221x300.jpg 221w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-768x1041.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-1133x1536.jpg 1133w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-1150x1558.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-750x1016.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-400x542.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1-250x339.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-43-40-1.jpg 1194w\" sizes=\"(max-width: 756px) 100vw, 756px\" \/><\/figure>\n\n\n\n<p>Set the prescaler to 32000-1 which will reduce the timer frequency to 1KHz (32MHz\/32KHz = 1KHz).<\/p>\n\n\n\n<p>Set the ARR to 1000-1, this will let the timer to count to 1000 which will give 1 second (1KHz\/1KHz= 1Hz = 1 second).<\/p>\n\n\n\n<p>From the NVIC, enable timer2 global interrupt as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"996\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-996x1024.jpg\" alt=\"\" class=\"wp-image-3108\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-996x1024.jpg 996w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-292x300.jpg 292w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-768x789.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-1150x1182.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-750x771.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-400x411.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35-250x257.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-46-35.jpg 1226w\" sizes=\"(max-width: 996px) 100vw, 996px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>For TIM3, the configuration as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"970\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-1024x970.jpg\" alt=\"\" class=\"wp-image-3109\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-1024x970.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-300x284.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-768x727.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-1150x1089.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-750x710.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-400x379.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55-250x237.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-47-55.jpg 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Set the prescaler to 32000-1.<\/p>\n\n\n\n<p>Set the period to be 2000-1 which will provide interrupt each 2 seconds.<\/p>\n\n\n\n<p>Also, enable the interrupt for TIM3 as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1010\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-1024x1010.jpg\" alt=\"\" class=\"wp-image-3110\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-1024x1010.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-300x296.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-768x758.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-1150x1134.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-750x740.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-400x395.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37-250x247.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-49-37.jpg 1184w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Also, enable UART, for how to enable UART, please refer to this guide <a href=\"https:\/\/blog.embeddedexpert.io\/?p=2844\" data-type=\"link\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=2844\">here<\/a>.<\/p>\n\n\n\n<p>Save the project this will generate the project.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Firmware Development:<\/h2>\n\n\n\n<p>Once the project has been generated, in main.c file, in user begin PV (Private variable), declare the following two volatile variables 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;}\">volatile uint8_t tim2_done=0, tim3_done=0;<\/pre><\/div>\n\n\n\n<p>These two variables are the flag to tell the firmware that the interrupt is generated.<\/p>\n\n\n\n<p>Also, declare a buffer to hold data to be transmitted over UART 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;}\">uint8_t uart_data[100]={0};<\/pre><\/div>\n\n\n\n<p>Next, in user code begin 2of the main function, start both timer in the interrupt 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;}\">  HAL_TIM_Base_Start_IT(&amp;htim2);\n  HAL_TIM_Base_Start_IT(&amp;htim3);<\/pre><\/div>\n\n\n\n<p>The function HAL_TIM_Base_Start_IT will start the timer in counting mode and generate interrupt periodically.<\/p>\n\n\n\n<p>In user code begin 3 of while 1 loop:<\/p>\n\n\n\n<p>Check if the interrupt is generate, if yes, reset the variable and print the interrupt source 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;}\">uint16_t len;\n\t  if(tim2_done==1)\n\t  {\n\t\t  tim2_done=0;\n\t\t  len=sprintf(uart_data,&quot;Timer 2 interrupt triggered\\r\\n&quot;);\n\t\t  HAL_UART_Transmit(&amp;huart3, uart_data, len, 100);\n\t  }\n\n\t  if(tim3_done==1)\n\t  {\n\t\t  tim3_done=0;\n\t\t  len=sprintf(uart_data,&quot;Timer 3 interrupt triggered\\r\\n&quot;);\n\t\t  HAL_UART_Transmit(&amp;huart3, uart_data, len, 100);\n\t  }<\/pre><\/div>\n\n\n\n<p>The len variable shall store the length of the string to be sent. Usually, sprintf returns number of the characters.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Next, open stm32h5xx_hal_tim.c source file as following and locate the following function:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"538\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-1024x538.jpg\" alt=\"\" class=\"wp-image-3111\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-1024x538.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-300x158.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-768x404.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-1536x808.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-2048x1077.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-1150x605.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-750x394.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-400x210.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-57-58-250x131.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The 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;}\">void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)<\/pre><\/div>\n\n\n\n<p>Shall be called each time the timer has overflowed (reaches to the maximum value and get back to zero).<\/p>\n\n\n\n<p>Since this function is declared as weak, the user can override this function is his firmware.<\/p>\n\n\n\n<p>In user code begin 4 of the main.c file, declare the function 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;}\">void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)\n{\n\tif(htim-&gt;Instance ==TIM2)\n\t{\n\t\ttim2_done=1;\n\t}\n\n\tif(htim-&gt;Instance ==TIM3)\n\t{\n\t\ttim3_done=1;\n\t}\n\n}<\/pre><\/div>\n\n\n\n<p>Within the function, check which timer is the source of the interrupt and set the flag.<\/p>\n\n\n\n<p>Thats all for the guide.<\/p>\n\n\n\n<p>Save the project, build it and run it on your STM32H563Zi board.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"28\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-1024x28.png\" alt=\"\" class=\"wp-image-2849\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-1024x28.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-300x8.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-768x21.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-1536x43.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-1150x32.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-750x21.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-400x11.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image-250x7.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/09\/image.png 1734w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Results:<\/h2>\n\n\n\n<p>Open your favourite terminal application, set the baudrate to be 115200 and you should see the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"733\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-1024x733.jpg\" alt=\"\" class=\"wp-image-3112\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-1024x733.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-300x215.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-768x550.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-1150x823.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-750x537.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-400x286.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51-250x179.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/12\/2024-12-27_16-22-51.jpg 1168w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Notice that timer 2 interrupt triggered is twice compared to timer 3 which is what we set in the CubeMX.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude09<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall use timer to generate interrupt for precise time control for our application. In this guide, we shall cover the following: 1. What is Timer Interrupt: A&nbsp;timer interrupt&nbsp;in a microcontroller is a mechanism where the microcontroller generates an interrupt signal based on events associated with a timer peripheral. These events can [&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-3102","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\/3102"}],"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=3102"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3102\/revisions"}],"predecessor-version":[{"id":3113,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/3102\/revisions\/3113"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}