I am implementing a 32bit counter by software and would be grateful if I could have some guidance.
/*
* InputCapture
* uses timer hardware to measure pulses on pin 8 on Mega328
*/
const int inputCapturePin = 8; // input pin fixed to internal Timer
volatile unsigned int results;
volatile unsigned int previous = 0;
volatile int i=0; // Timer 1 overflow counter
volatile int a=0;
void setup()
{
Serial.begin(9600); // 9600bps
pinMode(inputCapturePin, INPUT); // ICP pin (digital pin 8 on Arduino) as input
TCCR1B = (1<<CS10); // Set timer 1 Clock source = FOsc
TCCR1A = 0 ; // Normal counting mode
TIMSK1 |= _BV(TOIE1); // enable timer 1 overflow flag
TIMSK1 |= _BV(ICIE1); // enable input capture interrupt for timer 1
}
//Print timer 1 total counts since last pulse
void loop()
{
float output = (((results-previous)+(65536*a))); //Calculate the total output value
//Debug only! Data to be transfered via SPI to the modulator. Add routine here.
Serial.println(output); // print the value to be sent to the modulator
}
//**********Interrupts************************************************************
//Overflow interrupt vector
ISR(TIMER1_OVF_vect)
{
cli();
i++; //Increment timer 1 overflow counter
}
//ICR interrupt vector
ISR(TIMER1_CAPT_vect)
{
cli(); //Disable interrupts
a=i; //Save the Value of i into a variable a, so that calculations can be made outside the ISR
i=0; //Clear i //Clear the overflow variable
previous = results; //Save the previous ICR1 Value so that no delay is added by reseting TCNT1
results = ICR1; //Assign the value of the ICR1 Register to the variable results
}
The problem is that often the overflow variable is incremented, during the ISR, resulting in 65536 being added to the correct result .
When an interrupt service routine (ISR) is called, interrupts are automatically disabled. Interrupts are automatically enabled when returning from an ISR. It is not necessary to explicitly enable nor disable interrupts inside of an ISR. The processor does these two things for you.
When an interrupt service routine (ISR) is called, interrupts are automatically disabled. Interrupts are automatically enabled when returning from an ISR. It is not necessary to explicitly enable nor disable interrupts inside of an ISR. The processor does these two things for you.
Mark
Right, i was clearly confusing with atomic variables!
So should I make it atomic or disable interrupts while performing this calculation?]
Something else I might need clarification on:
int for a variable that can overflow at 64 is an overkill. I have used char, but I don't believe that the most correct term.