Hallo,
ich möchte während ich den taster an PA0 drücke die variable a immer um
+1 hochzählen. wenn ich ihn erneut drücke soll die Variable a wieder um
+1 hoch gezählt werden. also drücken a=1 ,erneut drücken a=2, erneut
drücken a=3 usw...
aber was habe ich hier nicht beachtet es scheint so als würde er mir
nicht richtig hochzählen (willkürlich). Taster mit kondensator
entprellt.
grüsse huber
Servus Hubert,
Du darfst die Variable nicht hochzählen, solange der Taster sich im
gedrückten Zustand befindet, sondern nur, wenn er vom nicht-gedrückten
in den gedrückten übergeht!
Huber M. schrieb:> Taster mit kondensator entprellt.
Taster mit Software entprellen. (s. Artikel Entprellung)
Für nicht genutzten Flash-Speicher gibt es kein Geld zurück.
Wolfgang schrieb:> Taster mit Software entprellen. (s. Artikel Entprellung)>> Für nicht genutzten Flash-Speicher gibt es kein Geld zurück.
Software Entprellung benötigt auch Ram.
Oder es wird Zeit in delays verplempert.
bin ich hier auf dem richtigen weg?
denn es macht nicht was es soll.
-ich drücke, lasse los, dann zählt er um eins hoch, also a = 1 ? noch
keine Funktion?
-ich drücke erneut. lasse los,zählt wieder um eins hoch, also a = 2?
jetzt müsste er mir doch PA1 Einschlten?
Arduino F. schrieb:> Software Entprellung benötigt auch Ram.> Oder es wird Zeit in delays verplempert.
Die wenigen RAM-Bytes werden wohl noch irgendwo zu finden sein.
Wer sein Timing auf solchen Zeitskalen mit delay() macht, hat allerdings
schnell verloren, wenn sich der µC auch noch um andere Dinge kümmern
soll. Falls die einzige Aufgabe allerdings ist, auf eine Taste
aufzupassen, ist es egal, womit er die Zeit verplempert. Irgendwie muss
er sie rum kriegen ;-)
Du musst dir den alten Tastenzustand merken. Hier ein Beispiel. Mal
schnell nebenbei und ungetestet. Allerdings solltest du das Konzept
überdenken. So macht man das nicht.
Als ganz einfachen Test könntest du in dem If- Block der Tasterabfrage
gegen das Prellen _delay_ms() einsetzen.
Tasterabfrage Taster gedrückt, kurz warten.
Schleife,
Tasterabfrage Taster nicht gedrückt, kurz warten.
Um die Ergebnisse zu überprüfen würde ich an deiner Stelle mit einer Led
einen Blinkcode ausgeben, damit ist die ganze Geschichte deutlich besser
überschaubar.
Arduino F. schrieb:> Software Entprellung benötigt auch Ram.
Das stimmt. Ein ganzes sattes Byte für bis zu acht Tasten. Wer zum
Teufel kann sich solcherart Verschwendung heutzutage denn noch leisten?
Huber M. schrieb:> bin ich hier auf dem richtigen weg?> denn es macht nicht was es soll.
Geh mal ganz systematisch und ohne Programmiersprache an das Problem
heran. Stell dir dazu einen Beamten vor, der in seinem Amt alle Arbeiten
machen muß. (jaja im Gedankenexperiment gibt es sowas...)
Dieser Beamte kommt in das Zimmer für die Taste, setzt sich an den
Schreibtisch und guckt auf das Arbeitsbuch auf dem Tisch, wo draufsteht,
was er zuletzt gemacht hat.
Also:
Fall 1: auf dem Zettel steht: kein aktueller Vorgang am Laufen, die
Taste war zuletzt aus.
Jetzt guckt er nach der Taste und stellt fest:
a) die ist immer noch aus. Also steht er auf und geht an seine nächste
Arbeit.
b) die Taste ist jetzt gedrückt. Also schreibt er auf nen Zettel: "Taste
wurde gedrückt, bitte Vorgang bearbeiten" und steckt ihn in die
amtsinterne Post. Anschließend schreibt er in das Arbeitsbuch: "Vorgang
ist am Laufen" und "Entprellzeit = 100 Bewertungen". Danach geht er an
seine nächste Arbeit.
Fall 2: auf dem Zettel steht:"Vorgang ist am Laufen".
Jetzt guckt er nach der Taste und stellt fest:
a) die Taste ist ungedrückt. Jetzt liest er im Arbeitsbuch:
"Entprellzeit = xxx Bewertungen". (xxx steht für eine Zahl) Er radiert
die Zahl aus und schreibt Zahl-1 hinein. Wenn das nun Null ergibt, dann
radiert er den gesamten Vorgang aus und schreibt "kein aktueller Vorgang
am laufen". Danach geht er an seine nächste Arbeit.
b) die Taste ist immer noch gedrückt. Also radiert er die Zahl für die
Entprellzeit aus und schreibt "100" hinein. Danach geht er an seine
nächste Arbeit.
So. Ist dir jetzt klar, wie man an solche Dinge herangehen kann? Die
Story dürfte sich selbst für einen ungeübten Programmierer ohne Probleme
in eine beliebige Programmiersprache übersetzen lassen.
Und nochwas: Eigentlich reicht es dem Beamten ja aus, zu sehen, ob die
Zahl auf dem Arbeitsbuch Null ist oder nicht.
W.S.
also, jetzt habe ich es mal so geschrieben, aber was mir einfach nicht
einleuchtet, warum er mir den druckzaehler nicht um eins höher zählt.
liegt das hier an der while schleife.
mir geht es hauptsächlich jetzt mal darum, das mir das mit dem zählen
endlich mal einleuchtet.
Der Ablauf von Deinem Programm sollte etwa folgender sein:
- Variablen und Hardware vorbereiten und einstellen
- Wiederhole für immer:
- Warte auf "Taste nicht gedrückt"
- Warte auf "Taste gedrückt"
- Zähle um Eins hoch
Wie Du siehst, kommt zweimal "Warte auf irgendwas" vor. So ein Warte
könnte man folgendermaßen programmieren:
- Weil "irgendwas" nicht wahr ist, wiederhole:
- Mache nichts
Verstanden?
dann ist das signal 1 also wahr Boolsche regel. mein problem ist nicht
das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum
hochzählen.
int tasterstatus = 0;
int zähler = 0;
if (tastergedrückt)
setze mir den tasterstatus auf 1
wenn der tasterstatus 1 ist
zähle mir den zähler um eins rauf
Huber M. schrieb:> if (!(PINA &(1<<PA0)))> { _delay_ms(15);
Das kann bestenfalls ein Gamer oder der Sieger im Schnellschreiben.
Ein typischer Nutzer benötigt 300ms zum Drücken und 300ms zum Loslassen.
Die universelle Lösung ist daher ein Timerinterrupt, der das Entprellen
und die Flankenerkennung im Hintergrund erledigt. Die Mainloop liest
dann einfach nur das Drück-Flag und löscht es.
http://www.c-howto.de/tutorial-verzweigungen-if-else.html
Die Variable "druckzaehler" wird nach jedem Durchlauf wider auf 0
gesetzt, kann dementsprechend niemals größer als 1 werden.
Die "else if (druckzaehler == 1)" kann nicht ausgeführt werden solange
"if (tasterstatus ==1)" wahr ist.
Wenn "if (tasterstatus ==1)" unwahr ist wurde "druckzaehler" bereits
wider auf 0 gesetzt.
Huber M. schrieb:> dann ist das signal 1 also wahr Boolsche regel. mein problem ist nicht> das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum> hochzählen.
Du hast Dich verrant und suchst an der falschen Stelle!
Benutze den Debugger und führe damit das Programm Schritt für Schritt
aus! Damit kannst Du es genau verfolgen und wirst sehen, wo das Programm
etwas anderes tut, als Du Dir vorstellst.
Huber M. schrieb:> mein problem ist nicht> das ich grundsätzlich nicht schalten kann, sondern ich bin zu blöd zum> hochzählen.
Ich würde das etwas anders formulieren: Du hast Schwierigkeiten, die
ganze Sache rein logisch zu verstehen und dir eine geeignete Lösung dazu
zu erarbeiten. Und verstehendes Lesen ist dir auch nicht wirklich
genehm.
Vielleicht dazu noch ein Rat: Programmierer sein, heißt nicht, in irgend
einer Programmiersprache etwas syntaktisch richtiges hinschreiben zu
können, sondern es heißt, gute Algorithmen zum Lösen von Problemen
erarbeiten und formulieren zu können.
W.S.
Jobst M. schrieb:> start
Nun ja, geht, aber das ist blockierend konstruiert. Außerdem vertraut es
auf hardwaremäßige Entprellung.
So langsam müßte unser TO endlich in die Puschen kommen.
W.S.
W.S. schrieb:> Nun ja, geht, aber das ist blockierend konstruiert.
Außerdem läuft die gewünschte Aktion erst nach Loslassen ab.
Man möchte aber die Reaktion schon beim Drücken haben.
W.S. schrieb:> Nun ja, geht, aber das ist blockierend konstruiert.
War nicht gefordert, dass es nicht so ist.
Peter D. schrieb:> Man möchte aber die Reaktion schon beim Drücken haben.Huber M. schrieb:> -ich drücke, lasse los, dann zählt er um eins hoch
Gruß
Jobst
W.S. schrieb:> So langsam müßte unser TO endlich in die Puschen kommen.
Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand
zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...
Er lässt sich das wohl lieber erklären / vormachen ...
Dieter F. schrieb:> Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand> zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...
Ich muss mir erst noch eines für C99 bestellen, denn ich habe zwei,
aber aus meiner unwissenheit sind diese für arduino und arduino und C
gewesen, denn ich will nicht mit forgefertigten platinen arbeiten,
sondern ich will mir selbst welche bauen. Deshalb dachte ich mir das der
arduino nicht das richtige für mich ist,Und habe in bei seite gelegt.
Und habe mir attiny24a, atmega8 zugelegt. und einen isp mk2 programmer
original.Und ja das grundprinzip ist das gleiche, aber dann für mich
auch irgendwie doch nicht.
Dieter F. schrieb:> Ihm ist schon in x Threads empfohlen worden, mal ein C-Buch in die Hand> zu nehmen, zu Lesen bzw. das Tutorial durchzuarbeiten ...>> Er lässt sich das wohl lieber erklären / vormachen ...
das stimmt nicht, ich frage nur wenn ich etwas nicht weiss oder
verstehe.
Manfred schrieb:> So zählt er schon beim drücken hoch. ;-)
Super, kam schon jemand anders drauf. Ist aber genau das, was der TO
nicht möchte:
Huber M. schrieb:> -ich drücke, lasse los, dann zählt er um eins hoch
Gruß
Jobst
Huber M. schrieb:
Das stimmt so aber nicht. Das war der erste Satz des TO
> Hallo,>> ich möchte während ich den taster an PA0 drücke die variable a immer um> +1 hochzählen.
Hallo Michael,
würdest Du dein Programm Schritt für Schritt durchgehen und zudem auch
noch zumindest halbwegs verstehen, was Du da geschrieben hast, dann
solltest Du eigentlich auch erkennen, was mit deinem Zähler, also der
Variablen a, innerhalb deiner Endlosschleife passiert und warum es nicht
gut ist, eine Variable, die ja innerhalb dieser Endlosschleife nur
aufgrund eines bestimmten Ereignisses inkrementiert werden soll, auch
gleichzeitig (immer wieder) in dieser Schleife zu initialisieren.
Schau, wo deine Endlosschleife beginnt und wie weit sie geht und
überlege Dir dann einfach mal, was durch den Ausdruck int a = 0;
innerhalb dieser Endlosschleife bewirkt wird.
Apropos, auch das
1
#define led (1<<PC0)
2
#define ein PORTC |=
3
#define aus PORTC &= ~
ist zwar ein ganz netter Ansatz bezüglich besserer Lesbarkeit, aber so
auch noch ziemlich verdreht, zumal es bisher ja auch noch gar keine
Verwendung in deinem Programm findet. Das aber auch nur so am Rande. Auf
dein Zählerproblem hat es keinen Einfluss.
Mit besten Grüßen
Murmelchen
Thomas E. schrieb:> Murmelchen schrieb:>> würdest Du dein Programm Schritt für Schritt durchgehen>> am Besten mit einem Debugger - @Michael: warum benutzt Du den nicht?
so wie bei emmbedded workbench (MSP430) die locals dann ansehen. Das
wäre ein Traum!!!!!. Da komme ich seit Wochen nicht drauf, wie man das
(bei ATMEl Studio 6.2) einstellt, das er mir dann die int Werte im
(local fenster) anzeigt und die berechneten ergebnisse.
das Inkrmentieren ist ja eigentlich so einfach das es schon wieder
kompliziert ist.
ich glaube mein Hauptproblem ist ganz einfach, und zwar verwirrt mich
irgendwie das, wie ich dem Taster an Port D0 (PD0) einer int variable
zuweise die halt dann eben 0 oder 1 ist.
im embedded workbench ist das ganz easy P1IN der Variable taster
zuweisen, schon ist die Variable im gedrückten Zustand bei 1.
1
2
3
inttaster=P1IN;// so funktionierts bei MSP430 embedded workbench
4
intdruckzaehler=0;
5
while(1)
6
{
7
if(taster==0)
8
{
9
druckzaehler++;
10
}
11
12
}
13
return0;
14
15
}
und da ich es mir bei Atmel studio 6.2 im debugger nicht anschauen kann.
sind wohl meine Gedanken komplett aus den ruder gelaufen und dann kamen
solche Code beispiele wie oben raus, weil ich nicht mehr wusste was ich
tun soll.
wie weisst man jetzt eigentlich richtig den PD0 einer int Variable
namens taster zu, das sie dann eben 0 oder 1 ist.
grüsse huber
Huber M. schrieb:> wie weisst man jetzt eigentlich richtig den PD0 einer int Variable> namens taster zu, das sie dann eben 0 oder 1 ist.
Du fragst den betreffenden Port ab (lesen), damit hast du
8 Bit. Aus diesen 8 Bit maskierst du das Bit aus das deinen
Tastenzustand beinhaltet und prüfst ob es 1 oder 0 ist.
Wenn es 1 ist weist du deiner Zustandsvariablen 1 zu, wenn
es Null ist weist du deiner Zustandsvariablen 0 zu. Oder
genau umgekehrt, je nachdem ob dein Taster eine aktive 1
oder eine aktive Null generiert.
Merke: das entsprechende Maskierte Bit der Taste ist nicht
gleich dem Wert der Zustandsvariable deiner Taste.
Huber M. schrieb:> Taster mit kondensator entprellt.
Das funktioniert nur bedingt. Eine vernünftige Entprell-
Schaltung braucht einen Kondensator und zwei Widerstände.
Bei deinem Herumexperimentieren fällst du evtl schon wegen
dem Prellen auf die Schnauze.
> int taster =P1IN; // so funktionierts bei MSP430 embedded workbench
warum funtioniert das dann bei mir nicht mit atmel, ich dachte man macht
das so:
//
PORTD = (1<<PD0); // oder 0b00000001; // oder 0x0x
wenn ich das so mache:
1
inttaster=(1<<PD0);
da ich mir den debugger bei Atmel Studio noch nicht so einstellen kann,
das ich mir die locals ansehen kann, kann ich es auch nicht kontrolieren
ob er 1 oder null macht. Und da ich mir nicht sicher bin ob die
zuweisung in diesem fall so korrekt ist. macht mir das riesige probleme.
W.S. schrieb:> Nun ja, geht, aber das ist blockierend konstruiert.
Wenn der Mikrocontroller nur ganz einfache Dinge tun muss, ist das
völlig ok.
Kompliziertere Dinge wird der TO zur Zeit noch nicht hinkriegen, wenn er
mit so einfacher Programmierlogik schon Probleme hat.
Huber M. schrieb:> da ich mir den debugger bei Atmel Studio noch nicht so einstellen kann,> das ich mir die locals ansehen kann, kann ich es auch nicht kontrolieren> ob er 1 oder null macht.
Eine Tasten-Variable lokal zu deklarieren macht ja auch wenig
Sinn da die Taste ja für die ganze Software gültig sein soll.
Also deklariere sie global. Im übrigen macht es auch wenig Sinn
diese als Integer zu deklarieren. uint8_t reicht aus und macht
die Operationen damit übersichtlicher, durchsichtiger.
Lokale Variablen sind übrigens dann nicht sichtbar wenn sie
durch eine Optimierungsstufe des Compilers weg-optimert werden.
Mahlzeit,
ich verstehe nicht warum das ganze nicht Funktioniert das kann nur am
tasterpin einlesen liegen? Nur mal zum verständnis, wenn ich das ganze
so(nachfolgend) schreibe, macht es ja auch was es soll. oder bin ich da
komplett verkehrt
1
2
3
intanton=1;
4
intberta=0;
5
6
while(1)
7
{
8
if(anton>0)
9
{
10
berta++;
11
}
12
if(berta==5)
13
{
14
berta=0;
15
}
16
}
17
18
undhiermeinAktuellerCode
[]/*
* GccApplication27.c
*
* Created: 20.09.2016 16:33:10
* Author: Huber
*/
#define F_CPU 1000000UL
#include <util/delay.h>
#include <stdbool.h>
#include <avr/io.h>
int main(void)
{
// EIN u. AUSGÄNGE konfigurieren
PORTD = (1<<PD0); // Eingang
DDRC = (1<<PC0);// Ausgang
// eigen funktion erstellen
void blinkled()
{
PORTC|= (1<<PC0);
_delay_ms(300);
PORTC&= ~(1<<PC0);
_delay_ms(300);
}
int taster = PIND0; // Lese an PIND0 ob high or low
int druckzaehler = 0;
while(1)
{
if(taster > 0 )
{
druckzaehler++;
}
if (druckzaehler == 5)
{
PORTC |= (1<<PC0);
}
}
}
[]
Arduinoquäler schrieb:> Lokale Variablen sind übrigens dann nicht sichtbar wenn sie> durch eine Optimierungsstufe des Compilers weg-optimert werden.
den habe ich unter optimize auf none -O0 gestellt
vielleicht 'taster=PIND0;' in die while(1) -Schleife hineinpacken?
Ansonsten muss die Taste beim Starten gedrückt sein.
Schreib doch mal auf was genau passieren soll; das Anton-Berta Ding
sieht auch ganz schön verkehrt aus. (Da kannst Du Anton auch weglassen).
Arduinoquäler schrieb:> Huber M. schrieb:>> int main(void)>> Das sind soviele Macken drin dass man dir wirklich nur> raten kann die Sprache C von Grund auf zu lernen.
das setzt das atmel studio schon als standard automatisch hin.
Huber M. schrieb:> das setzt das atmel studio schon als standard automatisch hin.
Man versteht ja schon deine Ausdrucksweise nicht. Sorry.
Und dass sich meine Aussage auf den ganze geposteten Code
bezieht hast du wohl auch nicht verstanden.
ich wollte eigentlich einfach nur per Tasterdruck (ohne dass, das die
Standard mässige vorgehensweise ist) eine Variable hochzählen ohne das
es einen grossen Sinn macht, denn ich bin jetzt einfach noch mal an den
Anfang gegangen, wo Rechnen mit
int a + int b und int c = c / a+b usw...und
if ( a <= b)
{
d= d+1;
}
if( d == 5)
{
d = 0;
}
zur übung steht.
das kann man auch mit nem texas instrument board machen. und dort wenn
ich zb. int a = P1IN; hinschreibe dann liest er den pin ein. zeigt halt
im debugger 0 oder 1 an.
ich dachte mir das muss doch mit dem im Atmelstudio mit dem Atmega8a
auch gehen, da lag ich wohl falsch. da sollte mir halt wenn d == keine
ahnung halt 5 ,ist die led an pc4 anschalten.
Huber M. schrieb:
> zb. int a = P1IN;
aber in der while(1) Schleife drin, und nicht draußen.
Ja, das habe ich schon gemacht, das ändert aber nichts. In
IDE ATMEL STUDIO 6.0 und Atmega8a muesste es ja dann so heissen oder?
>int a = PIND;>int a = (1<<PD0);
das > zb. int a = P1IN; ist eine andere IDE embedded workbench
Huber M. schrieb:> IDE ATMEL STUDIO 6.0 und Atmega8a muesste es ja dann so heissen oder?>>int a = PIND;>>int a = (1<<PD0);
Nein.
Eher so:
>uint8_t a = PIND|(1<<PD0);
Arduinoquäler schrieb:> Man versteht ja schon deine Ausdrucksweise nicht. Sorry.
Du gehst davon aus, dass er Deinen Satz verstanden hat. Hat er nicht!
Er geht davon aus, dass Du rätselst, ob es sich um C handelt.
Auch einige andere Sätze scheint er nicht verstanden zu haben.
@TO:
Verkauf den Krempel. Du kannst damit nichts anfangen, es überfordert
Dich!
Und die Aufgaben werden bei weiteren Projekten wesentlich (!) komplexer.
Gruß
Jobst
Ralf G. schrieb:> Arduino F. schrieb:>>>uint8_t a = PIND | (1<<PD0);> was soll das jetzt bewirken?
Naja...
Ich dachte mir so...
Huber M. schrieb:>>int a = PIND;>>int a = (1<<PD0);
Das wäre ein unbeholfener Versuch einen Taster einzulesen....
Vielleicht habe ich mich ja auch getäuscht.
Dann bin ich jetzt ent- täuscht.
Peter D. schrieb:> ungetestet
:-) witzig ...
Da sind wir aber einige Sphären außerhalb "Huber M."-s aktuellem
Kenntnisstands.
Er (der TO) hat sich wohl ein C-Buch gekauft (welches auch immer) aber
die Verwendung ist fraglich. Hinweise auf das GCC-Tutorial fallen
scheinbar nicht auf fruchtbaren Boden.
Ich habe mir div. Threads des TO angeschaut und finde überall die
gleiche Unsicherheit. Aus meiner Sicht fehlen die Grundlagen, die sich
jeder halt beibringen muss oder via Volkshochschule oder wie auch immer
erlangen muss.
Karl-Heinz ist ja wohl nicht mehr aktiv ( was mich wirklich sehr
"bedrückt" - ich finde keinen anderen Ausdruck) und ich habe weder die
Geduld noch die Leidensfähigkeit ähnlich aktiv einzugreifen. Auch fehlen
mir die tiefgreifenden Kenntnisse.
@Hubert: Lese Dein Buch und vollziehe alles nach. Gehe das GCC-Tutorial
Schritt für Schritt durch und probiere alles aus. Setze Dich mit dem
Debugger des Atmel-Studios auseinander (das ist nicht allzu schwer - das
weiß ich aus eigener Erfahrung).
Dieter F. schrieb:> ...und ich habe weder die> Geduld noch die Leidensfähigkeit ähnlich aktiv einzugreifen. Auch fehlen> mir die tiefgreifenden Kenntnisse.
Aber was willst Du dann in diesem Thread? Nutzlose Nebenschauplätze
eröffnen, oder was sonst?
PfostenStecker
PfostenStecker schrieb:> Aber was willst Du dann in diesem Thread? Nutzlose Nebenschauplätze> eröffnen, oder was sonst?
Auf die Sinnlosigkeit (welche Dir wohl entgangen ist) hinweisen.
Wobei Dein Beitrag mehr als nutzlos ist. Typisch Gast, eigentlich wollte
ich solche Beiträge ignorieren. Ich gelobe Besserung!
Huber M. schrieb:> ich wollte eigentlich einfach nur per Tasterdruck (ohne dass, das die> Standard mässige vorgehensweise ist) eine Variable hochzählen ohne das> es einen grossen Sinn macht,
Du willst bei einem bestimmten Ereignis, bei einem Tastendruck
hochzählen. Ein Ereignis passiert zu einem bestimmten Zeitpunkt.
Wenn Du aber mit dem Finger eine Taste drückst, drückst Du aber für eine
bestimmte Zeitdauer auf die Taste.
Während Du mit dem Finger auf der Taste bist, führt der Mikrocontroller
locker ein paar Millionen mal Deine Schleife aus. Der ist rasend
schnell.
Mache Dir den Unterschied zwischen einem Zeitpunkt und einer
Zeitdauer klar.
Eine kleine Grafik:
Zeitdauer Taster Zeitdauer Taster
nicht gedrückt gedrückt
<-------------------------> <----------------------->
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1
|
|
Zeitpunkt, hier hat sich der Taster
von "nicht gedrückt" auf "gedrückt"
geändert!
Verstehst Du, was ich Dir erklären will?
Geduldiger schrieb:> Verstehst Du, was ich Dir erklären will?
Dieser Mensch gibt keine Rückmeldungen auf Fragen oder
Erklärungen.
Mit anderen Worten:
Vergebene Liebesmüh, du redest an eine Wand.
Mahlzeit,
Erstmal danke für die Mühe, und die vielen Erklärungen. ich glaube ich
habe es jetzt..... da es beim taster eigentlich nur vier Zustände gibt
-wenn er gedrückt wird
-wenn er gedrückt ist
-wenn er losgelassen wird
-wenn er nicht gedrückt ist
diese Zustände kann ich dann mit rückgabe jeweils auswerten
grüsse huber
Huber M. schrieb:> ich glaube ich habe es jetzt.....
Das glaube ich wiederum nicht. ;-)
Vielleicht solltest Du Dir erst mal klar machen, wie diese Art von
Programmierung überhaupt so abläuft.
Diese Programme bestehen in der Regel aus zwei Teilen. Im ersten Teil
wird der Controller für seine Aufgabe konfiguriert und die für den
weiteren Teil des Programms nötigen Variablen deklariert und
initialisiert. Dieser Teil des Programms wird nach dem Start oder einem
Reset nur einmal durchlaufen, sprich, die Anweisungen werden nur einmal
ausgeführt. Hier wird z. Bsp. festgelegt, ob und welche Port(pin)s als
Eingang oder als Ausgang fungieren und hier wird z. Bsp. deine
Zählervariable initialisiert.
Der zweite Teil des Programms, bei den es ja darum geht, dass der
Controller auf bestimmte Ereignisse reagiert, wird dann in der Regel in
Form einer Endlosschleife ausgelegt. Da so ein Controller so eine
Endlosschleife aber recht fix durchläuft, ein menschlicher Tastendruck
aber immer eine gewisse Zeit dauert und Taster und Schalter zudem auch
noch prellen, also bei Betätigung den Kontakt oft noch mehrmals ändern,
bevor sich der vom Betätiger gewünschte Zustand stabil einstellt, muss
im einfachsten Fall nach Erkennen des Tastendrucks eine gewisse Zeit
gewartet werden, bevor die Taste erneut abgefragt und bei Betätigung
erneut gezählt wird.
Dein Programm könnte also folgenden Aufbau haben:
1
// nötige Bibliotheken einbinden
2
3
intmain(void)
4
{
5
// Controller konfigurieren
6
7
// Variablen deklarieren und initialisieren
8
9
intzaehler=0;
10
11
12
while(1)// Beginn der Endlosschleife, durch den Wert 1
13
{// immer gültig, wird also endlos ausgeführt
14
15
if(taste_gedrueckt)// Abfrage, ob Taste gedrückt
16
{// Ausdruck 'taste_gedrueckt' wahr
17
// es folgen Anweisungen, die nur dann ausgeführt werden,
18
// wenn Taste bei Abfrage gedrückt war
19
20
zaehler=zaehler+1;
21
22
// zaehler z. Bspl. zur Visualisierung über einen Port ausgeben
23
24
delay(300ms);// oder länger warten - Funktionsaufruf
25
// einer Zählschleife
26
27
}// Ende der Anweisungen, die nur abgearbeitet werden,
28
// wenn bei Abfrage die Taste gedrückt war
29
30
}// Ende der Endlosschleife - es folgt der nächste while(1) Durchlauf
31
// die Taste wird dabei erneut abgefragt
32
33
}// Programmende - wird durch die Endlosschleife nie erreicht
Die Sache mit dem Entprellen könnte man natürlich noch stark verfeinern,
z. Bsp. kurze Störungen filtern, die Verzögerungszeit soweit verkürzen,
dass der Einfluss des Prellen zwar eliminiert wird, dabei aber trotzdem
keine unnötigen Verzögerungen entstehen. Sicherstellen, dass nach
drücken der Taste diese auch erst wieder losgelassen werden muss, bevor
erneutes drücken als gültig betrachtet wird usw. Auch wäre eine
Auswertung über einen Interrupt möglich. Aber all das dürfte deine
Fähigkeiten und deinen Kenntnisstand zur Zeit noch überfordern. Deshalb
versuche erst mal anhand der obigen Beschreibung ein lauffähiges
Programm zu erstellen.
Mit besten Grüßen
Murmelchen
Huber M. schrieb:> da es beim taster eigentlich nur vier Zustände gibt>> -wenn er gedrückt wird> -wenn er gedrückt ist> -wenn er losgelassen wird> -wenn er nicht gedrückt ist
Du schreibst und denkst noch immer unlogisch und wirr.
Also: Es gibt bei einem Taster nur exakt 2 Zustände:
1. gedrückt
2. ungedrückt.
Das "gedrückt _werden_" ist kein Zustand, sondern ein Übergang, nämlich
von einem Zustand in einen anderen. Ebenso das "ungedrückt werden" bzw.
losgelassen werden.
An einem Übergang muß man ein Ereignis generieren, das zu einer Reaktion
führen soll (beispielsweise zum Hochzählen eines Zählers): entweder beim
Übergang von ungedrückt zu gedrückt oder bei dem anderen Übergang.
Ich hab dir weiter oben mit der Fabel vom fleißigen Beamten quasi eine
Bauanleitung für deine Software geschrieben, aber du scheinst sie
überhaupt nicht gelesen zu haben, weswegen du immer noch
orientierungslos dahintaumelst.
W.S.
Huber M. schrieb:> -wenn er gedrückt wird> -wenn er gedrückt ist> -wenn er losgelassen wird> -wenn er nicht gedrückt ist
Ja, das kommt in etwa hin. Der Taster hat entweder den Zustand
"gedrückt" oder "nicht gedrückt".
Aber Dein Programm muss unterscheiden, zwischen:
- Taster jetzt nicht gedrückt, vorher war er auch nicht gedrückt
- Taster jetzt gedrückt, aber vorher eben war er noch nicht gedrückt
- Taster jetzt gedrückt, und vorher war er auch gedrückt
- Taster jetzt nicht gedrückt, aber vorher eben war er gedrückt
Genau das sind die Fälle, die dein Programm unterscheiden muss. Und in
genau einem Fall der vier möglichen Fälle, soll dein Programm zählen
oder etwas anderes machen. Der Hauptteil des Programms könnte so
aussehen:
1
inttaster_vorher=0;
2
inttaster_jetzt=0;
3
4
// Endlosschleife
5
while(1)
6
{
7
// Nachschauen, wie der Taster jetzt steht
8
if((PINA&(1<<PA0)))
9
taster_jetzt=1;
10
else
11
taster_jetzt=0;
12
13
// Prüfen, ob der Taster sich gegenüber vorher verändert hat
14
if(taster_vorher==0&&taster_jetzt==1)
15
{
16
// Bingo, Taster wurde gerade eben gedrückt, hier also Zählen etc.
17
...
18
}
19
20
// Endlosschleife springt gleich an den Anfang zurück: Was jetzt aktuell ist, ist nachher alt
21
taster_vorher=taster_jetzt;
22
}
Versuch mal, das Programm zu vervollständigen.
Viel Erfolg! Du bekommst das bestimmt hin!