cembeddedarduino-unoatmegabare-metal

Defining ISR crashes ATmega328p


I am doing bare metal programming for an ATmega328p on an Arduino UNO R3. I am trying to blink an LED that I connected to the board by using interrupts with output compare through Timer/Counter 1. I wrote the following program.

#include <avr/io.h>
#include <avr/interrupt.h>

ISR (TIMER1_COMPA_vect)
{
    // toggle Port D, Pin 5
    PORTD ^= (1 << PORTD5);

}

int main(void) {

    // write 0 to PRTIM1 bit to enable Timer/Counter 1
    PRR &= ~(1 << PRTIM1);

    // output compare value
    OCR1A = 15625 - 1;

    // disconnect OC1A/OC1B pins by writing 0 to all these pins
    TCCR1A = 0;

    // operate in clear timer on compare (CTC) mode
    // WGM10 & WGM11 are 0 by default
    // select clock source using CS12, CS11, CS10 bits of TCCR1B
    // sets clock to clk_I/O / 1024 preclaser
    // 15625 Hz, so need that many ticks - 1 for 1s
    TCCR1B |= (1 << WGM12);
    TCCR1B |= (1 << CS12);
    TCCR1B &= ~(1 << CS11);
    TCCR1B |= (1 << CS10);

    // enable output compare interrupts for output compare unit A
    TIMSK1 |= (1 << OCIE1A);

    // global interrupt enable
    sei();

    // enable PORTD5 as output and write logic low to start
    DDRD |= (1 << DDD5);
    PORTD &= ~(1 << PORTD5);


    // for debugging purposes; enable onboard LED (pin 13 AKA Port B, Pin 5)
    DDRB |= (1 << DDB5);
    PORTB |= (1 << PORTB5);



    // run
    while (1) {

        // NOP
        ;;
    }

    // keeps compiler happy
    return 0;
}

I enable the onboard LED on the Uno R3 to ensure my program is properly flashed, and that's where things get weird. If I don't have the ISR at the top (either I delete it or comment it out) and flash my code, it works fine; the onboard LED (not the one I connected via Port D, Pin 5) turns on and stays on. Obviously, the interrupt portion of the code doesn't work (i.e. my connected LED won't flash). If I uncomment the ISR to flash the pin when Timer/Counter 1 interrupts the CPU and flash the program, the onboard LED -- which should just stay on -- starts flashing rapidly. The last time the onboard LED flashed like this (on a different project), my program was broken and hadn't flashed properly. I'm assuming it's the same issue now; something in the code is not working right and won't flash. The LED I connected never blinks. I've done some surfing but haven't seen people with this problem yet. Anyone know why my ISR is breaking the program?


Solution

  • It appears to have been my Makefile. I was compiling & flashing with avr-gcc and avrdude. I opened the file in Arduino IDE and wrote the raw C code and flashed via the IDE's built-in upload feature. Everything began to work as expected after that.