Skip to main content
chriskuku
Senior II
November 28, 2022
Question

Starting one shot TIM1 and catching interrupt of count down event

  • November 28, 2022
  • 11 replies
  • 4636 views

My idea is, to implement a timer (TIM1 in this case).

Given a certain key pressed, I want to fire it up, let it count down causing an interrupt.

This are the parameters I gave it in the init procedure. (STM32F103C8T6)

static void MX_TIM1_Init(void)
{
 
 /* USER CODE BEGIN TIM1_Init 0 */
 
 /* USER CODE END TIM1_Init 0 */
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 /* USER CODE BEGIN TIM1_Init 1 */
 
 /* USER CODE END TIM1_Init 1 */
 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 7200;
 htim1.Init.CounterMode = TIM_COUNTERMODE_DOWN;
 htim1.Init.Period = 5000;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM1_Init 2 */
 
 /* USER CODE END TIM1_Init 2 */
 
}

1\ How to I start the timer?

2\ where do I find the IR service routine?

This topic has been closed for replies.

11 replies

chriskuku
chriskukuAuthor
Senior II
November 28, 2022

Or in other words: under which circumstances an ISR and callback routine is automatically being generated? At the moment I'm missing such.

waclawek.jan
Super User
November 28, 2022

> 1\ How to I start the timer?

By setting TIMx_CR1.CEN.

> 2\ where do I find the IR service routine?

Wherever you write it, just make sure it's name is identical with the name in the vector table, which is usually in the startup code.

> Or in other words: under which circumstances an ISR and callback routine is automatically being generated? At the moment I'm missing such.

OK so if this question was "how do I click in CubeMX so that this automagically works", I don't know, I don't use Cube/CubeMX.

JW

chriskuku
chriskukuAuthor
Senior II
November 29, 2022

Maybe I forgot to tic the Interrupt check box in the .ioc Timer configuration, since I didn't see an interrupt in the source file.

What is the interrupt that is fired, when the timer reaches 65536 (overflow). Is it the Tim1_BREAK interrupt? Or is it the Capture_Compare Interrupt?

chriskuku
chriskukuAuthor
Senior II
December 17, 2022

@Community member​ the much I appreciate your answer, but it isn't appropriate in my case. I don't like HAL either but I succeeded in one case and would like to stay with the (HAL based) program for now.

This is the code so far:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2022 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim1;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
/* USER CODE BEGIN PFP */
void pc13_on(void);
void pc13_off(void);
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
 
 /* MCU Configuration--------------------------------------------------------*/
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* USER CODE BEGIN Init */
 
 /* USER CODE END Init */
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* USER CODE BEGIN SysInit */
 
 /* USER CODE END SysInit */
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_TIM1_Init();
 /* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start(&htim1);
 HAL_TIM_Base_Start_IT(&htim1);
 /* USER CODE END 2 */
 
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
 
 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}
 
/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 
 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
 {
 Error_Handler();
 }
}
 
/**
 * @brief TIM1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_TIM1_Init(void)
{
 
 /* USER CODE BEGIN TIM1_Init 0 */
 
 /* USER CODE END TIM1_Init 0 */
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 /* USER CODE BEGIN TIM1_Init 1 */
 
 /* USER CODE END TIM1_Init 1 */
 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 7200;
 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim1.Init.Period = 15535;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM1_Init 2 */
 
 /* USER CODE END TIM1_Init 2 */
 
}
 
/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET);
 
 /*Configure GPIO pin : PC13 */
 GPIO_InitStruct.Pin = GPIO_PIN_13;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
 /*Configure GPIO pin : PA14 */
 GPIO_InitStruct.Pin = GPIO_PIN_14;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
}
 
/* USER CODE BEGIN 4 */
void pc13_off(){
	GPIOC->ODR=0xffffffff;
 
 
}
void pc13_on(){
	GPIOC->ODR=~(1<<13);
 
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
 pc13_off();
}
 
 
/* USER CODE END 4 */
 
/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}
 
#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * @param file: pointer to the source file name
 * @param line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

The purpose is to trigger the timer once and let it generate an interrupt after 0.5 s.

The timer code doesn't seem to land in the ISR.

AScha.3
Super User
December 17, 2022

set int active in Cube, [gen.code] , then see timer int in stm...xx_it.c file .

ex:

0693W00000WLEjPQAX.pngthen see in xx_it.c :

0693W00000WLEjUQAX.png

"If you feel a post has answered your question, please click ""Accept as Solution""."
chriskuku
chriskukuAuthor
Senior II
December 17, 2022

0693W00000WLElLQAX.png0693W00000WLEl6QAH.pngThanks.

I'm using TIM1. I don't see global interrupt. Also, why DMA2 stream0 global interrupt? I don't use DMA. Furthermore this is an STM32F103 (blue pill) and it doesn't have a TIM5.

