Building 0s/03 doubles timer speed?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-24 5: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!!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-24 6:02 AM
Which device?
Post a minimal but complete compilable code (a blinky perhaps), exhibiting the problem. JW- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-24 8: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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-25 2: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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-25 3: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 ...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-25 4: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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-25 4: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.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-01-30 7:25 PM
Clearing the IRQ on entering was the fix.
Thanks Clive, and others!