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
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.
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.
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.
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...
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?
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?
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!
Ü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.