Hallo,
ich nutze den Codevision-Compiler habe folgenden Code :
1
2
PORTD.5=1;
3
#asm("CLI")
4
display_string("Testausgabe",25,40,6);
5
#asm("SEI")
6
PORTD.5=0;
Die Funktion display_string sendet über die SPI-Schnittstelle Daten an
das Display und lies das Ack über SPI zurück.
Die SPI-Schnittstelle funktioniert nicht über Interrupt. Alle 50ms wird
ein Timerinterrupt ausgeführt.
Wenn ich nun den Ausgang D5 mit dem Oszi beobachte, so messe ich, dass
er für die Ausgabe "Testausgabe" für 10ms High ist. Manchmal aber auch
für 60ms.
Kann ich nun daraus schließen, dass das Display an der sporadischen
Verzögerung schuld ist??
Miriam schrieb:> Wenn ich nun den Ausgang D5 mit dem Oszi beobachte, so messe ich, dass> er für die Ausgabe "Testausgabe" für 10ms High ist. Manchmal aber auch> für 60ms.
Daran sieht man schön, daß es unklug ist, LCD-Ausgaben in Interrupts
oder unter Interruptsperre zu machen.
10ms sind nämlich verdammt lang, da können viele andere Interrupts
verloren gehen.
Die 60ms scheinen, daß Du auch im Interrupt mit PORTD rum machst.
Peter
Hallo!
> Die 60ms scheinen, daß Du auch im Interrupt mit PORTD rum machst.
Nicht unbedingt.
Was kann zwischen Zeile 1 und Zeile 2 passieren?
Was passiert nach der Zeile 5, wenn zwischenzeitlioch der Timer
übergelaufen ist?
Woher kann ich wissen was passiert wenn der Timer überläuft, eigentlich
einen Interrupt ausführen möchte, aber nicht darf?
Wie löse ich die Ausgabe am Display geschickter? Soll ich besser auch
die SPI-Kommunikation über Interrupt lösen?
Miriam schrieb:> Woher kann ich wissen was passiert wenn der Timer überläuft, eigentlich> einen Interrupt ausführen möchte, aber nicht darf?
steht im Datenblatt, aber ich würde einfach davon ausgehen das ebend
nichts passiert. Der Timer wird deswegen nicht stehen bleiben.
Miriam schrieb:> Wie löse ich die Ausgabe am Display geschickter?
Geschickter als was?
Das da oben ist ja nicht wirklich ein Codeausschnitt, mit dem man
irgendwas anfangen kann.
10ms für das LCD ist auch viel zu lang.
Ein Zeichen dauert max 50µs, Du gibst 11 aus, d.h. nach 550µs sollte es
fertig sein. Es sind aber 9450µs mehr.
Da ist also irgendwas faul in der LCD-Routine.
Peter
Hallo!
> Woher kann ich wissen was passiert wenn der Timer überläuft, eigentlich> einen Interrupt ausführen möchte, aber nicht darf?
Der Interrupt wird sofort nach Zeile 4 ausgeführt, noch bevor Du in
Zeile 5 den Ausgang PORTD.5 zurücksetzt! Der Timer-INT kann aber auch
schod nach der ersten Zeile zuschlagen, dann hast Du PORTD.5 schon
gesetzt und der INT wird erst in der zweiten Zeile verboten.
Also: Zeitmessungen komplett! in CLI/SEI schachteln.
1. und 2. sowie 4. und 5. Zeile tauschen.
Die Ausgabe in der iLCD-Routine funktioniert nach folgendem Schema:
1
while((ack!=0x06)&&(run<=MAX_SPI_RUN))
2
{
3
spi(DC1);
4
spi(len);spi(ESC);spi('Z');
5
spi('L');spi(x);
6
spi(y);
7
for(i=0;i<(len-6);i++)
8
{
9
sum=sum+(int)str[i];
10
spi(str[i]);
11
}
12
sum=sum+DC1+(int)len+ESC+'Z'+'L'+x+y+NUL;
13
bcc=(unsignedchar)(sum%256);
14
spi(NUL);
15
spi(bcc);
16
17
delay_us(100);
18
ack=spi(0x00);
19
versuche++;
20
}
Die SPI-Kommunikation ist auf eine Datenrate von 115,195 kHz
eingestellt. Laut Datenblatt des Displays kann unter 100kHz im "NonStop"
Betrieben werden, ab 100 kHz sollte man zwischen den einzelnen Bytes
min. 100usec Pause lassen. Wenn ich diese zwischen die einzelnen
spi-Sende Befehle einfüge, braucht das Display jedoch wesentlich länger.
Du mußt in Zeile 58 ein
POKE 0xD00F
einbauen.
Im Ernst: Du wirst keine gescheite Analyse Deines Problems bekommen,
wenn Du nur ein paar Brocken von Deinem Programm rausrückst.
Wo ist der Timer-Interrupt?
Wie sieht main() aus?
Miriam schrieb:> Die Ausgabe in der iLCD-Routine funktioniert nach folgendem Schema:
Ich vermute mal, das ist ein eDIPTFT43-A.
Daß das wirklich funktionieren soll, kann ich mir nicht vorstellen.
Die korrekte Methode ist, man fragt vorher ab, ob für das Kommando
genügend Platz im Puffer ist. Und dann schickt man es ab und kriegt ACK
zurück.
Es kann sein, daß das dauernde Senden, bis es zufällig mal klappt,
Schuld daran ist, daß es so lange dauert.
Peter