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?
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
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 | }
|
>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 )
|
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?
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!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.