Reputation: 126
I am using STM32L476 Nucleo board and STM32CubeMX. I want to use Output Compare channel 1 for timeout of 2 ms. I have configured the timer, but the timer is not giving interrupts for Output Compare. I am getting interrupts for the period I gave to the timer, but not for output compare.
Here is my timer configuration:
static void MX_TIM1_Init(void)
{
/* USER CODE BEGIN TIM1_Init 0 */
/* USER CODE END TIM1_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
/* USER CODE BEGIN TIM1_Init 1 */
/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = TIMER1_PRESCALER_VAL;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = TIMER_PERIOD;
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_OC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
sSlaveConfig.InputTrigger = TIM_TS_ITR0;
if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
sConfigOC.Pulse = 1000 * TIMER_OC_1_VAL;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */
HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
}
I tried changing the sConfigOC.Pulse
value but I don't see the expected behavior.
Upvotes: 2
Views: 6486
Reputation: 125
First, you have to initialize the output pin before starting the timer like that:
/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);
/* USER CODE BEGIN TIM1_Init 2 */
HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);
Second, you have to start the Output timer
HAL_TIM_OC_Start_IT( &htim1, TIM_CHANNEL_1 );
HAL_TIM_Base_Start_IT( &htim1 );
Yyour output pin are enable like that: (this code is for Stm32F4xx)
GPIO_InitStruct.Pin = GPIO_PIN_9; // channel 1
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
I am not sure you need the BREAK code. Have a look 17.3.12 Using the break function in the Reference Manual
Upvotes: 0
Reputation: 13
Do you check for the right interrupt flag in the interrupt handler? Also keep in mind that you have to clear the flag right away.
My IRQHandler looks like this, if this is any help for you.
void TIM3_IRQHandler(void) {
if(LL_TIM_IsActiveFlag_CC1(TIM3) == 1) {
LL_TIM_ClearFlag_CC1(TIM3);
TimerCaptureCompare_Callback();
}
}
Edit:
OK as it seems, the HAL_TIM_OC_DelayElapsedCallback
interrupt is only fired when the timer overflows (i. e., resets).
This means that you have to enable the overflow interrupt, as the HAL_TIM_OC_Start_IT
only enables the capture/compare interrupt.
You only need to enable it before enabling the timer.
__HAL_TIM_ENABLE_IT(&tim3, TIM_IT_UPDATE );
Upvotes: 1