I am trying to handle two AVR interrupt vectors ISR(PCINT1_vect) and ISR(PCINT0_vect). However, only one of them are executed.
Which ISR is executed is dependent upon if function "SonarSensor_init0(void)" or "SonarSensor_init1(void)" is called upon first in the code.
Am I handling multiple ISRs in the wrong way?
I am by the way using Atmega328PB.
#define F_CPU 16000000UL
#define USART_BAUDRATE 9600
#define UBRR_value (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
uint16_t distance1;
uint16_t distance2;
void SonarSensor_init0(void);
void SonarSensor_init1(void);
int main(void)
{
SonarSensor_init0();
SonarSensor_init1();
while(1)
{
sei();
PORTC |= (1 << PINC4);
_delay_us(10); // 10 us trigger. Echo pin is pulled high by control circuit of sonar sensor.
PORTC &= ~(1<<PINC4);
sei();
PORTB |= (1 << PINB0);
_delay_us(10); // 10 us trigger. Echo pin is pulled high by control circuit of sonar sensor.
PORTB &= ~(1<<PINB0);
}
}
void SonarSensor_init1(void)
{
DDRC = 0xFF; // Port C all output.
DDRC &= ~(1<<DDC5);
PORTC |= (1<<PORTC5); // Enable pull up on C5 (echo)
PORTC &= ~(1<<PINC4); // Init C4 as low (trigger)
PRR &= ~(1<<PRTIM1); // To activate timer1 module
TCNT1 = 0; // Initial timer value
TCCR1B |= (1<<CS12); // Timer without prescaler. Since default clock for atmega328p is 1Mhz period is 1uS
TCCR1B |= (1<<ICES1); // First capture on rising edge
PCICR = (1<<PCIE1); // Enable PCINT[14:8] we use pin C5 which is PCINT13
PCMSK1 = (1<<PCINT13); // Enable C5 interrupt
//sei(); // Enable global interrrupt
}
void SonarSensor_init0(void)
{
DDRB = 0xFF; // Port B all output.
DDRB &= ~(1<<DDB1);
PORTB |= (1<<PORTB1); // Enable pull up on B1 (echo)
PORTB &= ~(1<<PINB0); // Init B0 as low (trigger)
PRR &= ~(1<<PRTIM0); // To activate timer0 module
TCNT0 = 0; // Initial timer value
TCCR0B |= (1<<CS00); // Timer without prescaler. Since default clock for atmega328p is 1Mhz period is 1uS
PCICR = (1<<PCIE0); // Enable PCINT[0:7] we use pin B1 which is PCINT1
PCMSK0 = (1<<PCINT1); // Enable B1 interrupt
//sei(); // Enable global interrrupt
}
ISR(PCINT1_vect) {
if ( (PINC & (1 << PINC5)) == (1 << PINC5)) // Checks if echo is high
{
TCNT1 = 0;
PORTB |= (1 << PINB5); // Toggles Debug Led
}
else
{
distance2 = TCNT1/3; // Save Timer value
PORTB &= ~(1 << PINB5); // Toggles Debug led
cli(); // Disable global interrupt;
}
}
ISR(PCINT0_vect) {
if ( (PINB & (1 << PINB1)) == (1 << PINB1)) // Checks if echo is high
{
TCNT0 = 0;
PORTB |= (1 << PINB5); // Toggles debug led
}
else
{
distance1 = TCNT0; // Save Timer value
PORTB &= ~(1 << PINB5); // Toggles debug led
cli();
}
}
It's probably caused by the fact that you have these two conflicting lines in your functions:
PCICR = (1<<PCIE1);
PCICR = (1<<PCIE0);
When the first line runs, it sets all the bits in PCICR to a particular value. When the second line runs, it sets all of them to a different value, disabling the interrupt that was enabled by the first one. Maybe you should be using |=
instead of =
so it only modifies the one bit it cares about.