2011-11-01 04:36 AM
Dear forum users,
I use the STM32L152 with a RTOS.I need to wake up a task after a short delay (shorter than the time slot).
I think I will utilize a timer interrupt to release the mutex token in the delay routine.This routine will also be protect using a second mutex to avoid re-entrance issue.
My question relates to the timer configuration to get the behavior description above.
Could someone help me to configure and to use the timer ?
Thank you in advance Thoma2011-11-01 07:28 AM
Please define ''short'' using international measurement units.
2011-11-01 08:37 AM
Hi clive1,
I would define ''short'' as between tens of clock pulses (~1µs) and the time slot of my RTOS (~1ms).In the delay function, I will take the mutex and then I will start a timer (countdown) with the delay expressed in clock pulses.
When it reaches 0x00000000, it will raise an interrupt and I will give the mutex back.
Currently, I have no idea on how to configure the timer? And which timer can be use for this kind of operation?
Thank you.
Thoma2011-11-01 12:32 PM
It's going to depend a lot on what resources you have to spare. You can pretty much use any timer.
I guess if I had TIM2 set up with a period of (10000 - 1), so that the update interrupt fell once every 1 ms, I could then use one of the 4 channels in compare mode to mark off events in the future. The timer would always be configured so you wouldn't need to set it up for each event. For example, something like current = TIM_GetCounter(TIM2); TIM_SetCompare4(TIM2, current + 10); // 1us in the future or TIM_SetCompare4(TIM2, 65535); // Off, park out of range void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 1ms event } else if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_CC4); TIM_SetCompare4(TIM2, 65535); // Out-of-scope // one-shot event } }2011-11-05 02:30 PM
Hi clive1,
Many thanks for your suggestion. Here is the final code: initialization:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 0x7FFF; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 1000000) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active; TIM_OCInitStructure.TIM_Pulse = 0xFFFF; /* Out of scope */ TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM3, DISABLE); TIM_Cmd(TIM3, ENABLE); TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE); interrupt code:if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{ TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); TIM_SetCompare1(TIM3, 0xFFFF); /* Disable the interrupt by putting the compare value out of range */ giveSemaphore(); } delay function:unsigned long current;
lockFunction();
current = TIM_GetCounter(TIM3); current += delay; current &= 0x7FFF; TIM_SetCompare1(TIM3, current); takeSemaphore(); unlockFunction(); I chose a period of 32768 to simplify the computation of counter looping. Thoma