Hallo, kann mir jemand schreiben, was ich bei der nachfolgenden if-Abfrage falsch mache? Egal, ob ich in die Bedingung eins oder null einsetze, immer wird Anweisung2 ausgeführt: if ((PINB &= 16) ==1) anweisung1 /* z.B. PORTC = 251;*/ else anweisung2 /* z.B. PORTC127; */ In seltenen Fällen funktioniert es, aber für die Abfrage eines PWM-Gerätes ist das zu wenig. Ich benutze avr-gcc, einen ATmega16 und der abzufragende Pin liegt über 10k an high. Kann es sein, daß solche if-Abfragen generell etwas hakelig sind? Bei der Ansteuerung eines I2C-Bausteins erhält man auch gelegentlich eine Errormeldung. mfg Günther
Sei gegrüßt fremder "----". > if ((PINB &= 16) ==1) zunächst wird PINB &= 16 ausgeführt und das Ergebnis in PINB abgelegt. PINB kann bei dieser Anweisung aber nur die Werte 0 oder 16 annehmen, weshalb dein Vergleich dann später auf 1 fehlschlägt. Laß zudem noch das '=' wech, denn du willst das PINB-Register nicht mit dem errechneten Wert beschreiben. Eine Lösung hat ja "----" schon geschrieben. > Kann es sein, daß solche if-Abfragen generell etwas hakelig sind? Nein! > Bei der Ansteuerung eines I2C-Bausteins erhält man auch gelegentlich eine Errormeldung. vermutlich Timingprobleme. ----, (QuadDash). ^^^^^^^^^^^^^^^^^ - nur echt mit dieser Sig :)
@---- Wo ist der Unterschied? Solche Dinger habe ich natürlich durchprobiert. Die Version habe ich aus dem ATmega-Manual übernommen (ist dort bei I2C-Ansteuerung beschrieben). Hier nochmals der Inhalt der lst-Datei Quellcode: if ((PINB & 1<<3) == 1) /*((PINB & _BV(3)) == 1) (PINB &~8) */ PORTC=127; else PORTC &=251 ; PORTC=255; lst-file { if ((PINB & 1<<3) == 1) /*((PINB & _BV(3)) == 1) (PINB &~8) */ 3a2: 86 b3 in r24, 0x16 ; 22 3a4: 99 27 eor r25, r25 3a6: 88 70 andi r24, 0x08 ; 8 3a8: 90 70 andi r25, 0x00 ; 0 3aa: 01 97 sbiw r24, 0x01 ; 1 3ac: 19 f0 breq .+6 ; 0x3b4 PORTC=127; else PORTC &=251 ; 3ae: aa 98 cbi 0x15, 2 ; 21 PORTC=255; 3b0: 25 bb out 0x15, r18 ; 21 3b2: f7 cf rjmp .-18 ; 0x3a2 3b4: 35 bb out 0x15, r19 ; 21 3b6: fc cf rjmp .-8 ; 0x3b0 Sieht doch normal aus? Funktioniert trotzdem nicht. Gruß Günther
Hi ----, (QuadDash). ^^^^^^^^^^^^^^^^^ ( richtig so?) > if ((PINB &= 16) ==1) >zunächst wird PINB &= 16 ausgeführt und das Ergebnis in PINB abgelegt. >PINB kann bei dieser Anweisung aber nur die Werte 0 oder 16 annehmen, >weshalb dein Vergleich dann später auf 1 fehlschlägt. Vielleicht liegt darin mein Denkfehler. Ich will ja nicht wissen, wie die PINB heißen (also PinB4 =16) sondern was daran anliegt, also liegt an PIN 4 Null oder Eins an. Danach wollte ich mit dem if fragen. Aber wie macht man es richtig? Gruß Günther Y
> Sieht doch normal aus? Funktioniert trotzdem nicht. Selbstzitat: "PINB kann bei dieser Anweisung aber nur die Werte 0 oder 16 annehmen, weshalb dein Vergleich dann später auf 1 fehlschlägt" Nebenbei zur Info: (PINB & 1<<3) ist ungleich (PINB & 16) > Die Version habe ich aus dem ATmega-Manual übernommen (ist dort bei I2C-Ansteuerung beschrieben). Vermutlich aber nur für den niederwertigsten Pin (PinB0), dann funktioniert der Vergleich auf 1 nämlich. Ansonsten ist das einfach falsch. Und wie du deinem Listfile entnehmen kannst, ist dein Compiler auch meiner Meinung :) (PORTC=127; wird wegoptimiert oder interpretier ich das was falsch?). ----, (QuadDash).
> Hi ----, (QuadDash). > ^^^^^^^^^^^^^^^^^ ( richtig so?) Super ;) (blöder Name, ich weiss). > Ich will ja nicht wissen, wie die PINB heißen (also PinB4 =16) Das hat damit nix zu tun. > Aber wie macht man es richtig? Variante 1: if (PINB & 1<<3) Variante 2: if ((PINB & 1<<3) == 0x08) ist Geschmackssache. ----, (QuadDash).
Variante 3: if ((PINB & 1<<3) == 1<<3) macht mehr Sinn als Variante 2 - da man sich ja extra für diese Notation entschieden hat. Variante 4: if (PINB & 0x08) Variante 5: if ((PINB & 0x08) == 0x08) ----, (QuadDash).
if ((PINB & 1<<3) != 0) klappt mit jeder Bitmaske Die meisten C-Programmierer wissen aber, daß alles != 0 wahr ist und schreiben: if (PINB & 1<<3) Peter
und wenn du noch ein Klammerpaar mehr schreibst ist es sogar auch noch lesbar:-) if (PINB & (1<<3)) Gruss Christian P.S. Gewisse C-Compiler hatten nämlich ohnehin Problemen mit der Operator-Reihenfolge der Schiebeoperatoren und hätten den Ausdruck ohne Klammern falsch ausgewertet.
Die wären allerdings hochgradig kaputt. Anyway, viele C-Compiler werden das warnen, da man sich als Leser oft genug nicht sofort im Klaren sein muß, welche der Operatoren den Vorrang haben.
Hallo, vielen Dank für die Hinweise, meine letzten Versuche mit if (PINB & 8) bzw. if (PINB & (1<<3)) oder if (PINB & (_BV(3))) waren erfolgreich! Aber jetzt geht es nicht mehr, weil ich mit TwinAVR keine Verbindung mehr bekomme. Wer weiß, woran das wieder liegt. Viele Grüße Günther
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.