This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer accuracy

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

Parents
  • 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

Reply
  • 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

Children