mikrocontroller.net

Forum: Compiler & IDEs Eingänge vergleichen


Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
#define BIT_VALUE( PORT, BIT )   ( ( (PORT) & (1<<(BIT)) != 0 )
#define L1_VALUE   BIT_VALUE( PIND, PIND4 )
#define L2_VALUE   BIT_VALUE( PIND, PIND5 )

...

      for(ms=0; L1_VALUE == L2_VALUE; ms++ )

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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 => (&&)
    #define L1 (PIND&(1<<PIND5))
    #define L2 (PIND&(1<<PIND4))

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

       long_delay(1);
   }

Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Mathiable (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.