Hallo zusammen, für mich ist die AVR programmierung Neuland und wollte von euch wissen ob es möglich ist für Ein/Ausgangsbits Variablen zu vergeben? z.B.: statt: if (PIND & (1<<PIND2)) { PORTB = 0x01; } so: if(Taster == 1) { LED =1; } weil so wäre der Code verständlicher
Hi Ja das geht, falls ich dich richtig verstehe...
1 | #define Taster (PIND & (1<<PIND2))
|
Für die LED geht das dann genauso.
Hallo und danke, ja stimmt schon. Nur hab ich hier das Problem das der Taster hier als high abgespeichert wird. ich will eigentlich nir für das 3.Bit am PORTD eine Variable definieren.
Daniel P. wrote: > if (PIND & (1<<PIND2)) > { > PORTB = 0x01; > } > > so: > > if(Taster == 1) > { > LED =1; > } Nein. Geht so nicht, weil (PIND & (1<<PIND2)) nie gleich 1 ist! Es ist allerhöchstens gleich "1 << PIND2", also "1 << 2" oder 4. Wenn Du allerdings das "==1" weglässt, dann wird (PIND & (1<<PIND2)) als Wahrheitswert ausgewertet, und dann klappt es. Also einfach den Vergleich weglassen.
Daniel P. wrote: > Nur hab ich hier das Problem das der Taster hier als high abgespeichert > wird. Vestehe nicht ganz, was Du damit sagen möchtest.
Also das ist so gemeint das ich eigentlich nur immer den Zustand des 3. Bit am PORTD abfragen will das wäre eigentlich nur 1 bzw. 0. Dies funktioniert nicht weil es in der Realität 0 bzw. 4 ist. Also sieht das ganze momentan so aus: #define Taster (PIND &(1<<PD2)) int main(void) { DDRD = 0x00; PORTD = 0xff; DDRB = 0xff; PORTB = 0x00; while (1) { if (Taster == 4) { PORTB = 0x00; } else { PORTB = 0x01; } } } für mich sehe aber das ganze schöner aus wenn ich den Taster mit if (Taster == 1) abfragen könnte.
Es gibt verschiedene Möglichkeiten, den Code transparenter zu machen: Die einfachste besteht darin, für den Port und das Portbit aussagekräftigere Namen zu vergeben:
1 | #define TASTERPORT PIND
|
2 | #define TASTERBIT PIND2
|
3 | |
4 | if (TASTERPORT & (1<<TASTERBIT)) |
5 | // ...
|
Man kann auch Makros definieren, über die auf die Portbits wie auf Variablen zugeriffen werden kann, dazu muss man aber etwas weiter ausholen:
1 | // Allgemeine Definitionen:
|
2 | |
3 | struct bits { |
4 | uint8_t b0:1; |
5 | uint8_t b1:1; |
6 | uint8_t b2:1; |
7 | uint8_t b3:1; |
8 | uint8_t b4:1; |
9 | uint8_t b5:1; |
10 | uint8_t b6:1; |
11 | uint8_t b7:1; |
12 | };
|
13 | |
14 | #define BIT(r,n) (((volatile struct bits *)&r)->b##n)
|
15 | |
16 | |
17 | // Konkrete Definitionen der einzelnen Portbits:
|
18 | |
19 | #define TASTER BIT(PIND, 2)
|
20 | #define LED BIT(PORTD, 0)
|
21 | |
22 | |
23 | // Verwendung der Makros:
|
24 | |
25 | // ...
|
26 | if(TASTER) // oder auch: if(TASTER == 1) |
27 | LED = 1; |
Obwohl das etwas komplizierter aussieht, erzeugt auch hier der GCC optimalen Code, nämliche exakt zwei Befehle (einen für die Abfrage und einen für die Zuweisung). Das Ganze wurde schon einmal hier behandelt: Beitrag "sbit macro für avr-gcc" Was die Lesbarkeit des Codes betrifft: Geübte Mikrocontrollerprogrammie- rer haben sich schon so sehr an die Notation mit den Bitoperatoren (&, |, ~ und <<) gewöhnt, dass auch die erste Variante sofort verstanden wird.
Hallo, Abfagen auf (Taster=1) erledigt man in C besser mit (Taster!=0) In dieser Version ist es wurst, welches bit tatsächlich benutzt wird. Gruss, Michael
Danke für die prompten Antworten. am einfachsten ist wohl die Variante if(Taster != 0) abzufragen. werde aber die anderen auch noch testen. also Danke nochmal an alle
Michael Appelt wrote:
> Abfagen auf (Taster=1) erledigt man in C besser mit (Taster!=0)
1 | if(Taster != 0) |
macht exakt dasselbe wie
1 | if(Taster) |
Und das hatte ich oben schon mal angesprochen. Wozu also der zusätzliche Schreibaufwand?
wenn du umbedingt ==1 willst dann mach: #define Taster ((PIND &(1<<PD2)) >>PD2) ;)
max wrote: > wenn du umbedingt ==1 willst dann mach: > > #define Taster ((PIND &(1<<PD2)) >>PD2) > > ;) Auaaaa... Komplizierter geht's fast net.
1 | #define Taster ((PIND >> PD2) & 1)
|
Wenn Du natürlich gerne irgendwelche Sachen hin- und herschiebst, möchte ich Dich nicht daran hindern;-)
Ich rate dir, diese Idee nicht weiter zu verfolgen. Auch wenn es zunächst ein wenig umständlich aussieht, wie in C die Pins gesetzt werden, so geht es nunmal. Daran gewöhnt man sich und dann ist es auch gar kein Problem mehr. Man kann jetzt krampfhaft versuchen einen anderen Weg zu finden, anstatt es einfach zu akzeptieren, aber das is verschwendete Zeit ;)
@Johannes M.: Auch wenn's kommisch klingt: Die doppelte Schieberei von Max wird vom Compiler komplett eliminiert und durch einen einfachen SBIS-Befehl ersetzt, während bei deiner Variante der Shift zur Laufzeit ausgeführt wird, was sind je nach Bitnummer bis zu vier Befehle zusätzlich bedeutet.
yalu wrote: > @Johannes M.: > Auch wenn's kommisch klingt: Die doppelte Schieberei von Max wird vom > Compiler komplett eliminiert und durch einen einfachen SBIS-Befehl > ersetzt, während bei deiner Variante der Shift zur Laufzeit ausgeführt > wird, was sind je nach Bitnummer bis zu vier Befehle zusätzlich > bedeutet. Hmmm, klingt komisch, is aber so... Hast natürlich Recht! Bei meiner Variante sind dem Optimizer die Hände gebunden. Aber abgesehen davon würde ich immer noch einfach den (überflüssigen) Vergleich weglassen. Dann kann man sich das zurückschieben schlicht schenken.
Klaus wrote: > Man kann jetzt krampfhaft versuchen einen anderen Weg zu finden, anstatt > es einfach zu akzeptieren, aber das is verschwendete Zeit ;) Das ist doch kein Krampf, das ist astreines ANSI-C. Ich finde auch, seitdem ich es verwende, hat sich die Lesbarkeit deutlich verbessert. Und Schreibaufwand spart es obendrein. Hier noch ein Beispiel mit Bitvariablen nach Yalu: http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip Peter
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.