我正在尝试处理两个AVR中断向量ISR(PCINT1_vect)和ISR(PCINT0_vect)。然而, 只有其中之一被处决。
执行哪个 ISR 取决于代码中是否首先调用函数“SonarSensor_init0(void)”或“SonarSensor_init1(void)”。
我是否以错误的方式处理多个 ISR?
顺便说一句,我正在使用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();
}
}
这可能是由于您的函数中有这两行相互冲突的行造成的:
PCICR = (1<<PCIE1);
PCICR = (1<<PCIE0);
当第一行运行时,它将 PCICR 中的所有位设置为特定值。当第二行运行时,它将所有这些设置为不同的值,从而禁用第一行启用的中断。也许您应该使用
|=
而不是 =
,这样它只会修改它关心的一位。