Problem mit Interrupt? Drehe bald durch

Gast #181312
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
Gast #181314
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!

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.