Forum: Compiler & IDEs Problem mit Interrupt? Drehe bald durch


von Werner Meier (Gast)


Lesenswert?

Hallo zusammen,
Ich habe einen ATMega16 und benutze das neueste WinAVR.
Hier ist mein Quellcode:

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

void delay_ms(uint16_t ms) {
  for (uint16_t i=0;i<ms;i++) {
    _delay_ms(1);
  }
}

void uart_putc(uint8_t c) {
  while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
  UDR = c;                      /* sende Zeichen */
}

int main (void) {
  PORTA=0x00;
  DDRA=0x00;

  UCSRA=0b00000000;
  UCSRB=0b11011000;
  UCSRC=0b10100110;
  UBRRH=0b00000000;
  UBRRL=0b01100111;

  // Global enable interrupts
  sei();

  delay_ms(500); // *3
  uart_putc(0x89);
  DDRA=0xFF; // Wird ausgefuehrt *1
  delay_ms(500); // *4
  //DDRA=0xFF; // Wurde nicht mehr ausgefuehrt *2
  uart_putc(0x57);

  while (1) {
  };

  return 1;
}


Mein Problem ist, dass *2 nicht ausgefuehrt wird, wenn ich Interrupts
angeschaltet habe. Wenn ich sei() auskommentiere klappt alles oder wenn
ich das USART ohne den Transmit Interrupt initialisiere.
Wenn ich die Zeilen mit delay_ms auskommentiere klappt es auch.
Kommentiere ich *4 aus klappt es, wenn nur *3 weg ist, klappt es
nicht.
Also wenn ich erst uart_putc und dann delay_ms aufrufe, stürzt es genau
da ab.
Ich habe mir die cof Datei generiert und im AVR Studio debuggt. Da
stürzt das Programm auch an der Stelle ab.
Ich weiß nicht mehr weiter.
Bitte helft mir! :)
Grüße

von Mike (Gast)


Lesenswert?

Wo ist deine ISR?

von Werner Meier (Gast)


Lesenswert?

Die hatte ich nach und nach rausgekürzt bei der Fehlersuche:

// USART Receiver buffer
// 512, da eine Message theoretisch 260 Zeichen lang sein koennte und
dann noch etwas Zeit gebraucht wird,
// um sie zu identifizieren
#define RX_BUFFER_SIZE 511
uint8_t rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
uint8_t rx_wr_index, rx_rd_index, rx_counter;
#else
uint16_t rx_wr_index, rx_rd_index, rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
uint8_t rx_buffer_overflow;

// USART Receiver interrupt service routine
//interrupt [SIG_USART_RECV] void usart_rx_isr(void) {
SIGNAL (SIG_USART_RECV) {
  uint8_t status, data;
  status = UCSRA;
  data = UDR;
  if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
    // Wenn alles ok ist, dann Daten in Puffer speichern
    rx_buffer[rx_wr_index] = data;
    // Wenn der Puffer am Ende ist
    if (++rx_wr_index == RX_BUFFER_SIZE) {
      // dann auf Anfang setzen
      rx_wr_index = 0;
    }
    // Wenn der Puffer voll ist
    if (++rx_counter == RX_BUFFER_SIZE) {
      // Fehler ausgeben und Zaehler zuruecksetzen
      rx_counter = 0;
      rx_buffer_overflow = 1;
    }
  }
}

// USART Transmitter buffer
#define TX_BUFFER_SIZE 255
uint8_t tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
uint8_t tx_wr_index,tx_rd_index,tx_counter;
#else
uint16_t tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service routine
//interrupt [SIG_USART_TRANS] void usart_tx_isr(void)
SIGNAL (SIG_USART_TRANS) {
  // Wenn Daten im Puffer sind
  if (tx_counter) {
    // Zaehler erniedrigen
    --tx_counter;
    // Daten senden
    UDR = tx_buffer[tx_rd_index];
    // Wenn der Puffer am Ende ist
    if (++tx_rd_index == TX_BUFFER_SIZE) {
      // dann auf Anfang setzen
      tx_rd_index = 0;
    }
   }
}

Jetzt geht alles wieder, wenn ich sie reintue!

Ich schätze, dass ich ursprünglich ein anderes Problem hatte und mir
dann durch wegkürzen der Funktionen dieses geschaffen habe.

Dank Dir für den Hinweis!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.