I have a program which sets the TIMER1 on the STM32F103 as Output Compare no Output.
In the main.c I have a simple variable, which I set to 1, and in the interrupt handler of TIM1 I have set it up so that variable is 2. In main, I also send the value of the said variable every one second.
All I get on UART is "1111", so the interrupt is never called. Why is that?
main.c:
uint16_t testPixel = 1;
uint8_t myChar[5];
[...]
HAL_TIM_OC_MspInit(&htim1);
[...]
while (1)
{
itoa(testPixel, myChar, 10);
HAL_UART_Transmit(&huart1,myChar,sizeof(myChar),10);
HAL_Delay(1000);
}
TIM1 set-up generated by CubeMX
static void MX_TIM1_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 80-1;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 10;
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.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
}
stm32f1xx_it.c:
extern testPixel;
[...]
void TIM1_UP_IRQHandler(void)
{
testPixel = 2;
HAL_TIM_IRQHandler(&htim1);
}
Thank you!
2 Answers 2
This function need to be called in order for the interrupt handler to be called:
HAL_TIM_Base_Start_IT(&htim1);
Thank you kkrambo for the tip, although it wasn't HAL_TIM_OC_Start_IT(), but the one above.
Are you sure that interrupt is no called? Even if , it is very probable tha you will only see the "1"s why?
You forgot the magic word "volatile". It is very likely any use use of TestPixel will be optimised out by the compiler. In your example if TestPixel is not changed anywhere in the main program that itoa will be taken out from the while loop, as the compiler does not see any parts of the code, where this variable could be possible changed.
-
\$\begingroup\$ I tried using volatile, still didn't work. I also tried to put into the IRQ handler
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
, so the LED should be half bright (togglig on-off 50% duty cycle), but it doesn't. \$\endgroup\$Cezar Chirila– Cezar Chirila2017年04月22日 16:23:12 +00:00Commented Apr 22, 2017 at 16:23
HAL_TIM_OC_MspInit()
from main.c instead ofMX_TIM1_Init()
? DoesMX_TIM1_Init()
ever get called? \$\endgroup\$HAL_TIM_OC_MspInit()
will be called fromHAL_TIM_OC_Init()
(see the implementation in stm32*_hal_tim.c). You don't need to callHAL_TIM_OC_MspInit()
directly. Show the implementation ofHAL_TIM_OC_MspInit()
. \$\endgroup\$void HAL_TIM_OC_MspInit(TIM_HandleTypeDef* htim_oc) { if(htim_oc->Instance==TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); HAL_NVIC_SetPriority(TIM1_UP_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); } }
The NVIC is set and the clock is started, is there something missing? I'm just thinking, what if the interrupt is called, but the way I use "extern testPixel" is wrong? \$\endgroup\$HAL_TIM_OC_Start_IT()
? That may be necessary. \$\endgroup\$