Tiny13: Hochzählen von Tastenbetätigungen

Gast #3133013
Lesenswert?

Hallo µC-Gemeinde,

ich möchte mit einem Tiny13 die Tastenbetätigungen hochzählen und beim 
erreichen eines Wertes X einen Ausgang schalten...
Bzgl. µC und Programmierung bin ich Neuling, dass schonmal vorab.

Mein Problem ist nun, dass das Hochzählen der x nicht funktioniert. 
Sollte durch Leuchten der led2 angezeigt werden (hier bei x=2 led2 an).
Was mache ich falls?

Der aktuelle Quellcode:
###############################################################
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1200000UL  // 1,2 MHz
#define WARTEPIN PINB
#define WARTEBIT PB0
//uint8_t x = 0;y;
int x;

int main(void)
{
  DDRB &= ~_BV(PB0);       // PB0 als Eingang
  PORTB |= _BV(PB0);       // Pull Up an der Stelle PB0 setzen
  DDRB = (1<<DDB1)|(1<<DDB3)|(1<<DDB4);  //PB1,PB3,PB4 als Ausgang
  x=0;
while (1)
{
  while (!(WARTEPIN & (1<<WARTEBIT)))
  {
    PORTB &=~((1<<PB3));    //led1 an
    x=x+1;
    PORTB|=(1<<PB1);          //led3 aus
  }
  if (x==2) PORTB &=~((1<<PB4));    //led2 an
  while (WARTEPIN & (1<<WARTEBIT))
  {
    PORTB |=(1<<PB4);    //led2 aus
          PORTB|=(1<<PB3);    //led1 aus
    _delay_ms(150);           //led3 blinken
    PORTB|=(1<<PB1);
    _delay_ms(150);
    PORTB&=~((1<<PB1));
  }
}
return 0;
}
###################################################################
Schaltplan:
--o------------o------------------o-----------o----+5Vdc
  |            |                  |           |
  |            |                  |           |
  |           | | 10k             |           |
  |           |_|       tiny13    |           |
  |            |    ____        |           |
  |   __  led1 '---|1    8|-------'           |
  |- |__|--->|-----|2    7|--    led 3   __   |
  '--|__|--->|-----|3    6|--------|<---|__|--'
          led2  .--|4____5|-----.
                |               |
                |             | o                led's mit 220 Ohm
                |           |=|   Taster         Vorwiderstand
                |             | o
                |               |
                |               |
----------------o---------------o-----------------GND
##################################################################

Vielen Dank im Voraus

MfG tiny 13
Gast #3133066
Lesenswert?

Auch mit einem entprellten Taster würde das nicht funktionieren. Du 
zählst nicht, wie oft ein Taster herunter gedrückt wird, sondern Du 
zählst immer hoch, solange der Taster gedrückt ist, unabhängigg davon, 
ob er zwischenzeitlich wieder losgelassen wurde. Du darfst nur neue, 
entprellte Tastendrücke zählen.
Gast #3133083
Lesenswert?

Wenn eine Taste prellt, und man hat eine Zeitschleife dahinter, dann laß 
sie prellen.

Die 150ms Delay könnten etwas knapp sein, daß ein Mensch darauf mit 
Taste drücken und los lassen reagiert. Einfach mal testweise verlängern.

Ich würde das Programm auch zum Test mal drastisch vereinfachen. Das ist 
ja ein Wirrwarr von 3 LEDs, wobei ich AVR nicht kenne.
Gast #3133158
Lesenswert?

Die while-Schleife, in der x hochgezählt wird, hat kein delay. Die 
Zeitschleife greift hier erst, wenn der Taster wieder losgelassen wurde. 
Die Variable x hat dann einen nahezu zufälligen Wert. Die LED2 ist nur 
für wenige Takte an, sodass man das gar nicht sehen kann.
(Firma: guloshop.de) #3133187
Lesenswert?

Hier würde sich eine ISR mit dem INT0 anbieten: Wenn der Taster gedrückt 
wird, springt der Mikrocontroller in die ISR.

Innerhalb der ISR kommt zuerst das Hochzählen und ggf. Einschalten von 
LEDs.

Danach eine Warteschleife wegen der Entprellung, z.B. 100ms.

Als Letztes löscht man in der ISR etwaige Interruptanforderungen, die 
seit dem Start der ISR entstanden sind - zum Zweck der Entprellung.

Das Hauptprogramm besteht aus der Initialisierung, gefolgt von einer 
leeren Endlosschleife.

Denke, das wäre die kompakteste Lösung, also das kürzeste Programm...
Gast #3133197
Lesenswert?

Markus Weber schrieb:
> Denke, das wäre die kompakteste Lösung, also das kürzeste Programm...

aber leider auch sehr unschön und später nicht mehr erweiterbar.

Es wird ja immer wieder (zu Recht) gesagt:
  - keine Tastenauswertung in der ISR
  - keine Wartezeiten in der ISR

und genau das willst du hier machen?
(Firma: guloshop.de) #3133204
Lesenswert?

Peter II schrieb:
> Es wird ja immer wieder (zu Recht) gesagt:
>   - keine Tastenauswertung in der ISR
>   - keine Wartezeiten in der ISR
>
> und genau das willst du hier machen?

Richtig. :-) Weil ich keinen Sinn in solch pauschalen Aussagen sehe.

In manchen Fällen sind Tastenauswertungen in einer ISR ungünstig. Und in 
vielen Fällen ist es sehr ungünstig, eine Warteschleife in eine ISR zu 
setzen. Aber eben nicht in allen Fällen. In genau dem vorliegenden Fall 
ist diese Art des Programms die einfachste Lösung, warum sollte man es 
nicht so machen?
Gast #3133206
Lesenswert?

Markus Weber schrieb:
> Richtig. :-) Weil ich keinen Sinn in solch pauschalen Aussagen sehe.
>
> In manchen Fällen sind Tastenauswertungen in einer ISR ungünstig. Und in
> vielen Fällen ist es sehr ungünstig, eine Warteschleife in eine ISR zu
> setzen. Aber eben nicht in allen Fällen. In genau dem vorliegenden Fall
> ist diese Art des Programms die einfachste Lösung, warum sollte man es
> nicht so machen?

Er verbreitet weiter seine satanischen Verse.
DAS FEUER WIRD SEINE SEELE REINIGEN!
Gast #3133207
Lesenswert?

Übrigens kann man eine Taste in einer Direkt-Entprellung auch sofort am 
Ort auswerten. Das dauert dann keine Millisekunde, und erst recht keinen 
nach folgenden Timer.

Ich habe zugegebenermaßen für den heutigen Geschmack schlecht designte 
Main-Programme aus meiner Anfangszeit vor 15 Jahren, wo ich das so 
machte, aber das Assembler programmierte Main-Programm auch 
Durchlaufzeiten von nur 6ms hatte.

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