Hi all!
I've been digging deeper into the Atmega registers lately and I'm having a problem setting up my interrupts.
I'm building a frequency detector (guitar in => volt/octave out via R-2R 10bit DAC on 10 pins, 6 from PORTC and 4 from PORTB, with some other cool features). Using Arduino UNO for now but will migrate to the standalone MCU chip.
To measure the period of my signal (frequency between 40Hz and 1400Hz), I want to use pin D8 (also called PB0 or ICP1) to detect a rising edge (from an external analog comparator) and launch an interrupt (reading the buffered Timer1 and reseting it). Also I want to use D2 and D3 (also called PD2 and PD3 or INT0 and INT1) to do other stuff. INT0 would detect a falling edge on the comparator and INT1 would detect a rising edge from another part of the circuit in order to run some computation and track the pitch of the guitar, in an optimized way.
If I strip all my program from it's actual content and just keep the bare minimum to set up the IN/OUTs, the timers and the interrupts, while monitoring an LED on pin D1 (also called PD1 or TX) to check if everything is OK, I can clearly see it isn't.
What I figured is basically two things:
1°) When I enable INT0 and INT1 via the EIMSK register, my Timer1 Compare A interrupt doesn't trigger. My Timer1 Input Capture Interrupt doesn't either.
2°) When I disable Timer Output Compare B Interrupt or Timer 1 Overflow Interrupt via the TIMSK1 register, my Timer1 Compare A interrupt doesn't trigger. My Timer1 Input Capture Interrupt doesn't either. This is less of a problem but I wonder why.
It is to be noted that I know there would be an easier way to code this by poling the inputs and using micros() rather than using interrupts. First of all I'm going to do some "heavy" computing in parallel and second of all I want to learn!
Is this behavior normal?
Thanks for reading here is my code.
void setup() {
pinMode(1,OUTPUT);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(8,INPUT_PULLUP);
//EIMSK |= (1 << INT0);//these two bits enable external interrupts and are causing my first problem
//EIMSK |= (1 << INT1);
TCCR1A &= (0 << COM1A1); //these 2 bits disable OC1A when not in PWM mode
TCCR1A &= (0 << COM1A0); //
TCCR1A &= (0 << COM1B1); //these 2 bits disable OC1B when not in PWM mode
TCCR1A &= (0 << COM1B0); //
TCCR1A |= (1 << WGM11); // these 4 bits set the Timer1 to FAST PWM mode with OCR1A as TOP value. For some reason right now this is the only mode I could use Compare Out A interrupt in.
TCCR1A |= (1 << WGM10); //
TCCR1B |= (1 << WGM13); //
TCCR1B |= (1 << WGM12); //
TIMSK1 |= (1 << OCIE1A); ////enable output compare A Interrupt
//TIMSK1 &= (0 << OCIE1B); //disable output compare B Interrupt. Cause of my 2nd problem
TIMSK1 |= (1 << ICIE1); //enable input capture interrupt
//TIMSK1 &= (0 << TOIE1); //disable overflow interrupt. Cause of my 2nd problem
TCCR1B |= (1 << ICES1); //input capture on rising edge (or comparator out i guess)
OCR1A = 65000;
}
//HERE ARE MY ISRs, THIS IS WHERE I USE THE LED TO CHECK IF IT WORKS.
ISR (TIMER1_CAPT_vect) {
digitalWrite(1,1);
}
ISR (TIMER1_COMPA_vect) {
//digitalWrite(1,1);
}
ISR (TIMER1_OVF_vect) {
//digitalWrite(1,1);
}
ISR (INT0_vect) {
//digitalWrite(1,1);
}
ISR (INT1_vect) {
//digitalWrite(1,1);
}
void loop() {
}