2013-01-24 05:48 AM
Hi all,
My TIM3 timer is setup to run at 10Khz which it does when i compile with -O0.When i compile with -03 or -Os, the timer speed increases to 20khz.All other build configs (gcc, linker, libs, etc) stay the same.The compiler is ''arm-none-eabi-gcc (Sourcery CodeBench Lite 2012.03-56) 4.6.3''.Can anyone hazard a guess as to why this might happen?Ive looked at everything i can think of with no result.Thanks!!2013-01-24 06:02 AM
Which device?
Post a minimal but complete compilable code (a blinky perhaps), exhibiting the problem. JW2013-01-24 08:43 AM
Can anyone hazard a guess as to why this might happen?
You fail to completely initialize auto/local variables/structures, which now contain random junk on the stack. If you post code it might be obvious.
2013-01-25 02:45 AM
Yup, sorry, its a STM32F103RC.
TIM3 init looks like:static void GPIO_TIM3_Setup()
{
// Setup 10KHz TIM3 timer
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
// TIM3 periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// Set up the TIM3 UP Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //top priority
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Time Base configuration. The timer input clock is 36MHz on APB1. We
// need to divide this by 3600 in order to get the 10kHz interrupt.
TIM_TimeBaseStructure.TIM_Prescaler = 3600;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//start
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
Thanks for the help...
2013-01-25 03:08 AM
Referring to your example code, that means for instance to call
TIM_TimeBaseStructInit (&TIM_TimeBaseStructure);
before starting to initialize it. Local variables are place on the stack, which contains junk from former usage. with different optimization levels, the stack usage may change. If no interrupts are involved up to that point, the ''junk'' could be the same every time, giving you a consistant misbehavior. You wouldn't be the first one to stumble across that ...2013-01-25 04:15 AM
''The counter clock frequency CK_CNT is equal to ***_PSC / (PSC[15:0] + 1).''
You would rather use this:// need to divide this by 3600 in order to get the 10kHz interrupt.
TIM_TimeBaseStructure.TIM_Prescaler = 3600 - 1;
10/20 kHz problem bay be related to the fact that TIM clock equals APB1 if ABP1 prescaler==1, otherwise TIM clock is APB1 x2.
2013-01-25 04:22 AM
A better way to do 10 KHz
TIM_TimeBaseStructure.TIM_Prescaler = 1; // APB1 at 36MHz, TIMCLK at 72MHz TIM_TimeBaseStructure.TIM_Period = 3600 - 1; Remember they that N-1 parameters, and you want the Counter portion to count, which means a Period >0 The problem I suspect however is in your IRQ code, it is important that you clear the pending IRQ first, if you do it as the last thing before you leave you expose a pipeline/race condition in the core, and it immediately tail-chains into your routine for a second time. Clear it as you enter.2013-01-30 07:25 PM
Clearing the IRQ on entering was the fix.
Thanks Clive, and others!