AScha.3
Super User
December 17, 2022

hey, this was just example (from my H743 ), to show you , how to do.

you need click on the int you want to enable them !!!! x = enabled !

then : gen. -> get int in xxxit.c

"If you feel a post has answered your question, please click ""Accept as Solution""."
chriskuku
chriskukuAuthor
Senior II
December 17, 2022

OK, I now have this in stm32f1xx.c:

/**
 * @brief This function handles TIM4 global interrupt.
 */
void TIM4_IRQHandler(void)
{
 /* USER CODE BEGIN TIM4_IRQn 0 */
 
 /* USER CODE END TIM4_IRQn 0 */
 HAL_TIM_IRQHandler(&htim4);
 /* USER CODE BEGIN TIM4_IRQn 1 */
 
 /* USER CODE END TIM4_IRQn 1 */
}

with this longish:

/**
 * @brief This function handles TIM interrupts requests.
 * @param htim TIM handle
 * @retval None
 */
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
 /* Capture compare 1 event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET)
 {
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
 
 /* Input capture event */
 if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->IC_CaptureCallback(htim);
#else
 HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 /* Output compare event */
 else
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->OC_DelayElapsedCallback(htim);
 htim->PWM_PulseFinishedCallback(htim);
#else
 HAL_TIM_OC_DelayElapsedCallback(htim);
 HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
 }
 }
 }
 /* Capture compare 2 event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
 /* Input capture event */
 if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->IC_CaptureCallback(htim);
#else
 HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 /* Output compare event */
 else
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->OC_DelayElapsedCallback(htim);
 htim->PWM_PulseFinishedCallback(htim);
#else
 HAL_TIM_OC_DelayElapsedCallback(htim);
 HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
 }
 }
 /* Capture compare 3 event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
 /* Input capture event */
 if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->IC_CaptureCallback(htim);
#else
 HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 /* Output compare event */
 else
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->OC_DelayElapsedCallback(htim);
 htim->PWM_PulseFinishedCallback(htim);
#else
 HAL_TIM_OC_DelayElapsedCallback(htim);
 HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
 }
 }
 /* Capture compare 4 event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
 /* Input capture event */
 if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->IC_CaptureCallback(htim);
#else
 HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 /* Output compare event */
 else
 {
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->OC_DelayElapsedCallback(htim);
 htim->PWM_PulseFinishedCallback(htim);
#else
 HAL_TIM_OC_DelayElapsedCallback(htim);
 HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
 }
 }
 /* TIM Update event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->PeriodElapsedCallback(htim);
#else
 HAL_TIM_PeriodElapsedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 }
 /* TIM Break input event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->BreakCallback(htim);
#else
 HAL_TIMEx_BreakCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 }
 /* TIM Trigger detection event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->TriggerCallback(htim);
#else
 HAL_TIM_TriggerCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 }
 /* TIM commutation event */
 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
 {
 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) != RESET)
 {
 __HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->CommutationCallback(htim);
#else
 HAL_TIMEx_CommutCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
 }
 }
}

BTW, is the logic reversed ? :

USE_HAL_TIM_REGISTER_CALLBACKS == 1

Anyway, which callback would I have to implement? To recall: the timer should fire only once (oneshot).

AScha.3
Super User
December 18, 2022

>OK, I now have this in stm32f1xx.c:

  • so you have now, what you asked for

>which callback would I have to implement? 

  • why add and take callbacks now? use for...what?

>BTW, is the logic reversed ? :

  • your logic .. ?

and please dont post the HAL library code in full length, posting it is 100% useless.

"If you feel a post has answered your question, please click ""Accept as Solution""."
chriskuku
chriskukuAuthor
Senior II
December 18, 2022

@AScha.3​ :

> >which callback would I have to implement? 

> why add and take callbacks now? use for...what?

Use for what? To do something when the pulse duration has finished, which is normally done effectively by an ISR.

>>BTW, is the logic reversed ? :

> your logic .. ?

You are using my question to build ironical or insulting constructs against me?

Is this conformant with the guidelines of this forum? Moderator please?

I was asking and posting the HAL code, because I was wondering about e.g.:

#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
 htim->CommutationCallback(htim);
#else
 HAL_TIMEx_CommutCallback(htim);

so, if USE_HAL_TIM_REGISTER_CALLBACKS==1 (true), the code

htim->CommutationCallBack(htim);​ is executed, but isn't

HAL_TIMEx_CommutCallback(htim); the HAL_TIM_REGISTER_CALLBACK(s)?​

AScha.3
Super User
December 18, 2022

seem we dont understand each other, so i stop trying to help you. just ignore, what i wrote.

"If you feel a post has answered your question, please click ""Accept as Solution""."