Hello, I configured a timer to generate a signal every 1 ms.
See below my code about the timer:
TIM_DeInit(TIMx); // TIM1 Deinitialization * TIM_InitStructure.TIM_Mode = TIM_OCM_CHANNEL_1; TIM_InitStructure.TIM_OC1_Modes = TIM_TIMING; TIM_InitStructure.TIM_Clock_Source = TIM_CLK_APB; TIM_InitStructure.TIM_Clock_Edge = TIM_CLK_EDGE_FALLING; TIM_InitStructure.TIM_Prescaler = 0xEF; // period = 5us TIM_InitStructure.TIM_Pulse_Length_1 = 0xC8; // cycle of 200 period => cycle = 1ms TIM_Init (TIMx, &TIM_InitStructure);
And the statements inside timer's interrupt:
void TIM1_IRQHandler(void) { // port 3 pin 7 activated P37_1; // ACK interrupt TIM_ClearFlag(TIM1, TIM_FLAG_OC1); // clear Output Compare 1 flag TIM_CounterCmd(TIM1, TIM_CLEAR); // Reset TIM1 Counter VIC0->VAR = 0xFF; // write any value to VIC0 VAR }
BUT my oscilloscope measured a period of 1.03 ms instead of the 1ms expected. Normally to generate a pulse every 1.03 ms the TIM_Pulse_Length_1 should be set to 0xCE. As you can see, the difference between 0xCE and 0xC8 is big.
What can be the cause of this timer's inaccuracy ? > Problem in PLL configuration ? > Problem of crystal ? > Problem in timer configuration ?
Has someone the same problem ? In advance, thank you
We use: > STR912FAW44
for the PLL configuration : > In the main application loaded by the bootloader, the PLL is configured as followed inside main.c (there is no file with the extension .s):
// Initialisation SCU_MCLKSourceConfig(SCU_MCLK_OSC); /* Default configuration */ /*wait state insertion :This function should be executed from SRAM when*/ /*booting from bank1 to avoid Read-While-Write from the Same Bank.*/ FMI_Config(FMI_READ_WAIT_STATE_2, FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE,\ FMI_LVD_ENABLE, FMI_FREQ_HIGH);/*Insert 2 Wait States for read*/ SCU_PLLFactorsConfig(192, 25, 2); /* PLL factors Configuration based on*/ /* a OSC/Crystal value = 25Mhz*/ SCU_PLLCmd(ENABLE); /* PLL Enable and wait for Locking*/ SCU_RCLKDivisorConfig(SCU_RCLK_Div1); /* RCLK @96Mhz */ SCU_HCLKDivisorConfig(SCU_HCLK_Div1); /* AHB @96Mhz */ SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);/* FMI @96Mhz */ SCU_PCLKDivisorConfig(SCU_PCLK_Div2); /* APB @48Mhz */ SCU_MCLKSourceConfig(SCU_MCLK_PLL); /* MCLK @96Mhz */
I give you also how I calculated my counter and prescaler: > APB = 48Mhz > prescaler = 0xEF because we choosed to count 5us per 5us <= 1/(48/240) = 5 us > counter = 0xC8 because 0xC8 = 200 and 200 * 5us = 1 ms
Are you running an RC oscillator?
What can be the cause of this timer's inaccuracy ?
It would be helpful to know what chip you're using and how it is configured (PLL, etc).
View all questions in Keil forum