Hello @all,
Ich möchte gerne mit einem µC und einem Taster etwas an- und
ausschalten.
Das Programm von Peter Dannegger ist mir bekannt und es funktioniert
auch auf meinen µC. Nur verstehe ich den Code noch nicht.
Ich möchte es von anfang an verstehen.
Das nur zur Funktion.
Ich habe das Gefühl das man es vielleicht mit weniger Zeilen und Aufwand
hinbekommt.
Ich bin ein newbie, bitte um konstruktive Kritik. Alles andere bringt
mich nicht weiter.
Nun zur Frage:
Wie weit ist der von mir entstandene Code zu optimieren?
Ich danke euch.
1
.include "tn2313def.inc"
2
.device attiny2313
3
.equ takt = 8000000
4
/*
5
*/
6
ldi r16, 0xFF
7
out DDRB, r16 ;port B->Ausgang
8
// ldi r16, 0x00
9
// out PORTB, r16 ;port B ->low
10
11
ldi r16, 0x00
12
out DDRD, r16 ;port D->Eingang
13
ldi r16, 0x00
14
out PORTD, r16 ;port D ->low
15
16
aus:
17
sbic PIND, 2 ;überspringe nächsten befehl, wenn PIND.2 1 ist - taste gedrückt
18
rjmp aus ;springt ins label aus -> wenn PIND.2 0 ist
19
rcall warte ;entprellzeit -> aufruf von label warte
20
cbi PORTB, 3 ;PINB.3 0
21
sbis PIND, 2 ;überspringe nächsten befehl wenn PIND.2 0 ist - taste nicht mehr gedrückt
22
rjmp aus ;springt ins label aus -> wenn PIND.2 1
23
rcall warte ;entprellzeit -> aufruf von label warte
24
rjmp an ;springt ins label an
25
26
an:
27
sbic PIND, 2 ;überspringe nächsten befehl, wenn PIND.2 1 ist - taste gedrückt
28
rjmp an ;springt ins label aus -> wenn PIND.2 0 ist
29
rcall warte ;entprellzeit -> aufruf von label warte
30
sbi PORTB, 3 ;PINB.3 1
31
sbis PIND, 2 ;überspringe nächsten befehl wenn PIND.2 0 ist - taste nicht mehr gedrückt
32
rjmp an ;springt ins label aus -> wenn PIND.2 1
33
rcall warte ;entprellzeit -> aufruf von label warte
34
rjmp aus ;springt ins label aus
35
36
warte: ;wartezeit wegen kontaktprellen erzeugen
37
ldi R19,67 ;lade R19 mit 67
38
LOOP0: ;äussere schleife
39
ldi R18,198 ;lade R18 mit 198
40
LOOP1: ;innere schleife
41
dec R18 ;erniedrige R18
42
brne LOOP1 ;solange R18 nicht 0 ist, bleib in der schleife
43
dec R19 ;erniedrige R19
44
brne LOOP0 ;solange R19 nicht 0 ist, bleib in der schleife
45
ret ;wenn schleifenzeit um ist, hüpfe dahin, wo du hergekommen bist
@Hein Blöd
Das Entprellen wird noch in 20 Jahren ein Thema sein, ueber das sich die
Leute streiten. Wenn Deine Methode funktioniert, behalte sie bei.
Es bringt mehr, eigenen Code zu entwickeln als sich in die Gedan-
kengaenge anderer hineinzusteigern. Wenn Du das gesamte Programm selbst
geschrieben hast, anstatt eine Routine von hier und eine von da
zusammmen
zu kopieren, dann ist eine viel groessere Zufriedenheit da.
gez. Zittermann
Zittermann schrieb:> Wenn Deine Methode funktioniert, behalte sie bei.
Das Problem dabei ist nur, zu verifizieren, ob es auch wirklich
fehlerfrei funktioniert.
Z.B. wenn man sich elektrostatisch geladen dem Draht zur Taste annähert.
Oder wenn noch ein langes Kabel zum Taster führt, welches parallel zur
Netzleitung zum Staubsauger liegt.
Zittermann schrieb:> Es bringt mehr, eigenen Code zu entwickeln als sich in die Gedan-> kengaenge anderer hineinzusteigern.
Wenn man sich hineinsteigern muß, sollte man das Programmieren besser
sein lassen. Zum Programmieren sollte man keinen Stress haben, sonst
macht man nur Fehler.
Wenn man Code von Leuten, die schon ein paar Tage länger programmieren,
verstehen will (und kann), ist das jedoch ein großer Vorteil. Dann ist
man als Programmierer auf dem richtigen Weg.
Als Programmierer darf man sich nicht als Künstler sehen, sondern eher
als Forscher, die voneinander gegenseitig lernen.
Zittermann schrieb:> Wenn Du das gesamte Programm selbst> geschrieben hast, anstatt eine Routine von hier und eine von da> zusammmen> zu kopieren, dann ist eine viel groessere Zufriedenheit da.
Die Zufriedenheit ist aber nicht von Dauer.
Die Delays werden Dir bei komplexeren Programmen irgendwann auf die Füße
fallen.
Peter
Kann keiner näher auf meine Frage eingehen?
@Peter:
Ich habe Deine Infos mir zu Herzen genommen.
Nur würde ich das gerne von Anfang an verstehen.
Man lernt auch laufen mit einem Schritt nach dem anderen.
Vielen Dank
BR
hein blöd schrieb:> Kann keiner näher auf meine Frage eingehen?
Welche?
Die hier?
> Nun zur Frage:> Wie weit ist der von mir entstandene Code zu optimieren?
Als Newbie solltest du dich um 'Optimierung' überhaupt noch nicht
kümmern. Zum jetzigen Zeitpunkt gibt es nur 1 Frage: Funktioniert er
bzw. unter welchen Nebenbedingungen funktioniert er nicht mehr.
> @Peter:> Ich habe Deine Infos mir zu Herzen genommen.> Nur würde ich das gerne von Anfang an verstehen.
Was würdest du gerne verstehen?
Die Danegger Entprellung?
Die ist so trickreich, das ist ok, wenn man die nicht versteht. Ist eine
der wenigen Ausnahmen zur Regel, dass man als Anfänger jeglichen
übernommenen Code verstehen sollte. An der genauen Funktionsweise
beissen sich auch gestandene Profis die Zähne aus, so trickreich ist
das. Hat man sie erst mal durchschaut, ist sie einfach. Aber bis man sie
in allen Details versteht, .....
hein blöd schrieb:> Kann keiner näher auf meine Frage eingehen?
Beim Optimieren Deines Programmbeispieles werde ich Dir nicht helfen,
denn das führt zu nichts.
Nimm die Dannegger-Bulletproof-Entprellung und analysiere sie. Es
reicht, wenn Du sie ein einziges mal verstehst und dann nur noch
benutzt. Um damit Dein Bit zu toggeln (an/aus-umschalten), kannst Du das
Byte (mit Deinem Bit) mit key_press EXORen und key_press danach löschen.
Somit kippt das Bit in Deinem Byte bei jedem Tastendruck in die andere
Richtung. Dazu muss es natürlich an derselben Bitposition wie der Taster
sein. Anhand dieses Bits kannst Du dann durch Bit-Prüfung (sbrs/sbrc)
Schaltvorgänge auslösen. Das funktioniert ohne jegliche Wartezeiten, das
Programm kann also nebenher noch genügend andere Dinge erledigen.
>> @Peter:> Ich habe Deine Infos mir zu Herzen genommen.> Nur würde ich das gerne von Anfang an verstehen.
Diesen Thread hast Du auch gelesen?
Beitrag "Bitte um Erklärung der Entprellroutine">> Man lernt auch laufen mit einem Schritt nach dem anderen.
Eben. Und manchen Schritt muss man wiederholen, wenn man ihn zuvor nicht
verstanden hat.
>> Vielen Dank>> BR
...
Hannes Lux schrieb:> Beim Optimieren Deines Programmbeispieles werde ich Dir nicht helfen,>> denn das führt zu nichts.
Das möchte ich auch nicht.
Nur ich möchte wissen ob ich auf den richtigen Holzweg bin.
Ich benötige kein Code, nur ein paar konstruktive Hinweise.
Vielen Dank.
BR
hein blöd schrieb:> Ich benötige kein Code, nur ein paar konstruktive Hinweise.
Mein Tipp: guck dir an, was andere machen.
Und dann trotzdem was eigenes schreiben.
So mach ich das. Erstmal abkupfern, bzw. Ideen sammeln, und danach doch
eigenen Code schreiben. Es sei denn, das "geklaute" ist sehr gut, und
habe es wirklich verstanden.
Karl heinz Buchegger schrieb:> Was würdest du gerne verstehen?>> Die Danegger Entprellung?
Jaein, bei der Software vom Peter begreife ich es nicht wie man es
ändern muss z. B. das wenn ich am Eingang von PD1 ein Taster betätigen
möchte das bei PB3 dann meine LED zum leuchten bekomme.
Bei der Software wird gleich der ganz PD am eingang somit entprellt.
Denn wenn ich nur zwei Tasten benötige und ich möchte den Rest meiner
I/Os nicht verschwenden.
Ich hoffe das ich mich einigermassen ausdrücken konnte.
Vielen Dank
BR
Peter Dannegger schrieb:> Die Delays werden Dir bei komplexeren Programmen irgendwann auf die Füße> fallen.
100% ACK
Aber manch einer muss eben erst den Schmerz erleben, bevor er seinen
Horizont erweitert. Das ist keine Schande, aber die eigene verschwendete
Zeit. Muss also jeder für sich entscheiden wie viel Zeit man liegen
lassen kann.
hein blöd schrieb:> Karl heinz Buchegger schrieb:>> Was würdest du gerne verstehen?>>>> Die Danegger Entprellung?>> Jaein, bei der Software vom Peter
Bitte sag nicht 'Bei der Software vom Peter'
Peter hat wahrscheinlich hunderte Codeschnipsel hier im Forum
hinterlassen.
Sag konkret: Dieses und jenes Codestück.
Garniert mit einem Link bzw. kopiere es hier rein.
Dann weiß jeder wovon du eigentlich sprichst.
hein blöd schrieb:> Bei der Software wird gleich der ganz PD am eingang somit entprellt.>> Denn wenn ich nur zwei Tasten benötige und ich möchte den Rest meiner> I/Os nicht verschwenden.
Reden wir von der Komfort-Lösung?
Du musst nicht einen kompletten Port für Taster abstellen.
Du kannst. Aber du musst nicht.
Frag die entsprechenden Taster einfach nicht ab und sie werden dir nicht
in die Quere kommen. Es spricht auch nichts dagegen, am Tastenport
einige Pins auf Ausgang zu stellen. Die Auswertung berücksichtigt sie
zwar als sowas ähnliches wie Tasten. Da das aber keine zusätzliche
Rechenzeit kostet, spielt es weiter keine Rolle.
hein blöd schrieb:> Hannes Lux schrieb:>> Beim Optimieren Deines Programmbeispieles werde ich Dir nicht helfen,>>>> denn das führt zu nichts.>> Das möchte ich auch nicht.> Nur ich möchte wissen ob ich auf den richtigen Holzweg bin.>> Ich benötige kein Code, nur ein paar konstruktive Hinweise.
Na gut, ich beziehe mich auf die Bulletproof-Version in ASM...
Mechanische Tasten prellen. Um sicher zu sein, dass die Taste betätigt
oder unbetätigt ist, liest man den Zustand in regelmäßigen Zeitabständen
ein und vergleicht ihn mit dem vorher eingelesenen Zustand. Dabei zählt
man mit, wie oft der neue Zustand sich wiederholt. Man braucht also eine
Zeitverzögerung und einen Entprellzähler.
Zur Zeitverzögerung sollte man einen Timer-Interrupt nutzen. Dies
bietet im Gegensatz von Warteschleifen die Möglichkeit, dass der
Controller außerhalb der Tastenabfrage noch andere Dinge tun kann. Bei
Verwendung von Warteschleifen muss die CPU ja Takte zählen und hat keine
Zeit, andere Dinge abzuarbeiten.
Der Entprellzähler soll die Anzahl der gleichen Zustände des
Tastereingangs zählen, jeder Tastereingang braucht seinen eigenen
Zähler. Man könnte nun jedem Taster ein Byte (Register, Variable)
spendieren, das wäre aber pure Verschwendung und würde bei mehreren
Tasten auch den Programmablauf verlangsamen. Stattdessen nimmt man zwei
Register als Zähler für 8 Taster, wobei jeder Zähler 2 Bit hat
(Zählumfang 0 bis 3), die sich in unterschiedlichen Registern befinden.
Das eine Register enthält also das Bit 0 aller 8 Zähler, das andere
Register das Bit 1 aller Zähler. Der große Vorteil besteht darin, dass
alle 8 Zähler mit wenigen Logikbefehlen gleichzeitig arbeiten. Wenn Du
den Zähler verstehen willst, dann schau Dir an, wie man einen Zähler mit
Logikgattern realisiert.
Außer den beiden Zählerbytes gibt es noch den Tastenstatus (Key_State)
und die Tastenflags (Key_Press). Im Status steht der zuletzt gültige
Zustand der 8 Tasten. Er dient zum Vergleich mit den neuen
Eingangszuständen und kann vom Hauptprogramm genutzt (aber nicht
verändert!) werden, um eine momentan gedrückte Taste (Shift) zu
erkennen. Ist nun der neu eingelesene Zustand (im Tempregister) gleich
wie der zuletzt gültige Zustand (in Key_State), so wird der jeweilige
Prellzähler gelöscht. Ist der Zustand anders, wird der Prellzähler
erhöht. Erreicht der jeweilige Prellzähler den Wert 3 (Bit in beiden
Zählerbytes gesetzt), so kommt das Bit im Tempregister durch
(anderenfalls wird es ja per AND gelöscht) und kann den gültigen Status
(Key_State) toggeln (EXOR). Durch ein weiteres AND wird geprüft, ob der
(entprellte, gültige) Status jeder Taste 0 oder 1 ist. Ist er 0, wird
das entsprechende Bit im Tempregister gelöscht. Ist er 1, so kommt das
Bit im Tempregister durch und darf das Merkerbit im Register Key_Press
setzen. Dieses zeigt dem Hauptprogramm, dass die entsprechende Taste neu
betätigt wurde. Das Hauptprogramm verzweigt nun anhand der gesetzten
Bits in Key_Press zu den Tastenbehandlungsroutinen. Diese erledigen den
zur Taste gehörenden Job und löschen das Tastenbit in Key_Press, denn
der Job ist ja erledigt.
Fazit:
Timer-Interrupt mit 10ms oder 20ms Aufrufintervall einrichten, darin die
Routine der Tastenentprellung unterbringen und noch andere Dinge, die
einen festen Zeittakt brauchen, z.B. Uhr.
Im Hauptprogramm nur das Register Key_Press auf gesetzte Bits prüfen und
bei gesetztem Bit zur jeweiligen Behandlungsroutine springen. In dieser
das Bit in Key_Press löschen (damit der Job nur einmal erledigt wird)
und den Job erledigen.
>> Vielen Dank.>> BR
...