2016-10-18 10:28 PM
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
2016-10-19 02:05 AM
> 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
2016-10-20 08:04 AM
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-