www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART-Interrupt haengt das Programm auf (Atmega8)


Autor: Andrea Runge (drea)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich habe ein riesiges Problem mit meinem ATmega8.
Ich habe ein kleines Programm geschrieben, um ein bischen mit den
Interrupt rumzuspielen. Es soll lediglich eine Ausgabe auf den UART
machen und damit ein Fenster auf meinem Terminal darstellen. Danach
soll es warten bis man ein Programm gewählt hat und dann das
dazugehörige Programm starten. Wenn das Programm läuft soll es durch
ein "e" vom Terminal gestopt werden können. Mein Problem ist nun,
dass wenn ich den Interrupt aktiviere, mein Programm sich aufhängt. Es
zeigt zwar noch das Fenster an, aber in dem Moment wenn die Interrupts
aktiviert werden gibt er das Fenster noch mal aus und das Unterprogramm
läuft nicht ab.
Wenn ich die Interrupts nicht aktiviere, sondern das Programm
blockierend betreibe, läuft es einwandfrei.
Die Interrupts und der UART funktionieren auch, denn die habe ich
vorher schon mit einem anderen Programm getestet. Allerdings habe ich
bei dem anderen Programm nur mit dem UART ein Zeichen empfangen.
Leider weiß ich nicht mehr weiter. Ich habe die ativierung der
Interrputs auch schon an andere Stellen verschoben, doch leider hilft
das auch nichts.
Es wäre schön, wenn noch jemand eine Idee hätte oder mir sagen kann,
was ich falsch mache.

Danke

