Hallo, ich stehe vor folgendem Problem... Ich habe 24Bit die ich ab intr X polle (4x 8Bit ATMEGA16 PORTA,B,C) und möchte bei jedem der 8Bit einen wechsel von 2Bit feststellen können. Meine Kenntnisse in C reichen leider nicht sehr weit für eine "elegante" Lösung und würde es bisher wie folgt versuchen... int ME_Alert (int leg1_sav, int leg2_sav, usw...) { int i; i=0; while (PD2 == 0 & i<=2) { if (LEG1_STATUS = leg1_sav) {} else{i++} if (LEG2_STATUS = leg2_sav) {} else{i++} if (LEG3_STATUS = leg3_sav) {} else{i++} if (LEG4_STATUS = leg4_sav) {} else{i++} } return i; } wobei #define LEG1_STATUS (PINA & 0xFC) #define LEG2_STATUS ((PINA & 0x03) | (PINB & 0x0F)) #define LEG3_STATUS ((PINB & 0xF0) | (PINC & 0xC0)) #define LEG4_STATUS (PINC & 0x3F) Danke vorab für Eure hilfe!!! Gruß Nacho
1) Code Tags benutzen! 2) if(a = b) ist an dieser Stelle falsch, da es eine Zuweisung ist. (a == b) ist hier richtig. 3)
1 | if (LEG1_STATUS = leg1_sav) {} |
2 | else{i++} |
3 | |
4 | // besser, schneller, übersichtlicher ist
|
5 | if(LEG1_STATUS != leg1_sav) |
6 | {
|
7 | i++; |
8 | }
|
4) So richtig verstehe ich nicht, was du erreichen willst. Willst du LEG1_STATUS mit einem anderen Bitmuster prüfen?
Hab ich eben noch übersehen:
1 | while ((PD2 == 0) && (i<=2)) |
Ein &-Zeichen ist eine binäre Verknüfpung. Zwei &-Zeichen ist eine logische Verknüpfung.
> Hab ich eben noch übersehen: > while ((PD2 == 0) && (i<=2)) > > > Ein &-Zeichen ist eine binäre Verknüfpung. Zwei &-Zeichen ist eine > logische Verknüpfung. Außerdem ist PD2 eine Konstante, die den Wert 2 hat, wird also sowieso niemals gleich 0 sein.
Zunächst mal danke für die Hinweise Lordziu... Zu deiner Frage wo ich hin möchte... Ich frage vor dem pollen einmalig den Status meiner DIs ab. Der Wert wird in legx_sav abgelegt. jedes "leg" soll nun nachher mit seiner legx_sav verglichen werden. Beim pollen möchte ich feststellen, ob bei legx_status gegnüber legx_sav kein, ein, zwei oder mehrere Bits geflippt sind... Wenn zwei oder mehr Bits pro legx ihren wert geändert haben soll wird Funktion Y ausgeführt werden... Mein Hauptproblem ist wie gesagt das feststellen wieviele bits gegenüber dem abgesicherten wert geflippt sind... Als Bsp.: angenommen logx_sav = 0b00010100 1. Abfrage ergibt: logx_status = 0b01010100 //1Bit... Ohne Auswirkungen 2. Abfrage ergibt: logx_status = 0b01010101 //2Bit... Funktion Y ausführen Verständlicher? :) Gruß Nacho
Hi Exclusive-Or. Und dann Bits Zählen. In Assembler kein Problem. MfG Spess
spess53 schrieb:
> In Assembler kein Problem.
In C auch nicht ^^ (nur halt ein bisschen langsamer)
>> In Assembler kein Problem. > > In C auch nicht ^^ (nur halt ein bisschen langsamer) Ja, vielleicht so ;-))
1 | #include <inttypes.h> |
2 | |
3 | // bla...bla..code..code
|
4 | |
5 | uint8_t number=ui8; // Byte, von dem wir wissen wollen, |
6 | // wie viele Bits gesetzt sind
|
7 | uint8_t count=0; // Anzahl der Bits in "ui8" |
8 | |
9 | /* dann irgenwo: */
|
10 | asm volatile ( |
11 | "ldi r16,8 \n\t" |
12 | "mov __tmp_reg__, %1 \n\t" |
13 | "clr %0 \n\t" |
14 | "L_0:" "rol __tmp_reg__ \n\t" |
15 | "brcc L_1 \n\t" |
16 | "inc %0 \n\t" |
17 | "L_1:""dec r16 \n\t" |
18 | "brne L_0 \n\t" |
19 | :"=&r" (count) |
20 | :"r" (number) |
21 | :"r16" |
22 | );
|
Natürlich ohne Gewähr. Ginge vielleicht auch unter Umgehung der "mov"-Zeile, aber ich habe mit dem Inlne-Assembler wenig Übung und bin da eher vorsichtig.
Hi Da ich kein C kann, ( noooch niicht) mal kurz, wie's gehen sollte Wert_alt XOR Wert_Neu -> Ergebnis gewechselte Bits Wert_alt AND Gewechselte Bits -> Flanke nach 0 / zwar nicht gefragt Wert_Neu AND Gewechselte Bits -> Flanke nach 1/ dto Gewechselte Bits schieben und Carry-Flag abfragen, bei Carry Zähler Incrementen.. Sollte in jeder Sprache umsetzbar sein. Gruß oldmax
> Wert_alt XOR Wert_Neu -> Ergebnis gewechselte Bits ... nicht nötig > Gewechselte Bits schieben und Carry-Flag abfragen, bei Carry Zähler > Incrementen.. Letzteres ist genau, was mein Inline-Assembler-Programm (s.o.) macht.
War vielleicht unklar: Das "nicht nötig" oben bezog sich auf die Schritte 2 und 3 im Ablauf, den oldmax vorgeschlagen hatte.
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.