Timer Issue

06 Jul 2014

Hello,

I have written a program to measure time for a time of flight experiment using an mBed LPC1768. To achieve the required precision I need timer0 to run at full clock speed (96 MHz) and the max speed I am getting is 12 MHz. I wrote a short routine on an 8-bit processor running at 16 MHz to trip the gates as a means of debugging without running the whole system. The clock speed of the 8-bit processor was verified using an oscilloscope. Using TIMER0_SETPRESCALE(1); to set the prescaler I thought would have timer0 running at full speed, I commented it out thinking that if I did set the prescaler it would default to max speed, both of these gave me a clock speed of 12 MHz. I used a variety of prescaler values and did not get the expected results.

The size of the source code is too large to include so I only included the pertinent routines and definitions below. The value of variable elapsedTicks assigned in gateOneTicks() is 1/8 of what it should be that is why I am saying the max speed is 12 MHz.

Does anyone see a reason why timer0 is giving such slow speed results, hopefully I have done something stupid and simple to fix, trust me it would not be the first time.

Thanks for looking at this post,

wade

Timer setup and interrupts

#include <mbed.h>
#include <time.h>
#include <timers.h>

volatile unsigned long elapsedTicks;
InterruptIn  gateOne(GATEONEPIN);
InterruptIn  gateTwo(GATETWOPIN);

//Function Prototypes
void gateOneTime(void);
void gateTwoTime(void);
void systemSetup(void);
void clockSetup(void);

void systemSetup(void){
// Set up interrupts
    gateOne.rise(&gateOneTime);
    gateTwo.rise(&gateTwoTime);
}

void clockSetup(void){
//  Set up clock to run at full speed (96 Mhz) so the timing resolution is at a max

    TIMER0_INIT();
    TIMER0_START();
    // TIMER0_SETPRESCALE(1);  // Here the clock prescale is being set
}

//  There are different interrupt routines for gate one and two they could be combined
//  as long as the state variable is managed properly.  Combining them would be a little
//  elegant but using one for each gate does not cost much space.

void gateOneTime(void){
    __disable_irq();//   Turn off Interrupts
  //  timer.reset();
  TIMER0_INIT();
  TIMER0_START(); 
    state = 2;
    __enable_irq();//    Turn on Interrupts
}

void gateTwoTime(void){
    __disable_irq();//   Turn off Interrupts
   elapsedTicks = TIMER0_VALUE();
    if(state != 2){
        state = 5; // second gate was triggered before first gate
    }
       
    state = 3;
    __enable_irq();//    Turn on Interrupts
}


06 Jul 2014

First of all, those commands aren't in the default mbed lib, so you are using a custom one, am I correct you are using this one: http://mbed.org/users/Alkorin/code/SimpleLib/file/ce11d7ff88af/timers.h?

You probably are going to have to grab the LPC1768's user manual and figure out what some registers should be set as. But generally writing a '1' to a prescaler register divides it by 2, and a 0 by 1. After commenting it, did you reset it, or power cycle it? If you don't power cycle it could very well keep its last value. Then by default most peripherals run at a quarter of the clock frequency. You can change this using the PCLKSEL regs, For example the PWM timer uses:

LPC_SC->PCLKSEL0|=1<<12;
06 Jul 2014

Eric, LPC_SC->PCLKSEL0 |= 1 << 4; did the trick, thanks for giving me the kick to look at the manual a few minutes there and I was golden.