Schalter für den Atmega16

OP #238672
Lesenswert?

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
Gast #238673
Lesenswert?

> 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.
}
OP #238674
Lesenswert?

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
Gast #238675
Lesenswert?

_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.
Moderator Persönliche Seite #238676
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren