/var/www/restricted/ssh/stm32/www/stm32circle/ STM CircleOS forum / Timer accuracy or interrupt priority problem

Username:     
Password:     
             

Forum
  • Index
  •  » circleOS
  •  » Timer accuracy or interrupt priority problem

# 1   2010-04-23 06:31:39 Timer accuracy or interrupt priority problem

commlinx
New member
Registered: 2010-02-08
Posts: 3

Timer accuracy or interrupt priority problem

I've been working on an application and I'm having problems getting an accurate timing result from a timer interrupt. I've set the priority to zero and because I noticed the audio and sd drivers use this level tried compiling a version of Circle OS 3.8 with those set to 1 just in case, although I wouldn't have been expecting any interrupt activity from those sources.

I cut out the relevant parts of the code into a small sample application to demonstrate. When the application displays 5:00 minutes have elapsed a stopwatch shows 5:18, so it's running about 6% slow. Does anyone have ideas on what I'm doing wrong?

#include <stdio.h>
#include "stm32f10x_tim.h"
#include "stm32f10x_nvic.h"
#include "stm32f10x_rcc.h"
#define __STM32F10x_H
#include "circle_api.h"

const char Application_Name[8+1] = {"Timer"};      // Max 8 characters
#define ACC_SAMPLE_RATE 160

int StopwatchTimer = 0;
void TIM3_IRQHandler( void ) __attribute__ ((interrupt ("IRQ")));
void TIM3_IRQHandler( void )
{
    StopwatchTimer++;
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}

enum MENU_code Application_Ini(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef       TIM_OCInitStructure;

    UTIL_SetPll(SPEED_VERY_HIGH); 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    TIM_TimeBaseStructure.TIM_Period = 72000000 / 0x10 / ACC_SAMPLE_RATE;
    TIM_TimeBaseStructure.TIM_Prescaler       = 0x1;
    TIM_TimeBaseStructure.TIM_ClockDivision   = 0x0;
    TIM_TimeBaseStructure.TIM_CounterMode     = TIM_CounterMode_Up;

    TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure );

    TIM_OCInitStructure.TIM_OCMode   = TIM_OCMode_Timing;
    /* in FWLib v1.0 : TIM_OCInitStructure.TIM_Channel  = TIM_Channel_1; */
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; /* now in FWLib v2.0 */
    TIM_OCInitStructure.TIM_Pulse    = 0x0;
    TIM_OC2Init( TIM3, &TIM_OCInitStructure ); /* changed against FWLib v2.0 */

    /* TIM3 enable counter */
    TIM_Cmd( TIM3, ENABLE );

    /* Immediate load of TIM3 Precaler value */
    TIM_PrescalerConfig( TIM3, 0x10, TIM_PSCReloadMode_Immediate );

    /* Clear TIM3 update pending flag */
    TIM_ClearFlag( TIM3, TIM_FLAG_Update );

    /* Enable TIM3 Update interrupt */
    TIM_ITConfig( TIM3, TIM_IT_Update, ENABLE );

    #define  TIM3_IRQ_ID 0x00B4
    UTIL_SetIrqHandler(TIM3_IRQ_ID, TIM3_IRQHandler);

    /* Enable the TIM3 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                    = TIM3_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority  = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority         = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd                 = ENABLE;
    NVIC_Init( &NVIC_InitStructure );

    return MENU_CONTINUE_COMMAND;
}

void __io_putchar(char c) {}

void ShowStopwatch()
{
    u32 mins, tenths;
    char s[64];
    mins = StopwatchTimer / ACC_SAMPLE_RATE / 60;
    tenths = (StopwatchTimer / (ACC_SAMPLE_RATE / 10)) % 600;

    DRAW_SetCursorPos(15, 60);
    DRAW_SetCharMagniCoeff(2);
    sprintf(s, "%02d:%02d.%01d", mins, tenths / 10, tenths % 10);
    DRAW_Puts(s);
    DRAW_SetCharMagniCoeff(1);
}

enum MENU_code Application_Handler(void)
{
    if(BUTTON_GetState() == BUTTON_PUSHED)
        {
        BUTTON_WaitForRelease();
        return MENU_Quit();
        }
   
    ShowStopwatch();
   
    return MENU_CONTINUE;   // Returning MENU_LEAVE will quit to CircleOS
}

Offline

 

# 2   2010-04-27 02:33:38 Timer accuracy or interrupt priority problem

commlinx
New member
Registered: 2010-02-08
Posts: 3

Re: Timer accuracy or interrupt priority problem

I ended up sorting this out myself, I hadn't taken into account that for the prescaler the setting of 16 divides by 17, so had to subtract one from the prescaler value.

Offline

 

  • Index
  •  » circleOS
  •  » Timer accuracy or interrupt priority problem

Board footer