Forum: Mikrocontroller und Digitale Elektronik ATMega128 - Programm Reset nach Portzugriff (PORTA)


von DK7IH (Peter) (Gast)


Angehängte Dateien:

Lesenswert?

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
von MWS (Gast)


Lesenswert?

AVCC und alle VCCs angeschlossen?

von DK7IH (Peter) (Gast)


Lesenswert?

Hi,

VCCs ja, AVCC noch nicht. Kommt also gleich. Danke! Peter

von DK7IH (Peter) (Gast)


Lesenswert?

AVCC anzuschließen hatte leider bezüglich des Problems keinen Effekt. 
Schade. :-(

von friend (Gast)


Lesenswert?

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.

von MWS (Gast)


Lesenswert?

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.

von DK7IH (Peter) (Gast)


Lesenswert?

OK, danke für den Hinweis, werde jetzt mal alle Anschlüsse durchmessen. 
73 de Peter

von DK7IH (Peter) (Gast)


Lesenswert?

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

von MWS (Gast)


Lesenswert?

Das Target ist richtig eingestellt?
Ansonsten mal das Hex (oder Disassemblat) posten, dann kann man schauen 
was da passiert.

von DK7IH (Peter) (Gast)


Angehängte Dateien:

Lesenswert?

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

von DK7IH (Peter) (Gast)


Lesenswert?

Mea culpa! Muss natürlich statt "lcd_init()" "lcd_write()" heißen!

von Felix (Gast)


Lesenswert?

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?

von hm (Gast)


Lesenswert?

tritt das Problem denn bei angeschlossenem und auch bei nicht 
angesclossenem LCD auf?

von DK7IH (Peter) (Gast)


Lesenswert?

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

von DK7IH (Peter) (Gast)


Lesenswert?

Das Problem tritt mit und ohne LCD identisch auf.

von Felix (Gast)


Lesenswert?

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.

von DK7IH (Peter) (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

der Compiler erzeugt ein .lss-File, das habe ich mal angehängt.

von MWS (Gast)


Lesenswert?

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.

von MWS (Gast)


Lesenswert?

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.

von DK7IH (Peter) (Gast)


Angehängte Dateien:

Lesenswert?

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ß

von Felix (Gast)


Lesenswert?

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).

von DK7IH (Peter) (Gast)


Lesenswert?

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!

von DK7IH (Peter) (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.