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
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
@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
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
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
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. ?
Ich habe inzwischen weiter rumexperimentiert. Zur besseren Kontrolle
habe ich noch ein Pin togglen lassen:
1
...
2
while(1){
3
for(uint16_tphi=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 :)
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.
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
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
voidmain(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.
Eine eigene Frage?
Dieser Thread ist über 22 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.