处理多个 AVR 中断向量

问题描述 投票:0回答:1

我正在尝试处理两个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();

    }
}
vector interrupt avr atmega
1个回答
0
投票

这可能是由于您的函数中有这两行相互冲突的行造成的:

PCICR = (1<<PCIE1);

PCICR = (1<<PCIE0);

当第一行运行时,它将 PCICR 中的所有位设置为特定值。当第二行运行时,它将所有这些设置为不同的值,从而禁用第一行启用的中断。也许您应该使用

|=
而不是
=
,这样它只会修改它关心的一位。

© www.soinside.com 2019 - 2024. All rights reserved.