cancel
Showing results for 
Search instead for 
Did you mean: 

Is this the right way to generate a one shot delay using TIM4?

aa_talaat
Associate II
Posted on October 29, 2014 at 03:58

Hi,

I am trying to create a debounce delay (10ms at 8MHz clock) using TIM4CH1. Is the following the right way to do it? The TIM4_Configuration function is called at program startup, then whenever I need to delay (when within the EXTI ISR), I call the enableDebounceTimer function which generates an interrupt upon timer expiration. Within the Timer ISR, first thing I do is to call disableDebounceTimer function to disable the timer.

void TIM4_Configuration (){
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE );
/* Enable the TIM4 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Time base configuration */
TIM_TimeBaseInitStruct.TIM_Period = 65535;
TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
TIM_TimeBaseInitStruct.TIM_ClockDivision = 80;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
/* Output Compare Timing Mode configuration: Channel1 */
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 1000; // Core Clock 8Mhz, we need 10ms interrupt
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
/* configure output compare of TIM4 CH1 */
TIM_OC1Init(TIM4, &TIM_OCInitStruct);
}
/*
* Loads the timer with a 10ms debouce delay, and configure it to generate an interrupt once expired
*/
void enableDebounceTimer(void) {
/* TIM4 enable counter */
TIM_SetCounter(TIM4,0); // Reset its counter
TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE); // Enable TIM Interrupt
TIM_Cmd(TIM4, ENABLE); // Enable Timer
}
/*
* Disable timer, and clear all interrupts
*/
void disableDebounceTimer(void) {
TIM_Cmd(TIM4, DISABLE); // Disable Timer
TIM_ITConfig(TIM4, TIM_IT_CC1, DISABLE); // Enable TIM Interrupt
TIM_SetCounter(TIM4,0); // Reset its counter
TIM_ClearITPendingBit(TIM4, TIM_IT_CC1); // Clear any pending interrupt bit so that we do not come here again
}

1 REPLY 1
aa_talaat
Associate II
Posted on October 30, 2014 at 11:42

Hi,

I do not think that there is a need to involve Output compare as all what I need is software delay without any hardware reflection on external pins. Here is another way for doing it.

*
* TIM4 configures to generate an interrupt each 20ms
*
*/
void TIM4_Configuration (){
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE );
/* Enable the TIM4 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Time base configuration */
// TIM2 frequency = counter clock / (period + 1) = 1000 / (19+1) = 50 Hz --> 20ms
// Prescaler = (SystemCoreClock / Fx) - 1 where FX is the timer clock we want to use
TIM_TimeBaseInitStruct.TIM_Period = 19;
TIM_TimeBaseInitStruct.TIM_Prescaler = (uint16_t) (SystemCoreClock / 1000) - 1;
TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
}
/*
* Loads the timer with a 10ms debouce delay, and configure it to generate an interrupt once expired
*/
void enableDebounceTimer(void) {
/* TIM4 enable counter */
TIM_SetCounter(TIM4,0); // Reset its counter
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); // Enable TIM Interrupt
TIM_Cmd(TIM4, ENABLE); // Enable Timer
}
/*
* Disable timer, and clear all interrupts
*/
void disableDebounceTimer(void) {
TIM_Cmd(TIM4, DISABLE); // Disable Timer
TIM_ITConfig(TIM4, TIM_IT_Update, DISABLE); // Disable TIM Interrupt
TIM_SetCounter(TIM4,0); // Reset its counter
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); // Clear any pending interrupt bit so that we do not come here again
}