lpcware

Inaccurate timing with 16 bit timer

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by nelmak on Thu Apr 19 11:28:33 MST 2012
Hey guys,

I am trying to time intervals between the peaks of pulses using the LPC 1227. I input a 1Hz pulse train into the LPC1227 GPIO and make it count the interval in between the peaks in milliseconds. However, I consistently get a reading of ~900 ms which is actually 1.11Hz. When I increase the frequency, the error actually becomes really large. I am using the 16 bit timer. Below is my code

    init_timer16(1);
    enable_timer16();
    LPC_SYSCON->SYSAHBCLKCTRL |= 0x8001001FUL;

    ADCInit(8000000);
    while(1) {
        adcval = ADCRead(0);
        if ((oldadcval > 800) && (adcval < 800))
        {
            disable_timer16();
            printf("New = %d, Old = %d, %d ms\n", adcval, oldadcval, counter);
            counter = 0;
            enable_timer16();
        }

        oldadcval = adcval;
    }
    return 0 ;
}

//Enable Timer
void enable_timer16(void)
{
      LPC_CT16B0->TCR = 1;
//      printf("Timer enabled\n");
      return;
}

void init_timer16(uint32_t delay)
{
    LPC_SYSCON->PRESETCTRL |= (0x1<<4);     //De-assert Reset
    LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<7);    //Enable clock for CT16B0
    LPC_CT16B0->PR  = 0x00;        /* set prescaler to zero */
    LPC_CT16B0->MR[0] = delay * (SystemCoreClock / 1000 - 1);
    LPC_CT16B0->IR  = 0xff;        /* reset all interrrupts */
    LPC_CT16B0->MCR = (0x3<<0);                //Interrupt and reset on MR0
    NVIC_EnableIRQ(13);                        //Enable timer0_16 interrupt
    counter = 0;
    printf("Timer initialized\n");

}

//Disable timer
void disable_timer16(void)
{
//      printf("Timer Disabled");
      LPC_CT16B0->TCR = 0;
      return;
}

void reset_timer16()
{
    LPC_CT16B0->TC = 0;
    counter = 0;
}

void TIMER16_0_IRQHandler()
{
      if ( LPC_CT16B0->IR & (0x1<<0) )
      {
        LPC_CT16B0->IR = 0x1<<0;            /* clear interrupt flag */
        counter++;                    //increment counter
      }
}

Can I get some feedback on my code and if I am making any mistakes to cause this error? Or would I need a faster processor to get more accurate timing?

Thanks in advance

Outcomes