Hallo!
Ich bastel gerade an einer DCF Routine. Ich weis, das es dafür schon
fertige Routinen hier im Forum gibt, nur ist es eben schöner, wenn man
es selbst hinbekommen hat.
Ich nutze als Empfangsteil den Empfänger von Reichelt. Empfang ist
wunderbar und um das Signal auszuwerten nutze ich den Input Capture
Interrupt. Sozusagen setze ich bei steigender Flanke den Zähler auf Null
und bei fallender Flanke versuche ich gerade den zählerstand
auszuwerten. Ich habe mir als erstes über UART über eine Minute die
zählerstände zum Rechner geschickt und mit HTerm angezeigt. Bei den
jeweiligen zählerständen ist eindeutig zu erkennen, was eine logische
eins und eine logische Null sein soll. sozusagen funktioniert mein Code
bis zu dem Punkt ganz gut.
Ich scheitere an dem Punkt, diese 16 Bit großen Zählerstände mit einer
Konstanten zu vergleichen, um festzustellen, ob jetzt eine logische Null
oder logische Eins gesendet wurde.
Sozusagen möchte ich als erstes ein Signal, welches kürzer als 80ms ist,
verwerfen, weil es offensichtlich nicht richtig empfangen wurde. Als
nächstes möchte ich überprüfen, ob das Signal länger als 120ms war, dann
ist es entweder ne logische eins, oder ein schlecht empfangenes Signal,
und so weiter...
mein erster Versuch sah so aus:
1
in temp1, ICR1L
2
in temp2, ICR1H
3
cpi temp2, HIGH(1000)
4
brlo falsch
5
cpi temp1, LOW(1000)
6
brlo falsch
7
.
8
.
9
.
Dieser Code ist eine Katastrophe und funktioniert überhaupt nicht.
Jetzt habe ich hier in einem Tutorial eine bessere Lösung gefunden, die
ich aber rein gar nicht kapiere. Ich schreibs einfach nochmal wie oben
hin, mit den anderen Befehlen.
1
in temp1, ICR1L
2
in temp2, ICR1H
3
ldi temp3, LOW(1000)
4
ldi temp4, HIGH(1000)
5
cp temp1, temp3
6
cpc temp2, temp4
7
brlo falsch
8
.
9
.
10
.
Meine erste Frage dazu ist, warum ich zuerst das LOW-Byte vergleiche,
weil das kann doch durchaus kleiner sein, als das LOW-Byte von 1000,
obwohl die gesamte 16Bit Zahl vielleicht größer ist, als 1000.
Und meine zweite Frage wäre, wie spielt das Carry-Flag da mit rein. Ich
denke fast, wenn ich das mit dem Carry Flag verstanden hab, kapiere ich
meine andere Frage auch von selbst, nur irgendwie erschließt es sich mir
einfach nicht.
Ich hoffe ihr könnt mir ein wenig helfen, und es ist nicht zuviel Text.
MfG Dennis
>> Meine erste Frage dazu ist, warum ich zuerst das LOW-Byte vergleiche,> weil das kann doch durchaus kleiner sein, als das LOW-Byte von 1000,> obwohl die gesamte 16Bit Zahl vielleicht größer ist, als 1000.
Weil es 2 verschiedene Befehle sind. Das eine ist CP und das andere CPC.
Der CPC berücksichtigt das Ergebnis des CP (in Form der Flags) in der
Art, dass man das auf beliebige Bytezahlen erweitern kann. Einfach mal
in der Doku den CPC Befehl genau studieren und mit ein paar Beispielen
durchspielen.
> Und meine zweite Frage wäre, wie spielt das Carry-Flag da mit rein.
Ein Compare macht nichts anderes als eine Subtraktion. Die beiden zu
vergleichenden Werte werden miteiander verglichen (CP a, b) indem b von
a subtrahiert wird. Das Rechenergebnis ist dabei uninteressant und wird
verworfen, lediglich die Flags (Carry, Overflow etc.) bleiben erhalten.
Wenn du dich also fragst, wie das Carry Flag in einem CP reinspielt,
musst du dich fragen, was das Carry Flag bei einer Subtraktion macht
bzw. aussagt.
Karl Heinz Buchegger schrieb:> Ein Compare macht nichts anderes als eine Subtraktion.
Ohne die Werte aber tatsächlich zu ändern.
> Das Rechenergebnis ist dabei uninteressant und wird verworfen
Bei der Subtraktion dagegen wird das Ergebnis (Differenz) an den
Minuenden zugewiesen.
Ich würde die 16 Bit so verkleinern, dass es dann 8 bit werden.
Durch shift operation oder einfach nur das high Byte nehmen.
Dann ist das auch mit dem Vergleichen einfacher.
Okay, vielen Dank euch für eure echt hilfreichen Tipps, ich hab
inzwischen die Befehle mal so mit eingearbeitet, und siehe da, der Code
funktioniert auf einmal, dafür hab ich mir jetzt ein Bier verdient :-)
Ich glaub, ich werde einfach mal ein ganz einfaches Programm schreiben,
und da mal so einen 16 Bit Vergleich simulieren, und da werde ich ja
dann sehen, was so die Flags machen, und wie sich das auswirkt, aber
heute nicht mehr.
Echt nochmal vielen Dank für eure Erklärungen
dennis
> mein erster Versuch sah so aus:> in temp1, ICR1L> in temp2, ICR1H> cpi temp2, HIGH(1000)> brlo falsch> cpi temp1, LOW(1000)> brlo falsch> .> .> .>> Dieser Code ist eine Katastrophe und funktioniert überhaupt nicht.
Ist dir klar, warum das nicht funktioniert?
Nenn die Dinge nicht High und Low sondern Minuten und Sekunden.
Und dann wende mal deine Vorschrift auf die Vergleiche
2 Minuten 38 Sekunden und 1 Minute 58 Sekunden
bzw. 2 Minuten 38 Sekunden und 2 Minuten 12 Sekunden
bzw. 2 Minuten 38 Sekunden und 3 Minuten 12 Sekunden
an. Das 3.te Beispiel zeigt dir (hoffentlich) wo du deinen Denkfehler
gemacht hast. (12 ist zwar kleiner als 38, das spielt aber keine Rolle,
weil 3 Minuten schon mal mehr sind als 2 Minuten. Die Sekunden sind nur
dann interessant, wenn beide Minutenzahlen gleich sind)
Ich glaube, jetzt habe ich zumindest den Befehl cpc verstanden,
sozusagen vergleicht dieser Befehl erstmal die beiden Bytes, und wenn
diese gleich sind wird das Carry noch mit einbezogen, welches von dem
vorherigen cp-Befehl beeinflusst wurde, um zu klären, welcher WErt nun
wirklich größer oder kleiner ist, ich glaube, so langsam komme ich
hinter die einzelnen Flags im Sreg, die haben echt haufen einfluss und
man kann viele schöne Sachen mit denen anstellen :-)
Dennis
Hi
>Ich glaube, jetzt habe ich zumindest den Befehl cpc verstanden,>sozusagen vergleicht dieser Befehl erstmal die beiden Bytes, und wenn>diese gleich sind wird das Carry noch mit einbezogen,...
Nicht ganz. Das Carry-Flag wird generell einbezogen. Ein 'cp(i)' ist,
wie schon gesagt, wie eine Subtraktion. Und das Carry-Flag ist der
Übertrag, wenn der Subtrahend der ersten Subtraktion (Low-Werte) gößer
als der Minuend ist.
MfG Spess