0
\$\begingroup\$

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!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Why do you call HAL_TIM_OC_MspInit() from main.c instead of MX_TIM1_Init()? Does MX_TIM1_Init() ever get called? \$\endgroup\$
    – kkrambo
    Apr 20, 2017 at 20:03
  • \$\begingroup\$ My bad. Yes it is called. MX_USART1_UART_Init(); MX_TIM1_Init(); \$\endgroup\$ Apr 21, 2017 at 8:22
  • \$\begingroup\$ HAL_TIM_OC_MspInit() will be called from HAL_TIM_OC_Init() (see the implementation in stm32*_hal_tim.c). You don't need to call HAL_TIM_OC_MspInit() directly. Show the implementation of HAL_TIM_OC_MspInit(). \$\endgroup\$
    – kkrambo
    Apr 21, 2017 at 13:06
  • \$\begingroup\$ Here it is: 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\$ Apr 21, 2017 at 19:23
  • \$\begingroup\$ Do you call HAL_TIM_OC_Start_IT()? That may be necessary. \$\endgroup\$
    – kkrambo
    Apr 21, 2017 at 19:49

2 Answers 2

1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\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\$ Apr 22, 2017 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.