Hi! Ich möchte einen (Meß-)Wert überwachen und bei einer Änderung um einen bestimmten Betrag eine Aktion ausführen. Dazu dachte ich an folgendes Verfahren: - Wenn der Betrag der Differenz (alterWert-NeuerWert) > Aktionstoleranz, dann agiere... Ich bilde also die Differenz aus (alt-neu). Ist diese negativ, dann einfach negieren und schließlich vergleichen mit Konstante Aktionstoleranz. Das funktioniert soweit ganz gut. Allerdings nicht, wenn ich mich im Bereich um den Maximal- und Minimalwert bewege. Konkret in meinem Fall heißt das: Die Variable ist 8bit und kann auch die volle Breite von 0 bis 255 an Werten annehmen. Als Toleranz nehmen wir mal 3 an, was in etwa 1% entspricht. Wenn sich der (Meß-)Wert nun von 0 auf 255 in einem Intervall ändert, ist das ja faktisch eine Differenz um den Betrag 255, was eindeutig höher ist, als die Vorgabetoleranz von 3. Nur leider geht dann meine o.g. Rechnung nicht ganz auf. Liege ich mit meinen Überlegungen komplett falsch? Für Tips wäre ich sehr dankbar. Irgendwie habe ich da schon seit Tagen eine kleine "Denkblockade". Meine Hardware ist für diesen Fall ein mega32, programmiert wird mit Assembler in Studio4. Der konkrete Anwendungsfall ist die Auswertung von DMX. Da kann solch ein Sprung von 0 auf 255 oder anders herum schon vorkommen. Danke Gralf
255-0 kann kleiner als 3 sein, wenn Du die Bytes mit Vorzeichen interpretierst. In C ist also uint8_t (unsigned char) ok, int8_t (char) nicht. In Assembler ist BRSH ok, BRGE jedoch falsch,
Meine Routine sieht im Moment so aus: .equ toleranz=3 sub old,new in temp,sreg sbrc temp,2 ;negativ? neg old cpi old,toleranz ;|oldval-newval|>=toleranz ? brlo keineAenderung ;nein ;ja,... Ich dachte, dadurch, daß ich die Differenz negiere, wenn das N-Flag gesetzt ist, wird das Ergebnis immer positiv sein und ein Vergleich mit brlo bzw. brsh immer stimmen. Dem ist aber nicht so. Wo ist der Fehler? Komme einfach nicht dahinter. Gralf
> Ich dachte, dadurch, daß ich die Differenz negiere, wenn das > N-Flag gesetzt ist, wird das Ergebnis immer positiv sein und ein > Vergleich mit brlo bzw. brsh immer stimmen. Dem ist aber nicht so. > Wo ist der Fehler? Tritt mal einen Schritt zurück. Wenn du zwei Werte hast, von denen jeder im Bereich 0 bis 255 liegen kann, dann liegt die Differenz dieser beiden Werte im Bereich -255 bis 255. Wie soll der in einen vorzeichenbehafteten 8bit-Wert passen? Wenn du das Ergebnis der Subtraktion als vorzheichenbehaftet interpretierst, dann ergibt 255 - 0 eben nicht 255, sondern -1. Nach Umdrehen des Voreichens wird daraus 1, und das ist kleiner als 3.
@Rolf Danke. Und ich dachte, das neg-Flag wäre sozusagen mein 9.bit, was mir bei der Subtraktion das Vorzeichen angibt. Du meinst also, ich müßte die ganze Sache mit dem Negieren weglassen und einfach: sub old,new cpi old,toleranz ;|oldval-newval|>=toleranz ? brlo keineAenderung ;nein ;ja,... Oder wie? Gralf
Ne, das kann ja auch nicht stimmen. Dann wäre ja z.B. 2-3=-1. Und das vorzeichenlos interpretiert ist doch dann 0xFF und somit größer als die Toleranz von 3, soll es aber nicht sein. Oder habe ich die Sache mit den negativen Zahlen falsch verstanden? Gralf
Hallo, Der konkrete Anwendungsfall ist die Auswertung von DMX. Meinst Du den DMX512 differenz Bus?
Warum SUB?? Vergleiche doch erstmal cp old,new Der Vergleich ergibt 3 Möglichkeiten: - Gleichheit (wegspringen, nixtun) - Größer ("3" addieren, neu vergleichen, reagieren) - Kleiner ("3" subtrahieren, neu vergleichen, reagieren) Ich messe auf diese Art RC-Impulsbreiten mit einer Hysterese, innerhalb der Änderungen nicht übernommen werden, damit das system nicht "flattert" (Jitterunterdrückung). ...
Egal ob CP oder SUB - das gesuchte 9.Bit ist das Carry-Bit. "2-3=-1. Und das vorzeichenlos interpretiert ist doch dann 0xFF und somit größer als die Toleranz von 3" Irrelevant. Bei der Subtraktion entsteht hier ein Übertrag (Carry/Borrow) und auf den wird getestet. Nicht auf das Vorzeichen vom Ergebnis.
1 | .equ toleranz=3 |
2 | sub old,new |
3 | brcc noneg |
4 | neg old |
5 | noneg: |
6 | cpi old,toleranz ;|oldval-newval|>=toleranz ? |
7 | brcs keineAenderung |
Peter
Danke für die vielen Antworten! Leider mußte ich nebenbei noch was für die Miete tun, so daß ich erst jetzt wieder dazu komme. Habe es gerade ausprobiert. Danke, das war's. Es geht mit dem Carry-Flag. Danke, Peter, für den Hinweis. Bei den ganzen Flags im Statusregister steige ich noch nicht bis ins letzte durch. Liegt wahrscheinlich an der absolut mangelhaften Dokumentation. Welcher Operation welches Bit verändert, ist zwar schön im Instruction Set im Datenblatt aufgelistet, aber warum und unter welcher Bedingung welcher Befehl welches Bit setzt oder löscht, steht da nicht. Gerade das braucht man doch, um die Bits richtig zu interpretieren und auswerten zu können. Kann da jemand vielleicht eine Quelle nennen, wo das ausführlicher dargestellt ist? Mit dem Carry und Zero habe ich jetzt schon des öfteren zu tun gehabt. Aber z.B. mit Halfcarry und dem V-Flag (?) kann ich gar nichts anfangen. Das hier jetzt im Forum breit zu treten ist vielleicht zu viel. Ein Artikel im Tutorial wäre vielleicht ganz nett, oder halt eine externe Quellenangabe... Nochmals Danke Gralf PS: @Hans Muster Ja, es geht hier um den DMX512-Bus. Aber die Differenz-Eigenschaft des Bus-Signals hat mit o.g. Problem nichts zu tun. Das macht ganz leicht ein Schnittstellenwandler-Chip.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.