Forum: Mikrocontroller und Digitale Elektronik ASM Lcd Ansteuerung - Atmega 8 bleibt stehen


von Fabian Schmitz (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

habe seit einigen Tagen ein Testboard und einen Atmega 8,
damit versuche ich nun ein Lcd Display anzusteuern.

Ich nutze dafür die SPI Schnittstelle des DIP 204-4 von Electronic
Assembly und habe im Assembler auch funktionierende Routinen dafür
erstellt.

Im angehängten File zeigt sich nun mein Problem:
Das Display gibt eine Zahl aus, die wird in einer Schleife jede Sekunde
um 1 verringert und wieder ausgegeben. Im Simulator funktioniert auch
alles 1a, nur in der Wirklichkeit bleibt der
Atmega 8 nach 1 bis 10 Sekunden stehen - wie er gerade Lust hat.

D.h. mal bleibt 255 stehen und nichts tut sich mehr, ein anderes Mal
läuft er 10 Sekunden bis 245 und quittiert dann den Dienst..
Herausgefunden habe ich schon, das es an der Lcd Ansteuerung liegen
muss. In einfacheren Anwendungen (z.B. Blinken einer Led)läuft er
Stunden ohne Probleme.

Wäre nett wenn ihr mal in das angehängte .asm File reinschauen könntet,
vielleicht findet ihr ja auf Anhieb einige Fehler. Und bitte nicht über
den Code aufregen, programmiere erst seit 2 Wochen : )

Grüße
Fabian

von Werner (Gast)


Lesenswert?

Vielleicht läuft dir der Stack über, in "lcd_senden_cmd" zb. push(t)
du zu Beginn 3mal, aber nur 2 werden per pop wieder ausgelesen.
Vielleicht ist es ja sowas einfachen ;-)

Werner

von leo9 (Gast)


Lesenswert?

@Werner:

Erst lesen, dann antworten ;-)
die Antwort wollte ich auch schon schreiben aber er popt mitten in der
Routine nocheinmal und dann passts wieder.

grüsse leo9

von Quark (Gast)


Lesenswert?

Hallo Fabian,

auch wenn Dein Code nicht grade sehr schwere Kost ist,
wäre es schön (bitte ich Dich), wend Du ein paar Komentare
dazu zu schreiben würdest.
Die "Helfer" haben es dann sehr viel einfacher, und
Anfänger wie ich, können auch noch etwas Lernen. Danke.

Grüße
Quark

von Fabian Schmitz (Gast)


Lesenswert?

Hallo,

Danke erstmal für eure Antworten! Werde den Code mal kommentieren,
allerdings komme ich erst in ein paar Tagen dazu. Zum Stack: Kann er
wegen den pushs schon überlaufen, dann müsste er doch immer zur
gleichen Zeit stehen bleiben oder ?

Grüße
Fabian

von W. Nickel (Gast)


Lesenswert?

Fabian, kannst du dich noch an dein damaliges Projekt erinnern?

Ich habe jetz ein ähnliches Problem und habe diesen Thread gefunden. Ich 
steuere 2 DDS-ICs (AD9833) über SPI mit einem ATMEGA88. Grundlegende 
Treiber-Funktionen wurden schon programmiert und erfolgreich 
ausprobiert. Jetz wollte ich, dass die Phase eines DDS-ICs langsam 
"wegschwimmt". Dazu der folgende Code:
[c]
...
while(1){
  for(uint16_t phi=0; phi<4096; phi++){
    phase(DDS1, phi); // schreibe phi ins Phasenregister des DDS1
    _delay_ms(1);
  }
}
[c]
Das funktioniert wunderbar und die eine Welle auf dem Oszilloskop ändert 
langsam gegenüber der anderen die Phase. Das geht so 1~1.5 Sekunden lang 
gut, danach hört der uc auf, die Daten über SPI auszugeben. Kein 
Watchdog. Keine Ahnung. ?

von W. Nickel (Gast)


Lesenswert?

Ich habe inzwischen weiter rumexperimentiert. Zur besseren Kontrolle 
habe ich noch ein Pin togglen lassen:
1
...
2
while(1){
3
  for(uint16_t phi=0; phi<4096; phi++){
4
    phase(DDS1, phi); // schreibe phi ins Phasenregister des DDS1
5
    _delay_ms(1);
6
    PORTD ^= (1<<PD2);
7
  }
8
}
Die Beobachtungen:
1. Die Zeit bis der uC stehen bleibt hängt (u.a.?) von der 
Betriebsspannung ab. @3V ~ 0.9-1.5s; @4V ~3-4s; @5V ~8-11s (is immer 
unterschiedlich).
2. Der Pin wird ungefähr einmal die Sekunde für ~400us auf Low gezogen. 
Und jetz Achtung: das sogar nach dem Stehenbleiben des uC!

Was gibt es im uC mit Sekundentakt?

PS: Die Fragen sind nicht nur an Fabian gerichtet :)

von W. Nickel (Gast)


Lesenswert?

Uups. Die Sache mit dem Sekundentakt kommt von dem noch angestecktem 
AVRISP-MKII. peinlich
Sonst bleibt alles in Kraft. Ausserdem noch eine Anmerkung: wenn ich die 
Zeile mit phase... auskommentiere, also kein SPI benutze, dann läuft der 
uC und läuft, und läuft.

von ich (Gast)


Lesenswert?

Wäre es dann vielleicht theoretisch möglich, dass der Fehler in der 
'phase'-funktion liegt?

von spess53 (Gast)


Lesenswert?

Hi

1. Du solltest deinen Programmtext erstmal halbwegs lesbar formatieren.
2. Wer ist eigentlich auf die kuriose Idee gekommen, leicht 
achvollziehbare
   Registernamen wie 'r16'... mit Bezeichnungen wie 'tmpxxx' oder 
tempxxx
   zu versehen. Zum einen erhöht sich der Schreibaufwand, und die
   Lesbarkeit des Programmes wird für andere nur erschwert.

MfG Spess

von W. Nickel (Gast)


Lesenswert?

Habe auch ATMEL angefragt. Die wissen es auch nicht und raten mir, einen 
Emulator zuzulegen.
Hier der auf das nötigste reduzierte Code (nur eine Datei), der die 
gleichen Symptome zeigt:
1
#define SPI_PORT PORTB
2
#define SPI_DDR  DDRB
3
#define SCK    PORT5
4
#define MISO  PORT4
5
#define MOSI  PORT3
6
#include <avr/io.h>
7
8
void main(void){
9
  DDRD = 0xff;
10
  PORTD = 0xff;
11
12
  SPI_DDR |= (1 << MOSI) | (1 << SCK);  // Setup port pin directions
13
  SPI_DDR &= ~(1 << MISO);
14
  SPI_PORT |= (1 << MISO) | (1<<SCK) | (1<<MOSI);
15
  SPCR = (1 << SPE) | (1 << MSTR) | (1<<CPOL);  // Enable SPI as Master
16
  while (1) {
17
    SPDR = 100;  // 100 just for example
18
    while(!(SPSR & (1 << SPIF)));  // Wait for previous transmission to complete
19
  }
20
}
Kann das einer Bitte an einem anderen ATMEGA ausprobieren? Habe jetzt 
keine ausser dem 88 hier. Danke.

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.