Hello,
I am not sure if I am approaching this correctly. Basically I have a buffer array that I want populated by an interrupt. I made the buffer a global pointer and thus do not pass it to the interrupt. Is this the preferred method? I've read that variables changed by interrupts should be made volatile, but I can't seem to get it to work ("volatile float* buff;" is not accepted).
Please see the function "ITR1" in the code below. Thanks!
// sbi is to set a bit
// cbi is to clear a bit
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
int buffSize=60;
int TOP=50; // this sets OCR1A for the CTC counter
float* buff;
volatile uint8_t low, high;
// Read a Samp and store it in the buff
// This is called at a fixed Samprate via the Interrupt
// Each time a Samp is made, this routine is called
void ITR1() {
while (bit_is_set(ADCSRA, ADSC));
low = ADCL;
high = ADCH;
// I know this is wasteful, I'm converting it to a
// circular buffer soon
for (int i= 0 ; i < buffSize - 1 ; i++){
buff[i] = buff[i+1];
}
buff[buffSize - 1] = (high<<8) | low;
}
//Interrupt Service Routine (ISR)
ISR(TIMER1_COMPA_vect) {
sbi(ADCSRA, ADSC);
ITR1();
}
// This gets called at startup
void setupIntr(){
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
// also known as the TOP
OCR1A = TOP;
TCCR1B |= (1 << CS12);
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
// page 264
ADMUX |= (1 << REFS0); //set reference voltage
// ADCSRA: page 265
// ADEN: Enable ADC
sbi(ADCSRA, ADEN);
// ADATE: ADC auto trigger enable
cbi(ADCSRA, ADATE);
// ADMUX page 264
// select ADC1 channel
cbi(ADMUX, MUX3);
cbi(ADMUX, MUX2);
cbi(ADMUX, MUX1);
cbi(ADMUX, MUX0);
// Quiet ADC inputs
// Check page 266 of the ATmega328p datasheet
// for more information.
sbi(DIDR0,ADC5D);
sbi(DIDR0,ADC4D);
sbi(DIDR0,ADC3D);
sbi(DIDR0,ADC2D);
sbi(DIDR0,ADC1D);
sbi(DIDR0,ADC0D);
// start the conversion
sbi(ADCSRA, ADSC);
}
void loop() {
}
void setup() {
//setup Interrupt routine
setupIntr();
Serial.begin(57600);
buff = (float *) malloc(sizeof(float)* buffSize);
sei();//enable interrupts
delay(1000);
TIMSK1=0;
for(int index=0; index < buffSize; index++) {
Serial.write("buff[");
Serial.print(index);
Serial.write("]=");
Serial.println(buff[index]);
}
}