Atmega328p 仅处理一个 ISR

Atmega328p only one ISR handled

我正在尝试 运行 两个函数 'similtaniously' 通过中断:
1) 通过定时器 0 (100Hz) 的计时测量 ADC,并在引脚 0-5 上显示结果
2) 通过引脚 6 上的计时器 1 (10Hz) 使 LED 闪烁。

问题似乎是定时器 1 的 ISR 阻塞了该函数,因此没有执行任何其他操作。这是代码:
(请不要被任何样式错误冒犯,代码正在开发中)

#define F_CPU 16000000UL // 16MHz Clock speed 
#include <avr/io.h>
#include <avr/interrupt.h>

void ADC_init(void);
void SetTimer0(void);
void SetTimer1(void);

int main(void)
{
    DDRB |= (1<<DDB0) + (1<<DDB1) + (1<<DDB2) + (1<<DDB3) + (1<<DDB4) + (1<<DDB5) + (1<<DDB6);
    PORTB = 0b00000000;
    DDRB &= ~(1<<DDB7);

    ADC_init();
    SetTimer0();
    SetTimer1();

    while(1){
    }
}

void ADC_init(void)
{
    cli();
    // Select Vref=AVcc
    // and set left adjust result
    // select pin ADC0 (PC0)
    ADMUX |= (1<<REFS0)|(1<<ADLAR);

    //and enable ADC
    //enable ADC interupt   
    //enable autotriggering 
    //set prescaller to 128
    ADCSRA |= (1<<ADEN) | (1<<ADATE) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

    //set ADC trigger source - Timer0 compare match A
    ADCSRB |= (1<<ADTS1)|(1<<ADTS0);

    // StartADC
    ADCSRA |= (1<<ADSC); 

    sei();
}

//initialize timer0 match A on 100hz
void SetTimer0(void)
{   
    cli();
    TCCR0A = 0; // set entire TCCR0A register to 0
    TCCR0B = 0; // same for TCCR0B
    TCNT0  = 0; // initialize counter value to 0
    // set compare match register for 100Hz increments
    OCR0A = 155; // = 16000000 / (1024 * 100.16025641025641)-1
    // toggle PD6/OC0A pin on compare match
    TCCR0A |=(1<<COM0A0)|(1<<WGM01);    
    //Set CTC mode
    TCCR0B |= (1 << WGM01);
    // Set CS02, CS01 and CS00 bits for 1024 prescaler
    TCCR0B |= (1 << CS02) | (0 << CS01) | (1 << CS00);
    // enable timer compare interrupt
    TIMSK0 |= (1 << OCIE0A);
    sei();
}

//initialize timer1 10hz
void SetTimer1(void){
    cli();
    TCCR1A = 0; // set entire TCCR1A register to 0
    TCCR1B = 0; // same for TCCR1B
    TCNT1  = 0; // initialize counter value to 0
    // set compare match register for 10 Hz increments
    OCR1A = 24999; // = 16000000 / (64 * 10) - 1 (must be <65536)
    // turn on CTC mode
    TCCR1B |= (1 << WGM12);
    // Set CS12, CS11 and CS10 bits for 64 prescaler
    TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
    // enable timer compare interrupt
    TIMSK1 |= (1 << OCIE1A);
    sei();
}

// ADC done interrupt
ISR(ADC_vect)
{
    // Clear timer compare match flag
    TIFR0=(1<<OCF0A);

    // save ADC measurement
    uint16_t val = ADC;

    // show ADC results
    if (val < 100)
    { PORTB = 0b00000000; }
    else if (val < 300)
    { PORTB = 0b00000001; }
    else if (val < 550)
    { PORTB = 0b00000011; }
    else if (val < 850)
    { PORTB = 0b00000111; }
    else if (val < 1020)
    { PORTB = 0b00001111; }
    else 
    { PORTB = 0b00011111; }

}


ISR(TIMER1_COMPA_vect)
{
    //PORTB ^= PINB5;
    static uint16_t on = 0;
    if (on == 1){
        PORTB = 0b00100000;
        on = 0;
    }
    else {
        PORTB = 0b00000000;
        on = 1;
    }
}

SetTimer1() 功能被禁用时,DCA 运行 将按预期运行。因此,单独来看,两个 ISR 都可以正常工作,但在一起时却不行。有人可以帮我解决这个问题吗?

您为 Timer0 启用了输出比较中断:

// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);

但没有用于该中断的 ISR 处理程序。

默认的__bad_interrupt处理程序只执行跳转到零中断向量,即重新启动程序。

这意味着如果您启用了中断,则应该有一个针对该中断的 ISR。