AVR ISR causa un comportamiento inesperado

2

Usando avr-gcc 4.8.0 y avr-libc 1.8.0 en Arch Linux. Intentar obtener interrupciones de UART RX trabajando en un ATtiny2313 con este simple código que debe repetir el byte recibido:

#define F_CPU 14745600

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

#define USART_BAUDRATE 9600 
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

int main(){
  DDRD |= _BV(PD6);

  UCSRB = (1 << RXEN) | (1 << TXEN);
  UCSRC = (1 << UCSZ0) | (1 << UCSZ1);

  UBRRH = (BAUD_PRESCALE >> 8);
  UBRRL = BAUD_PRESCALE;

  UCSRB |= (1 << RXCIE);
  sei();

  for (;;){ 
    PORTD ^= _BV(PD6);
    _delay_ms(50);
  }  

  return 0;
}

ISR(USART_RX_vect){
   char b;
   b = UDR;
   UDR = b;
}

Subo esto con avrdude y el LED no pulsa. Si comento el ISR, funciona como lo esperaría. El sondeo de UART también funciona normalmente, así que estoy bastante seguro de que está configurado correctamente. He podido reproducir esto con un ATmega162 y un ATmega328p.

Otro comportamiento extraño: si compilo sin optimización, el LED pulsará hasta que envíe un byte, luego dejará de latir.

Realmente no tengo idea de dónde radica el problema, ya que cada tutorial que he visto usa casi este código exacto.

    
pregunta Andrew

1 respuesta

1

Me odio por esto. Cómo estaba compilando:

avr-gcc -o build/src/main.o -c -Wall -g -Os -mmcu=attiny2313 src/main.c 
avr-gcc -o build/main.elf build/src/main.o

Cómo debería haber sido:

avr-gcc -o build/src/main.o -c -Wall -Os -mmcu=attiny2313 -std=c99 -ffunction-sections -fdata-sections src/main.c
avr-gcc -o build/main.elf -mmcu=attiny2313 build/src/main.o

El culpable real no fue pasar el indicador -mmcu al vinculador, pero agregar -ffunction-sections y -fdata-sections también solucionó algunos problemas extraños que estaba teniendo al usar archivos de encabezado externos.

    
respondido por el Andrew

Lea otras preguntas en las etiquetas