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
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
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 :)
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
Ürgs, meinte die "zeichen" variable, die lokal und global definiert ist. das war bestimmt nicht so gedacht.
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
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?
@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
;-( 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!
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.
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??
Weil Du kein Betriebssystem hast zu dem main() am ende zurückkehren kann.
Strukturiere das doch mal etwas übersichtlicher um
1 | volatile char zeichen = '\0'; |
2 | |
3 | SIGNAL( rx...) { zeichen = UDR; } |
4 | |
5 | main() { |
6 | init_CharacterFormatOfRS232(); |
7 | enable_RX_TX_and_RXCIE(); |
8 | sei(); |
9 | while(1) { /* betriebssystem :) */ |
10 | while(zeichen != '1') /* TuNix */ |
11 | while(zeichen != 'e') { |
12 | /* TuWasSinnvolles */
|
13 | }
|
14 | }
|
15 | }
|
Den TX Interrupt darfst Du defintiv nicht freigeben denn der ist immer aktiv solange kein zeichen im sendebuffer steht.
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.
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).
1 | /* Es hat sich die Konvention eingbürgert an Funktionen die
|
2 | Datem aus dem Flash verarbeiten die Endung "_P" anzuhängen */
|
3 | void uart_puts_P (prog_char *s) |
4 | {
|
5 | char c; |
6 | do
|
7 | { /* so lange *s != '\0' also ungleich dem |
8 | "String-Endezeichen" */
|
9 | c = pgm_read_byte(s); // lese byte aus flash |
10 | if(c == '\0') |
11 | break; |
12 | uart_putc(c); |
13 | s++; |
14 | } while(1); |
15 | }
|
16 | |
17 | |
18 | void disp1(void) |
19 | {
|
20 | /* PSTR ist ein makro dass dem compiler sagt dass die daten nicht
|
21 | ins RAM kopiert werden sollen */
|
22 | uart_puts_P(PSTR("*******************************************************************\n\r")); |
23 | uart_puts_P(PSTR("** |
24 | **\n\r")); |
25 | uart_puts_P(PSTR("** 1 Starte Blinklicht |
26 | **\n\r")); |
27 | uart_puts_P(PSTR("** 2 Starte Nightrider |
28 | **\n\r")); |
29 | uart_puts_P(PSTR("** e Stop Programm |
30 | **\n\r")); |
31 | uart_puts_P(PSTR("** |
32 | **\n\r")); |
33 | uart_puts_P(PSTR("*******************************************************************\n\r")); |
34 | |
35 | }
|
Vielen lieben Dank, das werde ich auf alle Fälle noch mal ausprobieren! :-)
@Werner: Hab´s grade ausprobiert und es läuft super!! Vielen lieben Dank!!!!!!!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.