atmega 328p中断和定时器设置[C / C ++]

时间:2017-09-03 10:08:02

标签: embedded avr atmega

我正在尝试设置一个中断和一个计数器/计时器。中断是外部的,从引脚读取低逻辑。定时器应每100 us递增一次,并加起来为count变量。 我设置了中断,但是在设置定时器后工作正常,中断和定时器都不起作用。代码是这样的:

volatile boolean allowCount = false, timerFlag = false;
volatile unsigned int counter;
boolean pulseLow = false;


void setup(){

Serial.begin(9600);

// initialize external pin interrupt.
PCICR =  0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10);    // set wanted flags (low logic level causes interrupt)
PCMSK1 = 0b00010000; // Enable Pin Change Interrupt for  A4


// TODO Interrupt settings not working together


// initialize Timer1
cli();          // disable global interrupts
TCCR1A = 0;     // set entire TCCR1A register to 0
TCCR1B = 0;     // same for TCCR1B

// set compare match register to desired timer count:
OCR1A = 0x18;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 64 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);


}

void loop(){
    if (allowCount == true)
    {   timer100_uS();

        if (counter > 50 && pulseLow == false){
            DDRC |= (1 << DDC3 ); // sets bit DDC3 to 1 within register DDRC        
            //set pin 3(A3) ouput as sourcing Vcc(HIGH)
            PORTC |= (1 << PORTC3);
            timerReset();
            pulseLow = true;
        }
        if (pulseLow == true){
            timer100_uS();
            if (counter >= 500){
                //set pin3 of port C to LOW (A3);
                PORTC &= ~(1 << PORTC3); 
                pulseLow = false
                timerReset();
        }

    }
// external pin interrupt
ISR(PCINT1_vect){
    if (allowCount == false)
    allowCount = true;
}
// timer/counter interrupt
ISR (TIMER1_COMPA_vect)
{
    if (timerFlag == true){
        counter++;
    }
}

void timer_100uS(void){
    timerFlag = true;
    cli();
}

void timerReset(void){
    sei();
    timerFlag = false;
    counter = 0;
}

根据以下公式,预分频器64和16 MHz处理器计算OCR0A的值为24(0x18):

OCRn =  [ (clock_speed / Prescaler_value) * Desired_time_in_Seconds ] - 1

如何设置不同的中断以使它们不会相互重叠? 或者更好的是,是否可以设置计时器以使其不使用中断? 谢谢你的阅读!

2 个答案:

答案 0 :(得分:0)

正如我所看到的,您正在使用带有Arduino库的ATMega328。您的问题是Arduino库内部使用Timer 1作为其内部用途。因此,如果为定时器1添加自己的中断处理程序,则会覆盖Arduino的中断处理程序,该中断处理程序用于中断库。

如果您想继续使用Arduino库,请使用该库来控制计时器:Arduino Timer1

答案 1 :(得分:0)

感谢@old_timer,@ klasyc的答案。 很晚,但我通过使用timer0而不是timer1解决了这个问题,并在设置中进行了以下设置:

// initialize external pin interrupt.
PCICR =  0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10);    // set wanted flags (falling edge causes interrupt)
PCMSK1 = 0b00001000; // Enable Pin Change Interrupt for A3

TCCR0B = 0;
TCCR0A = 0;
//set CTC mode
TCCR0A = ( 1 << WGM01 );

// set OCR0A value for 1 us counter (OCRxn = (freq/prescaler)*desired_value)-1
OCR0A = 15;

// set compare match counter
TIMSK0 |= (1 << OCIE0A);


//set prescaler
TCCR0B |= ( 1 << CS00);

并在循环之外:

ISR(TIMER0_COMPA_vect){
  counter++;
}