cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Problem with Timer OVF

luk
Associate II
Posted on October 19, 2016 at 07:28

Hi all,

i have a problem with my program but i can not find the error. Maybe here is one who knows what i'm doing wrong. I want to meassure the time between two edges. I works most of the time, but sometimes the value would be correct just with one OVF two much. So for example (timer runs with 16Mhz) when i meassure 12kHz (via signal generator) most of the time the µC shows the right measurement (1333) but sometimes it shows ''66869'', so one OVF which shouldn't be there. This happens only, when the value ''new'' ist exactly ''65535''. So my thought was that the OVF Interrupt happens before the Capture Interrupt, but normally that shouldn't happen due to the Priority i set? Here is my Code:

void InterruptInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// Clock Enable
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// Clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
// Config PD13 als Digital-Ausgang
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// Config des Pins PE11 als AF-Input
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE, &GPIO_InitStructure);
// Connect PE11 with TIM1 for Input Capture
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Channel 2
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x02; //0x02 = 4 consecutive events are needed to validate a transition on the output
TIM_ICInit(TIM1, &TIM_ICInitStructure);
//Interrupt Enable
TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
// Timer enable
TIM_Cmd(TIM1, ENABLE);
}
//-----------------
// TIM1 OVF Handler
//-----------------
void TIM1_UP_TIM10_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
// Delete Interrupt Flags
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
OVF_cnt++;
}
}
//-------------------------------
// TIM1 Capture Interrupt Handler
//-------------------------------
void TIM1_CC_IRQHandler(void)
{
if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)
{
__disable_irq();
// Delete Interrupt Flags
TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
uint16_t new = TIM_GetCapture2(TIM1);
uint8_t OVF = OVF_cnt;
OVF_cnt = 0;
uint32_t period_32 = 0;
period_32 = ((uint32_t)new + (OVF << 16)) - old;
old = new;
__enable_irq();
}
}

Thanks in advance mark
2 REPLIES 2
Posted on October 19, 2016 at 11:05

> So my thought was that the OVF Interrupt happens before the Capture Interrupt,

> but normally that shouldn't happen due to the Priority i set? 

From PM0214:

A lower priority value indicating a higher priority.

 

[...]

 

A programmable priority level of 0-15 for each interrupt. A higher level corresponds to a

 

lower priority, so level 0 is the highest interrupt priority

 

 

 

JW

 

Walid FTITI_O
Senior II
Posted on October 20, 2016 at 17:04

Hi

wer.mark,

Usually whoever has higher preemption priority can be executed first, this is always happening with nested interrupts. when 2 interrupts have same preemption priority, then the one who has higher sub priority will be execute first. If both interrupts both have same preemption priority and sub priority, the one comes first will be execute first(first come first serve).

So to make the Capture compare interrupt the highest priority interrupt make the following modification (example):

NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

-Hannibal-