Mal wieder eine unbeliebte Anfängerfrage.... Ich benutze ein STK500. Unten sind Auszüge eines Programms. Zum einen die Init und zum anderen dass eigentliche Programm. Die LED0 am PORTB soll bei tastendruck leuchten, bei wiederloslassen soll sie wieder ausgehen. Mein Problem liegt bei der "if" Anweisung. Es wird ja PIND mit (1<<PD0) "verundet". D.h, der taster PD0 wird maskiert. Ich verstehe nun nicht, auf was die "if" anweisung "abfragt". Seither kenne ich nur if Anweisung, wie z.B. if(a = 1) { } hier wird ja klar abgefragt, ob a = 1 ist. Aber auf was fragt die if Anweisung in meim Programm ab? Ich glaub, meine frage ist nicht leicht zu verstehen, aber vllt kann mir ja jemand helfen. Danke! DDRA = 0xFF; DDRB = 0xFF; DDRC = 0xFF; DDRD = 0xFE; PORTA = 0xFF; PORTB = 0xFF; PORTC = 0xFF; PORTD = 0xFF; while(1) { if(!(PIND & (1<<PD0))) { PORTB = ~1; } else { PORTB = 0xFF; } } return(0);
Jens1993 schrieb: > if(a = 1) > { > } > > hier wird ja klar abgefragt, ob a = 1 ist. Nein. Klassischer Programmierfehler. Rest: Bitmanipulation
> if(!(PIND & (1<<PD0))) ist identisch if( (PIND & (1<<PD0)) == 0 ) PIND ist ein 8-bittiges SFR special function register bei AVR µCs. & (1<<PD0) bildet eine Bitmaske für das PD0.te Bit. Die Bedingung testet also ob das PD0.te Bit in PIND nicht gesetzt ist.
Jens1993 schrieb:
> Aber auf was fragt die if Anweisung in meim Programm ab?
In C ist 0 false und alles andere true, also sind
1 | if (FOO) |
2 | if (FOO != 0) |
äquivalent.
PD0 ist auf 0 definiert (#define) x sei 0 oder 1 Wenn PIND gleich xxxxxxx0 binär dann ist das Ergebnis der Berechnung 00000000 binär bzw. 0 dezimal und die if-Bedingung wahr wenn PIND gleich xxxxxxx1 binär dann ist das Ergebnis der Berechnung 00000001 binär bzw. 1 dezimal und die if-Bedingung falsch
ok danke erstmal! dann versuch ich das mal als Bitmuster darzustellen if( (PIND & (1<<PD0)) == 0 ) wenn PD0 gedrückt ergibt sich folgendes Muster PIND = 11111110 & (1<<PD0) = 00000001 ergebnis = 00000000 wenn also ergebnis == 0 dann PORTB = ~1 so müsste es doch dann aussehen?!?
Ich würde mir außerdem diverse Aktionen zum entprellen der Tasten überlegen. http://www.mikrocontroller.net/articles/Entprellung Ein kleiner Tipp am Rande: Ich verwende Bitoperationen wie (PIND & (1<<PD0)) nur beim Initialisieren des Prozessors um eine bessere Übersichtlichkeit zu haben. Im Programm selbst verwende ich Deffinitionen der Bitmuster. Denn wenn einmal nicht optimiert werden sollte, gehen bei jedem Durchgang ein Takt für's shiften und einer für's verunden drauf. Dass steht zum Beispiel in meinen Deffinitionsheader: Generelle Deffiniton der Bitmuster:
1 | //StdDefEx.h
|
2 | #ifndef stddefex_h
|
3 | #define stddefex_h
|
4 | |
5 | #define Bit0 0x01
|
6 | #define Bit1 0x02
|
7 | #define Bit2 0x04
|
8 | #define Bit3 0x08
|
9 | #define Bit4 0x10
|
10 | #define Bit5 0x20
|
11 | #define Bit6 0x40
|
12 | #define Bit7 0x80
|
13 | |
14 | #define Clear_Bit0 0xFE
|
15 | #define Clear_Bit1 0xFD
|
16 | #define Clear_Bit2 0xFB
|
17 | #define Clear_Bit3 0xF7
|
18 | #define Clear_Bit4 0xEF
|
19 | #define Clear_Bit5 0xDF
|
20 | #define Clear_Bit6 0xBF
|
21 | #define Clear_Bit7 0x7F
|
22 | |
23 | #ifndef NULL
|
24 | #define NULL 0x00
|
25 | #endif
|
26 | |
27 | #ifndef TRUE
|
28 | #define TRUE 0x01
|
29 | #endif
|
30 | |
31 | #ifndef FALSE
|
32 | #define FALSE 0x00
|
33 | #endif
|
34 | |
35 | typedef union { |
36 | unsigned short us; |
37 | struct
|
38 | {
|
39 | unsigned char uch_l; |
40 | unsigned char uch_h; |
41 | };
|
42 | } split_short; |
43 | #endif /*stddefex_h*/ |
Und zum Beispiel dass im Projektheader;
1 | //Main.h
|
2 | #ifndef main_h
|
3 | #define main_h
|
4 | |
5 | //////////////////////
|
6 | // Port Deffinition //
|
7 | ////////////////////////
|
8 | |
9 | #define DEF_PORT_LED PORTA
|
10 | |
11 | #define DEF_PIN_LED Bit0
|
12 | #define DEF_PIN_LED_CLEAR Clear_Bit0
|
13 | |
14 | ////////////////////////////////////
|
15 | // Deffinition für LED-Steuerung //
|
16 | /////////////////////////////////////
|
17 | |
18 | #define LEDan (DEF_PORT_LED &= DEF_PIN_LED_CLEAR) // LED an -> invertierte logik
|
19 | #define LEDaus (DEF_PORT_LED |= DEF_PIN_LED) // LED aus -> invertierte logik
|
20 | #define IsLEDaus ((DEF_PORT_LED & DEF_PIN_LED)==DEF_PIN_LED) //Überprüfen ob die LED aus ist -> if(IsLEDaus)
|
21 | #define IsLEDan ((DEF_PORT_LED & DEF_PIN_LED)==0) //Überprüfen ob die LED an ist -> if(IsLEDan)
|
22 | #endif /*main_h*/ |
Damit kann ich im Projekt über LEDan; und LEDaus; die LED an und aus schalten, ohne mich groß um Bitmanipulationen sorgen machen zu müssen. Außerdem hat man den Vorteil, dass wenn sich etwas an der Hardware ändert, die Änderungen_ nur _ein mal_ an _einer Stelle durchgeführt werden müssen. Man muß also nicht gleich den gesammten Quellcode durchsuchen war zu Fehler führen kann. Dass gleiche Prinzip kannst du auch bei der Auswertung der Tasten anwenden.
Exaktemente. [Goldwaageauspackmodus an] > wenn PD0 gedrückt ergibt sich folgendes Muster > PIND = 11111110 NUR, wenn es ein active-low angeschlossener Taster ist. Was das ist, steht im AVR-GCC-Tutorial Gleich merken: Fragen zu Sourcecode sind im µC-Bereich meist von der Schaltung abhängig. Deshalb lieber Schaltplan einmal zu oft an die Frage anhängen als einmal zu wenig... [Goldwaageauspackmodus aus]
@ Jens1993 Fast richtig. ~1 ist quasi ein "Wechselschalter" Wenn Bit0 gerade 0 ist, wird es 1, wenn es gerade 1 ist, wird es 0. Wenn du gezielt, unabhängig vom aktuellen Zustand schalten willst, verwende: PORTB |= 0x01; und PORTB &= 0xFE;
Ich habe vergessen zu schreiben dass der angefügte Code nur aus Codeausschnitten besteht. Im eigentlichen Projekt sind ein paar Includes und Deffinitonen mehr drinnen ;)
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.