2014-11-10 06:14 AM
Hi
I want to generate a timer interrupt after every 1micoseconds. I am using TIMER2 for this purpose.So I took a code from one site and modified for my purpose. But the issue is I cant get an interrupt of 1microsecond.To ensure this I toggled a gpio in the ISR and verified the frequency on DSO and it was found to be 806Khz. Is there anything that I'm doing wrong in the code? void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { count++; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); flag_for_state_machine=1; if(count%2 == 0) GPIO_ResetBits(GPIOD, GPIO_Pin_12); else GPIO_SetBits(GPIOD, GPIO_Pin_12); } } void configure_d1_d2_d3(void) { /* Enable the GPIO_LED Clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); } void INTTIM_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable the TIM2 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* TIM2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 1; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); } int main(void) { configure_d1_d2_d3(); INTTIM_Config(); while(1); } #discovery #stm32f4 #timers2014-11-10 06:47 AM
Interrupting at 1 MHz is ridiculously fast, think a bit harder about a better way to solve whatever problem you are trying to solve.
TIM_TimeBaseStructure.TIM_Period = 1; // Like 84 MHz / 2? WTF? TIM_TimeBaseStructure.TIM_Prescaler = 0;2014-11-10 06:51 AM
TIM_TimeBaseStructure.TIM_Period = ((SystemCoreClock / 2) / 1000000) - 1; // 1 MHz (1us)
Toggling will HALF the measured frequency. So if the interrupt occurs at 1 MHz (1 us) the pin frequency will be 500 KHz2014-11-10 06:59 AM
IMHO, you should ask yourself how to execute the following under 1us:
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
count++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
flag_for_state_machine=1;
if(count%2 == 0)
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
else
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
}
What about having a look at assembly code ? Then try to follow the flow or count instructions (beware 1 instruction may require more than one cycle).
Clive is right, there are very few use case that requires to go at that rate. What do you try to achieve ? Maybe it could be done in an other way (DMA ?).
2014-11-17 08:37 PM
Hi Clive,
Thanks for the reply, that worked If I want to generate interrupt at 2 Mhz (0.5microsec) How should I modify the above program?2014-11-18 06:09 AM
If this wasn't evident from the previous example:
TIM_TimeBaseStructure.TIM_Period = ((SystemCoreClock / 2) / 2000000) - 1; // 2 MHz You should really let the hardware do the toggling at these rates, it's not a viable rate to interrupt at, and at some point you will saturate the processor.