I've been trying for 2 days now to get my Output Compare to trigger a function.
I've been reading up on it, and there is a callback function that, from what I understand, is triggered when an output compare is triggered: HAL_TIM_OC_DelayElapsedCallback()
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim){ if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){ HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET); } if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4){ HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET); } } When I put a breakpoint on this function, I noticed that my program never entered it, even though I have 2 outputs compare that are triggered every second.
I don't know where to look anymore,
So I have my timer3 with channels 2 and 4 in output compare, in toggle on match mode. My timer has a period of 1000 and my channel 2 has a pulse at 250 and channel 750.
The timer channels are connected to the pins of the 2 LEDs, when the OUTPUT compare is triggered, it turns the LEDs on and off at regular intervals.
My idea was that with the output compare callback function when an output compare is triggered, it turns on the LEDs, so there is no need to connect the timer channels directly to the PINS of the 2 LEDs.
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> /* 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 htim3; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM3_Init(void); /* USER CODE BEGIN PFP */ /* 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_TIM3_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_2); HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4); /* 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}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); /** 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.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 15; RCC_OscInitStruct.PLL.PLLN = 144; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 5; 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_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { Error_Handler(); } } /** * @brief TIM3 Initialization Function * @param None * @retval None */ static void MX_TIM3_Init(void) { /* USER CODE BEGIN TIM3_Init 0 */ /* USER CODE END TIM3_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; /* USER CODE BEGIN TIM3_Init 1 */ /* USER CODE END TIM3_Init 1 */ htim3.Instance = TIM3; htim3.Init.Prescaler = 16000; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 1000; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_OC_Init(&htim3) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; sConfigOC.Pulse = 250; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = 750; if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ HAL_TIM_MspPostInit(&htim3); } /** * @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_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); /*Configure GPIO pin : PA5 */ GPIO_InitStruct.Pin = GPIO_PIN_5; 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 HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim){ if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){ HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET); } if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4){ HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET); } } /* USER CODE END 4 */ !!! Note that my program doesn't initialize the LEDs, for the moment I just want to see in debug mode if my program enters the function when a compare output is triggered, and already that, it doesn't work...
EDIT :thank you for your answers, by modifying HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_2); by HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_2); and by activating the interrupts HAL_NVIC_EnableIRQ(TIM3_IRQn); my program enters the HAL_TIM_OC_DelayElapsedCallback function.
On the other hand, by wanting to create the RQHandler function,
void TIM3_IRQHandler(void){ HAL_TIM_IRQHandler(&htim3); } I get a first defined here error, I don't know if this function is useful for the rest of my problem:
Now that my program enters the callback function of the output compare, it doesn't seem to compare, I explain myself:
I thought the lines:
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) were going to check if the output compare of channel 2 or 4 is enabled, and if so, do what's in my condition. But, that's not what happens.
My program always enters the conditions.
I did a test to verify this:
I changed the value of my comparative output from channel 4 to 1500. The period of my timer is 1000, so this compare output should never be triggered. But it still triggers, my program enters the condition : if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) when it should not.
I don't know why, I still feel like I'm forgetting something lol

HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_2);instead ofHAL_TIM_OC_Start(&htim3, TIM_CHANNEL_2);. Additionally, you could check the HAL and LL documentation ST has on their website. \$\endgroup\$