2017-08-28 04:46 AM
Hello everyone,
I am setting up a project to make some tests with an STM32F7 MCU. I am using the STM32Cube HAL and the idea is to configure some timers and their interrupts using this HAL. The board is equipped with and 25MHz HSE so in the code I am configuring the HSE and disabling the PLL.
The problem is that if I don't write the SysTick_Handle() function inside my code the MCU and the interrupts don't work. The PC goes to the SysTick_Handler() defined inside 'startup_stm32f769xx.s'.
I am trying to understand why is it a must to define the SysTick_Handler() in the code so you can use the HAL properly but I am not sure whether I really understand why.
In the FAQs of the HAL manual the third step of the sequence to use the HAL drivers is:
'Add HAL_IncTick() function under SysTick_Handler() ISR function to enable polling process when using HAL_Delay() function'
But I am not using the HAL_Delay() function, so why I need to define it?
Anyone can help with this?
This is my code :
&sharpinclude <stm32f7xx_hal.h>
static TIM_HandleTypeDef s_TimerInstance;void SysTick_Handler(void){ HAL_IncTick(); HAL_SYSTICK_IRQHandler();}/*** @brief This function initializes the SystemClock as HSE* @param None* @retval None*/void initClock(){ RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; HAL_StatusTypeDef ret = HAL_OK; /* Enable Power Control clock */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF; ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); if(ret != HAL_OK){ while(1){;} } /* Select HSE as system clock source */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); if(ret != HAL_OK){ while(1){;} }}void InitializeTimer(){ __TIM6_CLK_ENABLE(); s_TimerInstance.Init.Prescaler = 512; s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP; s_TimerInstance.Init.Period = 65535; s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; s_TimerInstance.Instance = TIM6; HAL_TIM_Base_Init(&s_TimerInstance); HAL_TIM_Base_Start_IT(&s_TimerInstance);}void GPIO_Init(){ GPIO_InitTypeDef GPIO_InitStructure; __GPIOB_CLK_ENABLE(); __GPIOJ_CLK_ENABLE(); GPIO_InitStructure.Pin = GPIO_PIN_8; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.Pin = GPIO_PIN_13; HAL_GPIO_Init(GPIOJ, &GPIO_InitStructure);}void TIM6_DAC_IRQHandler(){ HAL_TIM_IRQHandler(&s_TimerInstance);}void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){ HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8); HAL_GPIO_TogglePin(GPIOJ, GPIO_PIN_13);}int main(void){ HAL_Init(); initClock(); GPIO_Init(); InitializeTimer(); HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); while(1){ }}Thanks in advanced,
Omar
#stm32f7 #interrupts #timer-interrupt #systick_handlerSolved! Go to Solution.
2017-08-28 05:19 AM
Hello!
'But I am not using the HAL_Delay() function, so why I need to define it?
Anyone can help with this?'
SYSTICK is not only used by HAL_Delay function.
Lot of HAL functions have internal timeouts based on this functionality.
HAL_IncTick() must be called every millisecond not necesarily from systick but from any other timer IRQ Handler (with hi priority ofcourse).
You have the right to redefine theese weak functions to control a different timer than systick.
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
void HAL_SuspendTick(void)
void HAL_ResumeTick(void)
Regards
vf
2017-08-28 05:19 AM
Hello!
'But I am not using the HAL_Delay() function, so why I need to define it?
Anyone can help with this?'
SYSTICK is not only used by HAL_Delay function.
Lot of HAL functions have internal timeouts based on this functionality.
HAL_IncTick() must be called every millisecond not necesarily from systick but from any other timer IRQ Handler (with hi priority ofcourse).
You have the right to redefine theese weak functions to control a different timer than systick.
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
void HAL_SuspendTick(void)
void HAL_ResumeTick(void)
Regards
vf
2017-08-28 06:38 AM
The use of the ticker is systemic to the HAL implementation, dangerously so, there are a vast number of blocking loops.
It is critical that the SysTick interrupt has the highest preemption level as your callback functions are occurring in interrupt context. Even for timeout loops one has to be skeptical of a design that can block in interrupt context for >1ms for no useful purpose.
There are some HAL/BSP implementation that use the RTC, HW counters, or TIM to generate the time base.
2017-08-28 08:20 AM
Thanks both for your fast replies.
Those were the answers I was looking for.
2017-08-28 09:45 AM
Also notice that many of the timeouts in the HAL read the timer tick count at the entry into the HAL call. And like the USART code, when calling it as a blocking call, checks for the timeout delta at the end of each byte being written. If you get interrupted away, the tick count keep going while interrupted away. When you return the output of the data my have worked on time, but the function will return a timeout error because the delta was larger than the timeout value passed in.
2017-11-14 09:52 AM
s_TimerInstance.Init.Prescaler = 512; // Divide by 513 ? Value here is N-1 for N states, ie 0..N-1