Hallo zusammen, ich benutze für ein Funkgeräteprojekt einen ATMega128 (8MHz interner Takt). Der entscheidenden Teil des Codes ist herauskopiert. Dieser Teil soll einen ST7920 LCD-Controller in einem 12864 LCD ansprechen. Die Datenübertragung ist im 8-Bit-Mode. Datenport ist PORTC, Über PA4..PA7 laufen RS, RW, E und RST. Der ATMega128 hat folgende Fuses: L:E4, H:D1, E:FF. Problem: Sobald ich PA7 auf "hi" setze (also nach dem RESET des LCD) und einen weiteren Schreibzugriff auf PORTA durchführe (im Code das Schreiben einer "0"), resettet sich der Controller und das Programm startet neu. Auslöser ist dabei nicht die "0" sondern das Setzen von wahlweise RS, RW oder E in der Funktion lcd_write(). Der Codeschnipsel hängt an (dk7ih.c). Hat jemand eine Idee, worin das Verhalten des Controllers begründet sein könnte? Grüße Peter
:
Verschoben durch Moderator
Hi, VCCs ja, AVCC noch nicht. Kommt also gleich. Danke! Peter
AVCC anzuschließen hatte leider bezüglich des Problems keinen Effekt. Schade. :-(
hallo, schau dir das mal an: Beitrag "Autoreset des Drecks-Arduino deaktivieren." ich hab einen 100nF zwischen VCC und GND und das reset ist weg.
DK7IH (Peter) schrieb: > AVCC anzuschließen hatte leider bezüglich des Problems keinen Effekt. > Schade. :-( Sind auch alle GNDs angeschlossen, ist jedes (A)VCC/GND-Pärchen mit jeweils 100nF abgeblockt? Wenn der Compiler keinen Murks baut, gibt es bei dem gezeigten Code, der nichts anderes macht, als ein paar Pins zu beschreiben, keinen Grund dasfür einen Softwarefehler zu vermuten. Ergo: Hardware.
OK, danke für den Hinweis, werde jetzt mal alle Anschlüsse durchmessen. 73 de Peter
So, leider war diese Prüfung auch unergiebig. Alle VCCs, GNDs und 100nF Kondensatoren sind korrekt angeschlossen. Spannungen liegen korrekt an, Controller wurde auch probehalber gewechselt, immer noch der gleiche Effekt. Compiler ist AVR GCC unter Linux. Grüße Peter
Das Target ist richtig eingestellt? Ansonsten mal das Hex (oder Disassemblat) posten, dann kann man schauen was da passiert.
Hallo, ja, das Target stimmt, das Projekt läuft unter "mini6" und wird auch so von AVRDUDE auf den Controller geladen. Hier mal die entsprechenden Zeilen aus dem Makefile: MCU = atmega128 FORMAT = ihex TARGET = mini6 OPT = 3 Optimierungslevels habe ich verschiedene getestet, jedes Mal das gleiche Ergebnis. Dann habe ich mal probehalber alle Zeilen aus der Funktion lcd_init() in das Hauptprogramm geschrieben. Jetzt tritt der Fehler, was mich sehr verwundert, NICHT mehr auf, wenn lcd_init() nun nicht mehr aufgerufen wird. Dieses Ergebnis ist nicht zufällig sondern reproduzierbar. Könnte es sein, dass der Compiler da einen Fehler macht? Das HEX-File hänge ich an. Gruß Peter
Mea culpa! Muss natürlich statt "lcd_init()" "lcd_write()" heißen!
Kann es sein, dass die Versorgungsspannung des Controllers einbricht, wenn du in der lcd_write etwas auf den Port ausgibst? Dann eventuell extern ein Kurzschluss am Pin gebaut?
tritt das Problem denn bei angeschlossenem und auch bei nicht angesclossenem LCD auf?
Hallo, die Versorgungsspannung habe ich mit dem Scope überprüft, die ist vollkommen glatt. Interessant ist ja, dass wenn ich lcd_write() weglasse und die entsprechenden Aufrufe identisch in das Hauptprogramm setze, der Fehler dann nicht mehr auftritt. Dann habe die PINs an PORTA und PORTC bei Überprüfung mit dem Scope die korrekten Signale und Soft- und Hardware arbeiten einwandfrei. Die Platine habe ich auch überprüft. Zwei ATMega128 (jeweils auf Breakoutboards verlötet) zeigen ebenfalls identisches Verhalten. Daher meine Vermutung, dass der Fehler vom Compiler kommt, der mit dem Handling der Funktion ein Problem hat. Gruß Peter
Das Problem tritt mit und ohne LCD identisch auf.
Ok, dann könnte die Vermutung darin liegen, dass der Stackpointer nicht eingestellt wurde, womit der Controller bei Funktionsaufruf bestimmte Infos nicht auf den Stack bekommt und deshalb einen Reset macht. Allerdings nutzt du C und der Compiler sollte sich darum kümmern, anders als bei Assembler, wo man das selbst einstellen muss. Vielleicht hier was verstellt? Andererseits dürte dann bereits das Betreten der Funktion schon ein Problem sein... Erzeugt dein Compiler ein .lss-File mit Assemblercode und Kommentaren, in denen die C-Befehle stehen? Darüber ließe sich auch einiges heraus finden, denke ich.
Hi, der Compiler erzeugt ein .lss-File, das habe ich mal angehängt.
DK7IH (Peter) schrieb: > Das HEX-File hänge ich an. Das Hex entspricht nicht dem oben gezeigten Code. Denn:
1 | int main(void) |
2 | {
|
3 | DDRA = 0xFF; |
4 | |
5 | PORTA |= 128; |
nach PortA |= 128 sitzt ein Delay drin, dass der Compiler sicher nicht selbst reingebastelt hat, sieht so aus:
1 | ldi r24,k66 |
2 | ldi r25,k0E |
3 | L0069: |
4 | sbiw r24,k01 |
5 | brne L0069 |
und dauert 14744 Takte gleich 1,8ms@8MHz. Außerdem wird in der Main Bit 7 von PortA nach dem Delay wieder gelöscht, bevor's in die lcd_write() geht. Ansonsten sieht der Code aus dem Hex dem geposteten C ähnlich, er rennt zum Schluss in eine Endlosschleife. Du verwechselst da aber nicht eine Endlosschleife mit einem Neustart? Wie willst Du bei diesem Code das Eine vom Anderen unterscheiden? Du müsstest mindestens eine Led beim Startup blinken lassen, um das zu erkennen.
DK7IH (Peter) schrieb: > Der ATMega128 hat folgende Fuses: L:E4, H:D1, E:FF. E:FF ist richtig, versichere Dich dennoch erneut, nicht dass es E:FD heißt und der M103C compatibility mode an ist.
Hi, ja, ich habe den Code zum Testen nochmal zwischendurch etwas verändert. Das Delay hat in der Tat ca. 1ms und ist natürlich von mir. ;-) Der Unterschied zwischen normalem Programmlauf und Dauer-Neustart ist für mich erkennbar, weil ein Scope an PA7 hängt. Wenn das Programm korrekt arbeitet (also der Funktionsaufruf nicht stattfindet) bleibt der Pegel nach dem Togglen auf "hi". Wenn das Programm sich selbst neu startet, wechselt PA7 zwischen 0 (PORTA &= ~(128);) und 1 (PORTA |= 128;). Die Endlosschleife ist ja leer, da passiert dann bei korrektem Programmablauf nichts mehr, was PA7 verändert. Ich hänge nochmal ein .C-, ein .lss und ein HEX-File an, die jetzt zueinander passen. Gruß
Stackpointer wird konfiguriert. Es wird der Speicherbereich des ATmega128 genommen. Im M103C Compatible Mode würde das jedoch über den SRAM hinaus springen, siehe Datenblatt Abschnitt "SRAM Data Memory" (bei mir Seite 17).
Das mit dem M103-Mode war ein guter Tipp. Ich hatte übersehen, dass die Kommandozeile, mit der ich den zweiten ATMega128 eingestellt hatte, ein fehlerhaftes Zeichen hatte. Jetzt sehe ich die ersten Zeichen auf dem Display. Vielen Dank!
Vielen Dank auch an die anderen Autoren hier!
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.