Hallo an Alle,
so nach vielem hin und her habe ich mich doch entschieden mich hier
anzumelden.
ich bin zur Zeit Schüler an der Technischen Akademie und wurde dort mit
dem AVR Virus befallen.
Ich hab mir selbst die Aufgabe gestellt, die aus der Überschrift zu
erahnen ist... Jeder kennt die Radiowecker Funktion, wenn man den Knopf
der Uhr drück, das sie erst langsam hoch zählt und nach einer gewissen
zeit schneller, bzw in Sprüngen hoch zählt. Genau das habe ich vor!!!
Mein Problem ist volgendes, das ich z.Z. mit einer einfachen IF Abfrage
und nem Zähler++ abriete.... ist zähler <x dann soll ein wert in 1ner
schriten und wenn der zähler >x ist soll er in größeren schritten weiter
zählen.
da ich keine schleife verwenden kann, die den taster direkt abfragt...
bzw. ich in der schleife hängen bleibe und die INT0 nur die flanken
zählz und nicht Impulse erzeugt hänge ich jetzt etwas fest!
ich stelle einfach mal den Teil der Main() hier rein... ich hoffe das
einige Schlau Köpfe eine ide haben... Ach ja die geschichte mit nem
Timer Interrupt würde ich gerne vermeiden wenn es geht!?
MFG Timo
Timo Solterbeck schrieb:> Ach ja die geschichte mit nem> Timer Interrupt würde ich gerne vermeiden wenn es geht!?
Tu' es dir trotzdem an, es ist bei weitem die eleganteste Lösung. Und
wenn du mal über mehr als ein "Micky-Maus-Programm" machen möchtest,
kommst du eh nicht mehr drum herum.
Ansonsten: Dein Code sollte eigentlich funktionieren. Was heißt "Geht
nicht..." ?
Läuft der Code wirklich genau dann in den Fall
>if(SERVO_PIN & (1 << HOCH))
wenn der Taster gedrückt ist?
Du solltest übrigens auch prüfen, dass die "cnt" nicht überlauft.
Captain Subtext schrieb:> wenn du mal über mehr als ein "Micky-Maus-Programm" machen möchtest
Entschuldige bitte meine Wortwahl, jeder fängt mal "klein" an.
danke das hier so promte antworten kommen.
ich hatte noch einen beitrag von "Karl Heinz Buchegger" zu meinem
beitrag, den würde ich gerne lesen, aber er ist nicht mehr da!
@Captain Subtext
entschuldigung angenommen, aber muss man das forum mit megal langen code
texten zu spamen.... ich denke nicht... und mein "kleines programm ist
nur eine nachbarkeitsstudie.... testest du deine programme immer gleich
komplett???
so nun zu meinem progrämmchen... das hochzählen der stepp-variable
funzt... der servo fährt auch, nur leider wird die cnt nicht
hochgezählt.... eigenlich, so hab ich mir das gedacht, müsste bei jedem
schleifendurchlauf der main while(1) der zähler hoch gezählt werden, und
genau das tut er nicht!!! keine ahnung warum.
vielleicht hat hier ja noch einer einen tip!?
achja warum ich den timer interrupt vermeinden will, weil ich nicht so
viele erfahrungen mit dem habe und weil einer davon schön für den servo
verwendet wird!!!!
mfg timo
Timo Solterbeck schrieb:> danke das hier so promte antworten kommen.>> ich hatte noch einen beitrag von "Karl Heinz Buchegger" zu meinem> beitrag, den würde ich gerne lesen, aber er ist nicht mehr da!
Weil ich zu spät gemerkt habe, dass du 2 Repeat Stufen haben willst.
Mein Grundtenor ist immer noch der gleiche: Nimm die PeDa
Entprellung und erfinde da nichts eigenes, was wieder mal nicht
vernünftig funktioniert.
Nur dass die PeDa Entprellung keine 2 unterschiedlichen Repeat-Stufen
hat. Da ich allerdings denke, dass man das auch nicht wirklich braucht,
hatte ich dann aber auch keine Lust mir da was einfallen zu lassen und
hab den Beitrag zurückgezogen.
Guten morgen an Alle,
so ich hab mir noch ein paar ratschläge zu herzen genommen und meinen
kopf ein klein wenig mehr angestrengt ;-)
ich hatte zwei "fehlerchen" in meinem code, zum einen war tatsächlich
die taster abfrage nicht ganz richtig, (danke @Captain Subtext) und zum
anderen hatte ich nen denkfehler in einem 'else' teil...
naja sei es drum hich habs geschaft und möchte den code kurz
präsentieren!
es ist ein kleines und recht einfaches programm um einen servo über
tasten drehen zu lassen.
vielleicht ist das von der tastenbeschaltung für den einen andern
anfänger interessant!?
mfg timo
1
#include<my_init.h> //beinhaltet: ADC, Interrupt, Standart #include's
> vielleicht ist das von der tastenbeschaltung für den einen andern> anfänger interessant!?
Als Beispiel wie man den sinnvollen Ratschlag eine Entprellung zu
benutzen komplett ignoriert?
Dieses Programm "funktioniert" trotz naturgemäß prellenden Tastern nur,
weil rel. lange Wartezeiten (delay_ms, LCD Ausgabe) zwischen den
einzelnen while-Durchläufen liegen.
Wenn sich der erste Anwender beschwert, dass wegen der rel. langen
Wartezeiten ein schnelles Antippen der Tasten nicht registriert wird,
kommt eine Codeänderung und nix geht mehr...
@Karl Heinz Buchegger ich hab die tasten entprell geschicht nicht
genommen weil ich ja was eigenens machen wollte (von dir ja auch
gefördert)
ich hab mir die entprellroutine angeguckt und bin aber nicht hinter die
makro funktinen gestiegen... dein code sieht logisch aus, aber halt mit
diesen makros.
die kritik mit den "langen" delay zeiten nehme ich zur kenntnis und ich
weis das das nicht ganz elegant ist, aber ich hab das programm ja nur
für diesen einen zweck des servo testens geschrieben...
ich werden mich bei gelegenheit um eine verbesserung bemühen!
mfg
Timo Solterbeck schrieb:> @Karl Heinz Buchegger ich hab die tasten entprell geschicht nicht> genommen weil ich ja was eigenens machen wollte (von dir ja auch> gefördert)> ich hab mir die entprellroutine angeguckt und bin aber nicht hinter die> makro funktinen gestiegen...
Wie ich in diesem Forum immer wieder sage:
Das macht nichts.
Diese Entprellung hat so viele Vorteile, dass es nichts ausmacht, wenn
man nicht dahinter steigt, wie sie eigentlich (der Code in der ISR)
funktioniert. Der ist zweifellos ziemlich trickreich. Aber sie
funktioniert einfach zu gut, als das man sie ignorieren könnte.
Ich versteh ja auch nicht im Detail, wie ein Autogetriebe genau
funktioniert und warum da so viele Zahnräder drinnen sind. Deshalb geh
ich aber auch nicht zu Fuss.
Und die Makros, na ja so schwer sind die auch nicht zu verstehen
Die ersten 3 legen die Konfiguration fest: AN welchem Port sind denn
eigentlich die Tasten.
Dann kommen n Stück Tastenvereinbarungen und an welchem Pin sie sind
ALL_KEYS ist einfach nur ein Makro welches alle Tasten zusammenfasst
(wegen der DDR und Pullup Initialisierung). Die letzten 3 Makros regeln,
auf welche Tasten ein Autorepeat gelegt wird, wann er einsetzen soll und
wie schnell er sein soll.
In Summe, denke ich, nicht allzuschwer zu verstehen und an seine
Gegebenheiten anzupassen.
Bei dir wäre das
1
#define KEY_DDR DDRD
2
#define KEY_PORT PORTD
3
#define KEY_PIN PIND
4
#define HOCH 2
5
#define RUNTER 3
6
#define MITTE 4
7
#define ALL_KEYS (1<<HOCH | 1<<RUNTER | 1<<MITTE)
8
9
#define REPEAT_MASK (1<<HOCH | 1<<RUNTER)
10
#define REPEAT_START 50 // after 500ms
11
#define REPEAT_NEXT 20 // every 200ms
12
13
volatileuint8_tkey_state;// debounced and inverted key state:
14
// bit = 1: key pressed
15
volatileuint8_tkey_press;// key press detect
16
17
volatileuint8_tkey_rpt;// key long press and repeat
den ISR Code noch in deine vorhandene ISR integrieren, die Funktionen
get_key_press und get_key_rpt in den eigenen Code übernehmen und am
Anfang vom main nich die Portinitialisierung für den Tastenport direkt
übernehmen. Eventuell noch die Werte bei REPEAT_START und REPEAT_NEXT
etwas verändern, so dass man das Zeitverhalten kriegt welches einem
zusagt.
Aber damit ist die Sache im wesentlichen gegessen und man hat
erstklassig entprellte Tasten, die man in der eigenen Anwendung leicht
und einfach verwenden kann.
Ach ja. Irgendeinen Timer braucht man noch (damit man eine ISR hat). Den
hat aber sowieso so gut wie jedes ernstzunehmende Programm in
irgendeiner Form bereits im Einsatz. Ob die ISR jetzt alle 4 oder alle
40 Millisekunden, oder irgendein Wert dazwischen, aufgerufen wird,
spielt hingegen für die Entprellung keine wirkliche Rolle. Hier nimmt
man, was man für den Rest der Applikation braucht. Bei dir gehts leider
nicht, weil deine ISR (gewollt) in unregelmässigen Abständen aufgerufen
wird. Macht aber nichts, du hast ja noch mehr Timer zur Verfügung.
Es ist schon ok, wenn du selbst dich an Tastenentprellung versuchst.
Aber du siehst auch, dass ohne _delay_ms da nicht viel geht. Und
_delay_ms ist (bis auf wirklich ganz kurze Zeiten) eines der Übel, die
einem bei komplexeren Programmen alles versauen, weil es damit schwer
bis unmöglich wird, dass das Programm scheinbar mehrere Dinge
gleichzeitig machen kann. Eine Motorabschaltung darf nicht 100ms zu spät
kommen, nur weil der Benutzer auf der Taste eingeschlafen ist.