Moin Moin,
Kniffelig weil folgendes nicht geht und ich frage mich wieso...
1
//wait for MOSI becomes HIGH
2
FL_CS_LOW;// Reset PB0
3
NOP();
4
while(!(PINB&(1<<PINB6)));
5
FL_CS_HIGH;// Set PB0
ABER dies geht:
1
//wait for MOSI becomes HIGH
2
FL_CS_LOW;// Reset PB0
3
NOP();
4
while(!(PINB&(1<<PINB6)));
5
FL_CS_HIGH;// Set PB0
Die fallende Flanke vom reset des PB0 lässt das high auf PB6 ebenfalls
auf LOW fallen. Im oberen code, ist in der while() schleife PB6 noch??
HIGH.
Wieso ist das so und kann man das ohne NOP() umgehen??
Beste Grüße
Karsten
P.S. Hier der "klartext" aus dem lss file....
Karsten K. schrieb:> FL_CS_LOW; // Reset PB0
------------^-------
hier ist ein Space mehr dazwischen.
> FL_CS_HIGH; // Set PB0
-------------^-------
hier ist auch ein Space mehr dazwischen.
Arduinoquäler schrieb:> Karsten K. schrieb:>> FL_CS_LOW; // Reset PB0> ------------^-------> hier ist ein Space mehr dazwischen.>>> FL_CS_HIGH; // Set PB0> -------------^-------> hier ist auch ein Space mehr dazwischen.
Stimmt. Danke.
Nu hört doch auf, ihn zu veräppeln.
Geht es eventuell darum, dass du den Ausgang PB0 mit dem Eingang PB1
verbunden hast und erwartest, dass eine Änderung von PB0 sofort danach
an PB1 sichtbar wird?
Das geht nicht, denn:
1) Nach Absetzen des Befehls, PB0 auf Low zu setzen, dauert ein einige
Nanosekunden, bis der Ausgang wirklich auf Low geht.
2) Der Eingang braucht auch einige Nanosekunden, bis er das erkennt.
3) Die Eingänge und Ausgänge sind synchron getaktet.
Wenn Du ein AusgangsRegister beschreibst, erscheint der neue Status am
Ausgangspin erst beim nächsten I/O Takt. Genau in diesem Moment werden
die Eingänge ins PIN Register geladen.
Deswegen ist ein NOP dazwischen notwendig.
Stefan Us schrieb:> 1) Nach Absetzen des Befehls, PB0 auf Low zu setzen, dauert ein einige> Nanosekunden, bis der Ausgang wirklich auf Low geht.>> 2) Der Eingang braucht auch einige Nanosekunden, bis er das erkennt.
Nein, das sind keine Nanosekunden, also keine Effekte irgendeines
propagation delays, sondern das ist voll synchron. Selbst, wenn du
den Controller mit 32 kHz taktest, brauchst du den NOP. Der Grund ist,
dass das Abtasten des Eingangspins für den IN-Befehl erfolgt, bevor
der OUT-Befehl seine Veränderung am Ausgang bewirkt hat. Dies ist
notwendig, da der Eingangspin auf den IO-Takt synchronisiert werden
muss und seine Information aber zu dem Zeitpunkt, da der IN-Befehl
abgearbeitet wird, bereits stabil (und CPU-Takt-synchron) bereitgestellt
worden sein muss. Schließlich soll der IN ja nicht noch einen
WAIT-Zyklus brauchen.
Steht alles im Datenblatt …
Stefan Us schrieb:> Nu hört doch auf, ihn zu veräppeln.
Okay... hast Du eine Erklärung dafür, dass die erste Version
mit dem NOP nicht geht, während die zweite Version mit dem
NOP funktioniert?
(Und - nein, meine Frage oben enthält keinen logischen Fehler.)
Possetitjel schrieb:> Okay... hast Du eine Erklärung dafür, dass die erste Version> mit dem NOP nicht geht, während die zweite Version mit dem> NOP funktioniert?
Reproduzierbar ?
Oder jedes Ding einmal probiert ?
Identische HW?
Identische Rest-SW ?
Possetitjel schrieb:> hast Du eine Erklärung dafür, dass die erste Version mit dem NOP nicht> geht, während die zweite Version mit dem NOP funktioniert?
Copy&paste-Fehler. Wird aber nur daraus deutlich, dass er fragt,
ob man das ohne NOP umgehen könnte.
OhhhOhhhh!!
Entschuldigt bitte:
Copy und Paste!
Im ersten Falle ist KEIN NOP();
Danke Jörg für die Erklärung. Und Ja! es steht viel in vielen
Datenblättern und leider ist manches eben zwischen den Zeilen verborgen
( so zumindest mein Eindruck ).
Zumindest bin ich jetzt schwer beruhigt, das hier keine merkwürdigen
Laufzeitfehler oder sonstwas ominöses am Werk ist.
Vielen Dank für eure lustigen und erhellenden Beiträge!
Gruß
Karsten ( DG2LAK )
Ja genau, es kommt überhaupt nicht auf die Taktfrequenz an und auch
nicht, wieviele Nanosekunden propagation delay nun vorhanden sind.
Entscheidend ist, dass überhaupt ein Delay vorhanden ist - was
physikalisch wohl kaum vermeidbar ist.
Der eine Taktimpuls, der die Änderung am Ausgang aktiviert, der liest
auch den Pegel am Eingang ein. Und da das Signal nicht ohne Zeit vom
Ausgang zum Eingang kommen kann, braucht man einen NOP dazwischen, so
dass das Lesen des Eingangs eine Takt später stattfindet.