Forum: Compiler & IDEs Eingänge vergleichen


von Mathiable (Gast)


Lesenswert?

Guten Tag

Ich habe eine verhältnismässig einfache Frage, bin aber schon länger 
daran am verzweifeln. Und zwar ist es so, dass ich quasi die drei Phasen 
einer Steckdose überwachen soll. Die Positive Halbwelle  kommt als 
Rechteckssignal an einen Atmega48. Nun muss ich unter anderem Fehler der 
Eingänge herausfiltern, beispielsweise wenn 2 Eingänge phasengleich 
sind. Ich dachte da an eine relativ einfache for Schleife:

    #define L1 (PIND&(1<<PIND5))
    #define L2 (PIND&(1<<PIND4))

    for(ms=0;L1==L2;ms++)
    {
       if(ms==20) return (false);

       long_delay(1);
   }

Wie ich schmerzlich erfahren musste funktioniert das mit dem "==" 
(zumindest bei Eingängen) nicht so einfach wie mit anderen C Compiler.

Weiss irgendjemand eine elegante Alternative für mein Problem?

von Karl H. (kbuchegg)


Lesenswert?

Mathiable schrieb:
>
> Wie ich schmerzlich

Wieso schmerzlich? Hast du auf die 230V gegriffen?

> erfahren musste funktioniert das mit dem "=="
> (zumindest bei Eingängen)

Du hast dir mit den Makros selber ins Knie geschossen.

Letztenendes steht da etwas ähnliches wie

        4 == 5

und es ist klar dass die nie gleich sein werden. In diesem Sinne wird 
(PIND&(1<<PIND5)) nur dann gleich (PIND&(1<<PIND4)) sein, wenn beide ein 
0-Bit an den enstprechenden Position haben. Bei einer 1 an Pin 5 und 
einer 1 an Pin 4 kann da niemals ein true herauskommen, weil ja jedesmal 
ein anderes Bit gesetzt ist.

> nicht so einfach wie mit anderen C Compiler.

Das hat weniger mit dem Compiler zu tun und mehr mit allgemeiner 
Programmlogik :-)

Wenn du das mit Makros ein wenig lesbarer gestalten willst, dann machs 
so
1
#define BIT_VALUE( PORT, BIT )   ( ( (PORT) & (1<<(BIT)) != 0 )
2
#define L1_VALUE   BIT_VALUE( PIND, PIND4 )
3
#define L2_VALUE   BIT_VALUE( PIND, PIND5 )
4
5
...
6
7
      for(ms=0; L1_VALUE == L2_VALUE; ms++ )

Der Vergleich != 0 ist wichtig. Erst er transformiert ein gesetztes Bit 
in den Zahlenwert 1

von Peter (Gast)


Lesenswert?

L1 ist niemals gleich L2, denn sind andere Bits:

PIND4 = 0b00010000
PIND5 = 0b00100000

Aber Du kannst prüffen, ob beide Bits TRUE sind mit dem logischen AND 
Operator => (&&)
1
    #define L1 (PIND&(1<<PIND5))
2
    #define L2 (PIND&(1<<PIND4))
3
4
    for(ms=0; (L1 && L2); ms++)
5
    {
6
       if(ms==20) return (false);
7
8
       long_delay(1);
9
   }

von Mathiable (Gast)


Lesenswert?

>L1 ist niemals gleich L2, denn sind andere Bits:

>PIND4 = 0b00010000
>PIND5 = 0b00100000

Ok, das wusste ich nicht. Scheint mir ein wenig unlogisch, dass man den 
Zustand eines einzelnen Bits nicht direkt abfragen kann, aber an das 
muss ich mich beim WinAVR gewöhnen ;-)

Der Code hatte zwar eine Klammer zu wenig aber das prinzipiell 
funktioniert es perfekt, danke!

1
#define BIT_VALUE( PORT, BIT )   ( ( (PORT) & (1<<(BIT))) != 0 )
2
#define L1_VALUE   BIT_VALUE( PIND, PIND4 )
3
#define L2_VALUE   BIT_VALUE( PIND, PIND5 )

von Karl H. (kbuchegg)


