mikrocontroller.net

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


Autor: Werner Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist deine ISR?

Autor: Werner Meier (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.