Autor: Thomas Stütz (tstuetz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was passiert wenn du eine Taste gedrückt hast ?
Bei einem uController sollte es NIE ein Ende von main() geben
=> Endlosschleife!

du hast sowohl im hauptprogramm (main) als auch im RX-Interrupt das
auslesen des RX-Puffers drin - ist das korrekt so ?

Gruss

Autor: Niels Huesken (monarch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Variable ist global UND lokal (in main) definiert.
Da hast du dich bestimmt verkaspert! Aber schön, das du an das volatile
gedacht hast :)

Autor: MooseC (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Problem sehe ich dem doppeltem Uart auslesen. Einmal im Interrupt
und einmal im main. Wenn Du den Interrupt freigibst fängt die
Uart-Serviceroutine alle empfangen Daten weg und im main kannst Du mit
dem RXC bit nicht mehr sehen, ob etwas ankam. Du solltest den Empfang
dann schon komplett im Interrupt mit einem Spooler oder mit eigenen
Flags aubauen und dann verwenden.

Dann noch ein Tip: lege die opulenten Bildschirmmasken lieber im Flash
ab und gebe sie von dort aus. Deine sternchenumrandete Maske hat
bereits 420 Bytes im RAM belegt und der Mega8 hat "nur" 1k RAM.

MooseC

Autor: MooseC (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur: 490 Bytes

Autor: Niels Huesken (monarch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ürgs, meinte die "zeichen" variable, die lokal und global definiert
ist.

das war bestimmt nicht so gedacht.

Autor: Andrea Runge (drea)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen lieben Dank für die ganzen Antworten!
Ich habe das doppelte UART auslesen raus genommen, ist wohl beim
Probieren so da rein gerutscht. Aber das Programm läuft erst richtig,
wenn ich in der UART Initialisierung den Interrupt fürs senden
auskommentiere. Allerdings verstehe ich nicht wieso das Probleme macht,
weil ich den Interrupt doch gar nicht benutze.
Was soll´s, jetzt läuft es. Die anderen Sachen die ihr gepostet habt
werde ich mir gleich anschauen.

Danke noch mal

Autor: Andrea Runge (drea)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab grade versucht, die Maske im Flash abzulegen, aber es hat leider
nicht geklappt. Ich hab erst einen String im Flash abgelegt mit PROGMEM
und dann wollte ich ihn auf den UART ausgeben. Leider kam aber nur
Datenschrott an. Dann habe ich es direkt mit PSTR versucht,
aber auch da kommt nur Datenschrott an. Muß ich da noch irgendwas
beachten, irgend einen cast oder so was?

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Andrea Runge,

Dein Programm muß und wird sich solange merkwürdig verhalten, bis Du
die Antwort von Thomas Stütz liest.

"sollte nie" ist etwas untertrieben, es muß "darf nie" heißen.


Peter

Autor: Niels Huesken (monarch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
;-(
Ich find meine doppelte deklaration der Variable "zeichen" auch
ziemlich wichtig! heul

Die Zeile "uint8_t zeichen;" in main() muss raus, sonst kann das
nicht funktionieren!

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du gibst Rx UND Tx Interrupt frei, hast aber nur eine ISR für den RX
definiert. Das kann nur schiefgehen weil der TX Interrupt immer anliegt
solange kein zeichen im sendebuffer steht.

Autor: Andrea Runge (drea)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Niels,

hab sebstverständlich gleich die doppelte Deklaration entfernt!!
(komischer weise hat es auch mit dieser funzt)
Tschuldige, dass ich das nicht explizit erwähnt hatte :-)


Die Endlosschleife habe ich auch gleich angefügt.
Da sie ja so wichtig ist, könnt ihr mir ja bestimmt auch erklären
warum??

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil Du kein Betriebssystem hast zu dem main() am ende zurückkehren
kann.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Strukturiere das doch mal etwas übersichtlicher um
volatile char zeichen = '\0';

SIGNAL( rx...) {  zeichen = UDR; }

main() {
  init_CharacterFormatOfRS232();
  enable_RX_TX_and_RXCIE();
  sei();
  while(1) { /* betriebssystem :) */
     while(zeichen != '1') /* TuNix */
     while(zeichen != 'e') {
        /* TuWasSinnvolles */
     }
   }
}

Den TX Interrupt darfst Du defintiv nicht freigeben denn der ist immer
aktiv solange kein zeichen im sendebuffer steht.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mist Strichpunkt nach /* TuNix */ vergessen :)

Autor: Andrea Runge (drea)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist mal die neuste Ausgabe von meinem Programm.
So weit funzt es auch. Nur kann ich die Ausgabemaske noch nicht im
Flash ablegen bzw. nicht wieder auslesen.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da brauchst Du etwas mehr dafür

Der Flash ist ein eigener Adressbereich beim AVR (Harward Architektur)
und kann aus C nicht so einfach angesprochen werden wie unter der
üblichen Von Neumann Architektur anderer Prozessoren.
Vereinfacht ausgedrückt: Flash und Ram liegen auf den geleichen
addressen und die normalen C Pointerfunktionen greifen immer auf das
RAM zu. Für Daten im Flash muss man sich etwas verrenken.
Siehe hierzu das Tutorial auf dieser Webseite.

Ums kurz zu machen; Dein code mal für Flash umgestrickt (ungetestet).
/* Es hat sich die Konvention eingbürgert an Funktionen die 
   Datem aus dem Flash verarbeiten die Endung "_P" anzuhängen */
void uart_puts_P (prog_char *s)
{
    char c;
    do
    {                        /* so lange *s != '\0' also ungleich dem
"String-Endezeichen" */
        c = pgm_read_byte(s);  // lese byte aus flash
        if(c == '\0')
             break;
        uart_putc(c);
        s++;
    } while(1);
}


void disp1(void)
{  
   /* PSTR ist ein makro dass dem compiler sagt dass die daten nicht
ins RAM kopiert werden sollen */   
uart_puts_P(PSTR("*******************************************************************\n\r"));
  uart_puts_P(PSTR("**                                                 
             **\n\r"));
  uart_puts_P(PSTR("**       1  Starte Blinklicht                      
             **\n\r"));
  uart_puts_P(PSTR("**       2  Starte Nightrider                      
             **\n\r"));
  uart_puts_P(PSTR("**       e  Stop Programm                          
             **\n\r"));
  uart_puts_P(PSTR("**                                                 
             **\n\r"));
  uart_puts_P(PSTR("*******************************************************************\n\r"));

}

Autor: Andrea Runge (drea)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen lieben Dank,

das werde ich auf alle Fälle noch mal ausprobieren! :-)

Autor: Andrea Runge (drea)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Werner:

Hab´s grade ausprobiert und es läuft super!!

Vielen lieben Dank!!!!!!!

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.