From aff30bc89ef1945f7fdf81660e36942f8e07058e Mon Sep 17 00:00:00 2001 From: Daedalusz Date: Fri, 31 Jan 2014 15:02:32 +1100 Subject: [PATCH] Added Low Resolution Timers kartTimers (terrible name) provides lower frequency timers and interrupts. --- kartTimers.h | 26 ++++++++++++++++++++++ kartTimers.ino | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ kartduino.ino | 17 ++++----------- scheduler.ino | 3 +-- 4 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 kartTimers.h create mode 100644 kartTimers.ino diff --git a/kartTimers.h b/kartTimers.h new file mode 100644 index 0000000..b935add --- /dev/null +++ b/kartTimers.h @@ -0,0 +1,26 @@ + + +/* +NOTE - This file and it's associated functions need a CLEARER NAME + +//Purpose +We're implementing a lower frequency interrupt loop to perform calculations that are needed less often, some of which depend on time having passed (delta/time) to be meaningful. + + +//Technical +Timer2 is only 8bit so we are setting the prescaler to 1024 to get the most out of it. This means that the counter increments every 0.064ms and the overflow at 256 will be after ~16ms +Max Period = (Prescale)*(1/Frequency)*(2^8) +(See http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html) + +We're looking for a 10ms interval so we'll need 156.25 intervals to reach this ( 10ms / 0.064ms per tick = 156.25). +Hence we will preload the timer with 99 cycles to leave 156 until overflow (~10ms). + +*/ + +volatile int loopGen; +volatile int loopSec; + + +void initialiseTimers(); + + diff --git a/kartTimers.ino b/kartTimers.ino new file mode 100644 index 0000000..2111e0b --- /dev/null +++ b/kartTimers.ino @@ -0,0 +1,58 @@ + + + +void initialiseTimers() { + + //Configure Timer2 for our low-freq interrupt code. + TCCR2B = 0x00; //Disbale Timer2 while we set it up + TCNT2 = 99; //Preload timer2 with 100 cycles, leaving 156 till overflow. + TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag + TIMSK2 = 0x01; //Timer2 Set Overflow Interrupt enabled. + TCCR2A = 0x00; //Timer2 Control Reg A: Wave Gen Mode normal + TCCR2B = ((1 << CS10) | (1 << CS11) | (1 << CS12)); //Timer2 Set Prescaler to 5 (101), 1024 mode. + +} + + +//Timer2 Overflow Interrupt Vector, called when the timer overflows. +//SHOULD execute every ~10ms. +ISR(TIMER2_OVF_vect) +{ + + //Increment Loop Counters + loopGen++; + loopSec++; + + + //Loop executed every 250ms loop (10ms x 25 = 250ms) + if (loopGen == 25) + { + loopGen = 0; //Reset Counter. + //250ms Code here. + } + + + + //Loop executed every 1 second (10ms x 100 = 1000ms) + if (loopSec == 100) + { + loopSec = 0; //Reset counter. + + + //If the engine is running or cranking, we need ot update the run time counter. + if (((currentStatus.engine & ENGINE_RUN) || (currentStatus.engine & ENGINE_CRANK))) + { //NOTE - There is a potential for a ~1sec gap between engine crank starting and ths runSec number being incremented. This may delay ASE! + if (currentStatus.runSecs <= 254) //Ensure we cap out at 255 and don't overflow. (which would reset ASE) + currentStatus.runSecs ++; //Increment our run counter by 1 second. + + } + + + //Reset Timer2 to trigger in another ~10ms + TCNT2 = 99; //Preload timer2 with 100 cycles, leaving 156 till overflow. + TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag + + + } + +} diff --git a/kartduino.ino b/kartduino.ino index 4eeb3dc..714490d 100644 --- a/kartduino.ino +++ b/kartduino.ino @@ -33,6 +33,7 @@ #include "comms.h" #include "math.h" #include "corrections.h" +#include "kartTimers.h" #include "fastAnalog.h" #define DIGITALIO_NO_MIX_ANALOGWRITE @@ -93,6 +94,7 @@ void setup() digitalWrite(pinCoil4, coilLOW); initialiseSchedulers(); + initialiseTimers(); //Once the configs have been loaded, a number of one time calculations can be completed req_fuel_uS = configPage1.reqFuel * 1000; //Convert to uS and an int. This is the only variable to be used in calculations @@ -236,22 +238,11 @@ void loop() { //Sets the engine cranking bit, clears the engine running bit BIT_SET(currentStatus.engine, 1); BIT_CLEAR(currentStatus.engine, 0); - - if (secCounter == 0) //Check to see if we already have a counter update queued. - { - secCounter = micros() + 100000; //Kick off the runtime counter if it isn't already going. - } - + currentStatus.runSecs = 0; //We're cranking (hopefully), so reset the engine run time to prompt ASE. } - //If the engine is running or cranking, Update Engine Running seconds. - if (((currentStatus.engine & ENGINE_RUN) || (currentStatus.engine & ENGINE_CRANK)) && micros() > secCounter) - { - currentStatus.runSecs ++; //Increment our run counter by 1 second. - secCounter = micros() + 100000; //Reset the next increment for 1 second from now. - - } + } diff --git a/scheduler.ino b/scheduler.ino index ee86893..025f3de 100644 --- a/scheduler.ino +++ b/scheduler.ino @@ -3,8 +3,7 @@ void initialiseSchedulers() { - - // Much help in this from http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html + // Much help in this from http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html //Fuel Schedules, which uses timer 3 TCCR3B = 0x00; //Disbale Timer3 while we set it up TCNT3 = 0; //Reset Timer Count