Hallo zusammen, als totaler AVR Anfänger habe ich folgendes Problem mit der switch-case Anweisung. Dieses kleine Programm habe ich nur zu Testzwecke geschrieben. Das funktioniert auch im WINAVR-Simulator einwandfrei, jedoch nicht mit meiner AVR-STK500 Hardware. Was habe ich nicht berücksichtigt? //---------------------------------------------------------------------- --- // Titel : Test1 //---------------------------------------------------------------------- --- // Funktion : Test // Schaltung : div. Versuch //---------------------------------------------------------------------- --- // Prozessor : ATmega8 // Takt : 3686400 Hz // Sprache : C // Datum : // Version : // Autor : ws // Programmer/Board: AVRISP MK2 / STK500 // Port : B = Eingabe; D = Ausgabe //---------------------------------------------------------------------- --- // #define F_CPU 3686400 #include <avr\io.h> #include <avr/wdt.h> #include <util/delay.h> //---------------------------------------------------------------------- -- // Initialisierungen //---------------------------------------------------------------------- -- void init() { // Ports initialisieren DDRD = 0b11111111; // PORTD0 auf Ausgang DDRB = 0b00000000; // PORTB auf Eingang PORTB = 0xff; //PORTB PullUp aktivieren } //---------------------------------------------------------------------- -- // Main-Funktion //---------------------------------------------------------------------- -- int main(void) { unsigned char x=0; init(); // Initialisierungen while (1) // Mainloop-Begin { x=PINB&0x1f; switch (x){ case 1: {PORTD = 0b11111101;} break; case 2: {PORTD = 0b11110110;} break; case 4: {PORTD = 0b10101010;} break; default: PORTD = 0b01010101; } } // Mainloop-Ende } //---------------------------------------------------------------------- -----
Sebastian Würzer schrieb: > Was habe ich nicht berücksichtigt? Du schaltest den Port auf Eingang und aktivierst auf allen Pins die Pullup Widerstände. Damit wird dir jeder Pin, an dem nichts angeshlossen ist, ein 1-Bit liefern. > x=PINB&0x1f; > switch (x){ > case 1: {PORTD = 0b11111101;} break; > > case 2: {PORTD = 0b11110110;} break; > > case 4: {PORTD = 0b10101010;} break; > default: PORTD = 0b01010101; > } > } // Mainloop-Ende Wenn du nicht explizit Hardware angeschlossen hast, die dir die restlichen Pins auf 0 ziehen, dann wirst du hier nicht 1, 2 oder 4 erhalten. Wenn du einzelne Pins abfragen willst, dann ist die beste Strategie das Eingelesene für jede Abfrage einzeln so zu maskieren, dass nur das interessierende Bit übrig bleibt.
1 | x = PINB; |
2 | |
3 | if( x & 0x01 ) |
4 | PORTD = 0b11111101; |
5 | |
6 | else if( x & 0x02 ) |
7 | PORTD = 0b11110110; |
8 | |
9 | else if( x & 0x04 ) |
10 | PORTD = 0b10101010; |
11 | |
12 | else
|
13 | PORTD = 0b01010101; |
Du kannst natürlich auch einen switch-case benutzen. Nur solltest du dann aber sicherheitshalber von x auch wirklich nur die Bits zum Vergleich benutzen, für die du case-Fälle hast bzw. diejenigen, bei denen auch tatsächlich etwas extern angeschlossen ist.
1 | x=PINB&0x1f; |
2 | switch (x & 0x07) { |
3 | case 1: PORTD = 0b11111101; break; |
4 | case 2: PORTD = 0b11110110; break; |
5 | case 4: PORTD = 0b10101010; break; |
6 | default: PORTD = 0b01010101; |
7 | }
|
hallo Herr Buchegger, vielen Dank für diesen Hinweis. Das war kein Anfängerfehler wie ich glaubte, sondern ein absoluter Aussetzer meinerseits. Habe den Eingang darauf hin entsprechend maskiert und schon funktioniert es. Danke. Sebastian
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.