Moin, Ich bin noch ein absoluter Anfänger mit Mikrocontrollern und möchte zwei Schalter mit dem Atmega16 verwenden. Dabei habe ich die Schalter an die Pins PB0 und PB1 angeschlossen. Die Schalter verbinden die Pins mit der Masse und die Pins sind über einen Widerstand (10 kOhm) mit der Spannung verbunden. DDRB &= ~(1 << DDB0) | ~(1 << DDB1); /* Pin B0 und B1 als Eingang */ unsigned int Taster1(void){ //Taster1 ist B0 unsigned char temp1, temp2; unsigned int i; unsigned int ret; temp1 = !(PINB); // read input for(i=0;i<65535;i++); temp2 = !(PINB); // read input temp1 = (temp1 & temp2); // debounce input if ( temp1 & (1 << PINB0) ){ ret=1; }else{ ret=0; } return ret; } main(){ ... taster1 = Taster1(); taster2 = Taster2(); if ((taster1 == 1) || (taster2 == 1)){ lcd_clrscr(); lcd_puts("Taster gedrückt:\n"); lcd_puts("Sehr gut!!"); } } Dieser Code funktioniert für keinen Taster, was ist daran verkehrt? Vielen Dank Matthias
> DDRB &= ~(1 << DDB0) | ~(1 << DDB1); /* Pin B0 und B1 als Eingang > */ Überprüfe mal deine Logik. ~(1 << DDB0) | ~(1 << DDB1) = 0xff Also wird der gesamte Port B auf Ausgang umgeschaltet. > for(i=0;i<65535;i++); Soll das eine Warteschleife sein? Dann lieber eine entsprechende Bibliotheksfunktion nutzen. Andernfalls wird der Compiler bei eingeschalteten Optimierungen diese Schleife komplett entfernen. }
Moin, nochma. @Rolf > DDRB &= ~(1 << DDB0) | ~(1 << DDB1); /* Pin B0 und B1 als Eingang > */ Überprüfe mal deine Logik. Ich habe meine Logik überprüft und es etwas verändert, nach dem avr-gcc Skript. DDRB &= ~((1 << PB0)|(1 << PB1)); //Eingänge -> 9.5 im Skript PORTB &= ~((1 << PB0)|(1 << PB1));//da Pull-Up Widerstände(10kOhm) Das Entprellen mache ich nun mit _delay_ms(100); es funktioniert allerdings immer noch nicht. Für weitere Hilfen bin ich immer noch dankbar. Matthias
_delay_ms(100) ist mglw. "zu viel", es gibt einige Randbedingungen fuer die maximale Wartezeit in Abhaengigkeit vom Takt, vgl. dazu avr-libc Dokumtentation. Testweise mehrere _delay_ms(x) mit x<max. Delay hintereinander.
Allerdings braucht man auch keine 100 ms zum Entprellen. 10 oder 20 ms sollten dafür genügen. Normalerweise pollt man einfach die Schalter im Timer-Interrupt, und betrachtet sie als gesetzt, wenn sie für N ms ihren Wert nicht mehr geändert haben. Ich glaube, Peter Dannegger hat da irgendwo ein Stück Code, was das macht. Die ganzen Operationen auf DDRB und PORTB sind übrigens NOPs, da sie den Reset-Wert von 0 nicht ändern (alle Ports sind nach dem Reset auf Eingang ohne Pullup geschaltet). Ansonsten Matze: bitte definiere ,,geht nicht'' etwas näher.
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.