Lesenswert?

Mathiable schrieb:
>>L1 ist niemals gleich L2, denn sind andere Bits:
>
>>PIND4 = 0b00010000
>>PIND5 = 0b00100000
>
> Ok, das wusste ich nicht. Scheint mir ein wenig unlogisch, dass man den
> Zustand eines einzelnen Bits nicht direkt abfragen kann, aber an das
> muss ich mich beim WinAVR gewöhnen ;-)

Wie wäre es, wenn du erst mal C lernst, ehe du den Compiler eines 
Vergehens beschuldigst welches nicht existent ist?

von Mathiable (Gast)


Lesenswert?

Ich habe 3 Jahre ua. C in einer Schule gelernt danach 2 Jahre Beruflich 
mit 5 verschiedenen Compiler gearbeitet bei denen die Syntax alle 
ungefähr die selben waren, nur bei dem GCC sind die Syntax für die I/O 
komplett anders und ziemlich unlogisch. Wieso kann man die I/O nicht 
direkt ansteuern und verwerten, sondern muss so einen riesigen Umweg 
machen um einfach 2 I/O miteinander zu vergleichen? Wenn es nicht vom 
Compiler kommt woher dann?

Und wieso kann man eigentlich nie in einem Forum eine Frage stellen ohne 
sofort als totaler Vollidiot dargestellt zu werden? Diese Erfahrung 
kommt nicht nur von mir!

von Karl H. (kbuchegg)


Lesenswert?

Mathiable schrieb:
> Ich habe 3 Jahre ua. C in einer Schule gelernt danach 2 Jahre Beruflich
> mit 5 verschiedenen Compiler gearbeitet bei denen die Syntax alle
> ungefähr die selben waren, nur bei dem GCC sind die Syntax für die I/O
> komplett anders und ziemlich unlogisch.

Der springende Punkt ist:
Das was du als unlogisch bezeichnest ist in Wirklichkeit Standard-C. 
Genau so und nicht anders frisst das jeder C Compiler auf dieser Welt. 
Das ist standardisiertes C, so wie es die normierte Sprache C vorsieht.

> Wieso kann man die I/O nicht
> direkt ansteuern und verwerten, sondern muss so einen riesigen Umweg
> machen um einfach 2 I/O miteinander zu vergleichen? Wenn es nicht vom
> Compiler kommt woher dann?

Woher das kommt?
Davon, dass du nicht zwischen Standard-C und irgendwelchen 
compilerspezifischen Dingen unterscheiden kannst.

Und wer nicht versteht, dass

   if( ( a & 0x01 )  ==  ( b & 0x02 ) )

nur dann true ergibt, wenn sowohl Bit 0 in a als auch Bit 1 in b beide 0 
sind und in keinem anderen Fall sonst, der kann nicht wirklich C, so wie 
es bei µC Anwendungen notwendig ist. Zugegeben: Das liegt auch daran, 
dass man diese Bitoperationen auf Dektopebene eher selten braucht. Aber 
auch dort werden solche Bitoperationen manchmal benutzt wenn diverse 
Statusflags als Bits kodiert sind um Speicher zu sparen.

Es tut mir leid. Aber an dieser Stelle ist dein C einfach mangelhaft. 
Egal wieviele Jahre du schon programmierst.

> Und wieso kann man eigentlich nie in einem Forum eine Frage stellen ohne
> sofort als totaler Vollidiot dargestellt zu werden? Diese Erfahrung
> kommt nicht nur von mir!

Ich stell dich nicht als kompletten Vollidioten hin. Nur wenn jemand den 
Compiler eines Vergehens beschuldigt, sollte er besser wissen wovon er 
spricht. Sonst machte er sich nämlich selber zum Kapserl. Da braucht es 
keinen anderen dazu.

Und um es klar auszudrücken. An dieser Stelle ist nicht der Compiler 
schuld. Er hat genau das umngesetzt was du programmiert hast. Wenn du 
etwas anderes wolltest, ist nicht der Compiler schuld, wenn es nicht so 
funktioniert wie du das willst.

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
Noch kein Account? Hier anmelden.