Deine Zeitverzögerungen habe ich mal versucht anhand des Datenblatts nachzurechnen:
Vorab:
Die CPU arbeitet intern (startet) mit einem 8 MHz Clock, dieser wird standardmäßig durch 8 geteilt,
somit bleibt ein Clock von 1 MHz bestehen.
Durch die "single pipeline" Struktur benötigen die meisten der Befehle dann auch entsprechend nur 1 Mikrosekunde.
Nehme ich jetzt mal deine Wartefunktion LCD_DLYL die 46ms dauern soll:
Es wird der Wert Hex 0xDAE0 dezimal 56032 ins X register geladen und in der Schleife kontinuierlich runtergezählt.
sbiw XH_XL,1 benötigt 2 Zyklen
brne ldl1 benötigt 2 Zyklen ausser beim letzten Durchlauf, dann nur einen.
Das sind also 56032 mal 4 Zyklen = 224128-1
nun kommen noch die anderen Befehle dazu
2 push XH
2 push XL
2 ldi
2 ldi
2 pop
2 pop
3 ret
3 der Aufruf der Funktion mit rcall
Also insgesamt 18 Zyklen
Das sind dann 224127+18 = 224145 also 224,145 Millisekunden
Bei 8 MHz wären es 28,0018125 Millisekunden
Jetzt können wir rückwärts rechnen welchen Wert wir wirklich brauchen für 46 ms
46000 - 18 = 45982
geteilt durch 4 für die innere Schleife
jedoch vorher noch einen abziehen
45981 / 4 = 11495,25
somit müste der Wert für das Laden des X Registers 11495 dezimal bzw. 0x2CE7 sein.
-----
Für die 2ms Sekunden wäre es dann
20000-18-1=19981 / 4 = 4994,25 also 49995 bzw. Hexadezimal 0x1383
----
Ich habe auf meinem Rechner nichts mit Atmel drauf,
aber das kann sicher mal jemand überprüfen mit dem Simulator.
Siro
Dies löst zwar nicht dein Problem, aber das Timing der Wartefunktionen sollte damit stimmen, sofern ich nix falsch gemacht habe...
Dein WAIT_KEY: hat aber ein Problem:
Du fragst den Pin ab und dann wird die entsprechende Funktion danach ausgeführt.
Das geht aber SOOOO schnell, das bei der nächsten WAIT_KEY die Taste noch garnicht losgelassen wurde
und somit wartet er garnicht mehr und führt die nächste Funktion sofort aus.
Thema Tastenentprellung.
So kommt leider immer ein Problem zum nächsten. Aber der Ansatz ist doch schonmal gut.
Bau mal einfach in die WaitKey eine lange Schleife rein bzw. rufe dort nur deine LCD_DLY funktion auf, unabhängig ob Taste gedrueckt ist.
und versuche es erneut.
Könnte es auch sein, dass der Watchdog zuschlägt ?
Das WDE Bit im Register WDTCSR mus auf 0 gesetzt sein.
Laut Datenblatt ist es undefiniert ??, hab ich aber auch noch nicht verstanden wie das geht.....
Lesezeichen