Hallo zusammen, leider programmiert PeDa ( Peter Dannegger ) ja nur noch in C. Ich würde gerne als " AVR-ASM-Übender " die erweiterte Version von dieser hier verstehen und suche somit Leute die Lust und Können besitzen, dies einem AVR-Assembler-Übenden zu erklären : Beitrag "Re: Tasten entprellen - Bulletproof" Wie sieht der Logikplan mit den erweiterten Funktionen key_release, key_short, key_long und key_repeat aus ? Beitrag "Universelle Tastenabfrage" Das hier meine ich schon verstanden zu haben, es benögtigt ja auch nur ein Register ( key_reg ), wo alles untergebracht ist. Somit habt Ihr auch meinen Verständnisstand und wißt wo Ihr mich geistig abholen könnt. Beitrag "Einzelnen Taster entprellen ASM" Bernd_Stein
:
Verschoben durch User
Hi Das http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten#Erkennung_von_Flanken_am_Tasteneingang ist dir bekannt? MfG Spess
spess53 schrieb: > Das > http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten#Erkennung_von_Flanken_am_Tasteneingang > > ist dir bekannt? > Nein, war es nicht. Super, alles in Assembler. Beim ersten Überfliegen raucht mir schon der Kopf. Scheint alles Angesprochene dabei zu sein, bis auf " Taster losgelassen " ( key_release ), aber das kann ich auch übersehen haben. Melde mich dann wenn ich gezielte Fragen dazu habe oder meine etwas anders gestalten zu wollen. Danke nochmals für diese schnelle und hilfreiche Antwort. Bernd_Stein
Hallo Bernd Stein, hab mal den Code im AVR Tutorial ganz grob überflogen! Und frage hier die Experten....warum ist besonders der Anfang so kompliziert. z.B. die .def Anweisungen wie: .def key_old=r3 (warum nicht z.B. temp3)oder .def temp1 = r17 (z.B temp17)oder .def temp2 = r18 (z.B. temp18) oder .equ led_ddr = DDRB (warum bleibt man nicht beim DDRB) usw. Ich finde, es ist dann ein Wahnsinn, diese Verschlüsselungen in der Loop....rjmp Loop Schleife auseinander zu Puzzeln. Oder liege hier völlig daneben? Wie gesagt, das würde mich verrückt machen. Also nichts für UNGUT! Grüße Rolf
Rolf H. schrieb: > .def key_old=r3 (warum nicht z.B. temp3) Der Name temp3 würde bedeuten, dieses Register darf überall im Programm zerstört und beliebig neu beschrieben werden. Die Bezeichnung key_old zeigtr nun, r3 ist dauerhaft von der Tastenroutine belegt und kann für nichts anderes mehr verwendet werden. > .def temp1 = r17 (z.B temp17) Warum temp17? Das würde ja bedeuten, temp0 bis temp16 sind auch schon definiert. Tatsächlich werden dort aber irgendwelche anderen Variablen - z.B. Key_old, key_press,.. - liegen. Der Name muss nicht zwangsläufig auf die tatsächliche Registeradresse hinweisen. Der Programierer legt Namen und Register einmal fest, beim weiteren programmieren kann man dann vergessen an welcher Adresse die Variable tatsächlich liegt.
Rolf H. schrieb: > .def key_old=r3 (warum nicht z.B. temp3)oder > .def temp1 = r17 (z.B temp17)oder > .def temp2 = r18 (z.B. temp18) oder > > Ich finde, es ist dann ein Wahnsinn, diese Verschlüsselungen > in der Loop....rjmp Loop Schleife auseinander zu Puzzeln. > Man gibt den Arbeitsregistern für ein Selber " sinnvolle " Namen. key_old steht z.B. für den Tasterzustand bevor der neue eingelesen wurde und somit ist key_old halt der alte Tasterzustand und der gerade eben erst eingelesene wird im Arbeitsregister key_now abgelegt. Jetzt muß man nicht überlegen welches Arbeitsregister den Inhalt vom alten Tasterzustand hat, denn key_old ist für diesen Zweck sinnfälliger als r3 oder temp3. Kannst Du mir z.B. sofort sagen in welchem Arbeitsregister ( r0 bis r31 ) der gerade eingelesene Tasterzustand abgelegt wurde ? Ich auch nicht, aber auf Grund meiner Englischkenntnisse fällt mir da eher key_now ein als eines der 32-Arbeitsrgister. Deshalb versieht man diese Arbeitsregister mit für die Programmierung sinnfäligen Namen. temp1 und temp2 sind Arbeitsregister die für temporere Aufgaben genutzt werden. Sie stehen also nicht für eine bestimmte Sache, sondern für die momentan zu bewerkstelligende. Und auch hier ist es ( fast ) egal welches von den 32 Arbeitsregister ( r0-r31 ) dafür genutzt wird. Fast - weil die oberen 16 Arbeitsregiser ( r16-r31 ) mehr Adressierungsmöglichkeiten bieten. Zum Beispiel können erst ab r16 die bitweise arbeitenden Befehle sbr/cbr sowie sbrs/sbrc genutzt werden. > > .equ led_ddr = DDRB (warum bleibt man nicht beim DDRB) usw. > Auch hier wieder wegen des besseren Behaltens. So ein µC bietet auch mal mehr als einen Port. Damit man sich nicht merken muß, an welchem Port z.B. die LEDs, Taster, LCD usw. sind, gibt man auch diesen sinnvolle Abkürzungen. Led, Key, Lcd usw. Außerdem gibt es hierbei noch einen enormen Vorteil. Nehmen wir einmal an, das LCD ist an einem anderen Port besser im Layout zu verdrahten, dann ordnet man dem LCD einfach einmalig den anderen Port in der Definition zu und muss sich im Programm um nichts weiter kümmern. Ich habe Dir jetzt mal als nicht Experte geantwortet und will Dir das von einem der Experten nochmal nahelegen. Da das alles für den Anfang sehr Viel ist nur ein Auszug für *Definitionen :* Definitionen: Damit die Unterprogramme auch wirklich universell sind, sollte man so oft wie möglich mit Definitionen arbeiten. Z.B. werden sämtliche Anschlüsse des ATTINY12 über Definitionen verwendet. Dadurch ist es jederzeit möglich, die Anschlüsse umzulegen, wenn sich z.B. dadurch ein günstigeres Platinenlayout ergibt. Oder auch, wenn in einem anderen Programm die Zuordnung eine andere ist (anderer AVR, Konflikte mit den Sonderfunktionen bestimmter Pins). Auch Konstanten innerhalb des Programms sollten nicht als Zahl eingegeben werden, wenn sie sich z.B. bei anderer Quarzfrequenz mit ändern. Auch kann der AVR-Assembler Berechnungen bis 32Bit für die Konstanten selber durchführen. Z.B. sind die benötigten Verzögerungen beim LCD oder 1-Wire-Bus über Berechnungen aus der Quarzfrequenz definiert. Man muß also nur z.B. 1.2MHz beim ATTINY12, 1.6MHz beim ATTINY15 oder 2MHz beim ATTINY26 angeben und schon werden die Verzögerungszeiten korrekt neu berechnet. Beitrag "Zeit + Temperatur auf LCD mit AVR" Bernd_Stein
:
Bearbeitet durch User
Bernd Stein schrieb: > Man gibt den Arbeitsregistern für ein Selber " sinnvolle " Namen. > . > ( r0 bis r31 ) der gerade eingelesene Tasterzustand abgelegt wurde ? > . > ( fast ) egal welches von den 32 Arbeitsregister ( r0-r31 ) dafür Wer oder was ist Selber und "never seen before" plenking? > Ich habe Dir jetzt mal als nicht Experte geantwortet und will Dir das > von einem der Experten nochmal nahelegen. Ansonsten kaum was zu deinem Beitrag zu bemerken, außer vielleicht, daß du dich wirklich weiter aufs Fragen und Lernen beschränken solltest.
na, das muß ich erst mal innerlich verarbeiten! In meinen Anwendungen, die sich ausschliesslich im Steuerungsbereich bewegen, hatte ich da noch nie Probleme. Aber bin ja belehrbar und werde es mal im Auge behalten...vielleicht macht es KLICK. Hatte mal von Hannes Lux ein Code für Modelleisenbahn vor mir, mit den ich erst mal nicht zurecht kam. Also umgestrickt auf meine Variante (tempx = rx)und dann gings los. Es sollte aber keine Kritik sein! Grüße Rolf.
grummel schrieb: > Wer oder was ist Selber und "never seen before" plenking? > Hast recht - hört sich fürchterlich an. Aber plenken gefällt mir, das werde ich wohl beibehalten ;-) *Man gibt den Arbeitsregistern für sich Selbst " sinnvolle " Namen.* Ich denke das liest und versteht sich wohl besser. Obwohl " für sich " schließt ja schon das " Selbst " mit ein, so das man sich dieses Wort sparen kann. Aber das ist wohl ähnlich wie mit dem Spruch : " Ich persönlich ". Rolf H. schrieb: > na, das muß ich erst mal innerlich verarbeiten! > So geht es mir auch. Nur meistens arbeite ich nicht lange genug daran. Und bevor ich es verinnerlicht hatte, hatte ich es leider wieder vergessen, womit ich wieder am Anfang stand. *Also dranbleiben lautet die Devise.* > > Hatte mal von Hannes Lux ein Code für Modelleisenbahn vor mir, > mit den ich erst mal nicht zurecht kam. > Oh ja, wirklich gute Assemblerprogramme. Nur das dahintersteigen habe ich nie ohne Seine Hilfe geschafft. Und fange fast jedesmal von vorne an, wenn ich mir Seine Programme anschaue, aber die Tricks sind einfach genial. Aber nun merke ich wieder wie ich langsam Off-Topic werde ;-), aber diese Tasterentprellung von PeDa macht es einem nicht einfach dran zu bleiben, weil hier auch so manche Tricks zum Tragen kommen, die mann immer wieder durchspielen muss um sie wirklich zu verinnerlichen. Bernd_Stein
Rolf H. schrieb: > Also umgestrickt auf meine Variante (tempx = rx)und dann gings los. Das ist aber auch Unfug, da kannst Du gleich rx (z.B. r17) ins Programm schreiben. wendelsberg
ja wendelsberg...hast Recht! Ich weiss heute auch garnicht, wo ich den Blödsinn abgekupfert habe. Aber irgendwo muß ich es her haben...von mir kommt das nicht. Vor Jahren hab ich mit den r17 bis rxx gearbeitet, allerdings r16 war für mich schon immer eine Ausnahme und das wird es auch bleiben. So, nun will ich das Thema aber beenden. Grüße Rolf
:
Bearbeitet durch User
Hallo, könnte das bitte jemand als Logikplan erstellen, ich krieg's nicht hin. Weiß zum Beispiel nicht woher key_state, iwr0, iwr1 und key_press ihren Ursprung haben sollen. key_old macht mich ganz kirre, denn zum Einen ist es ja der " gerade " eingelesene Tasterzustand und zum Anderen ist er aber vorher nach iwr0 kopiert worden. Wie soll man sowas in einem Logikplan festmachen ? Wo ist denn da der Prellzähler enthalten ? Quelle ist hier : http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten#Kombinierte_Entprellung_und_Flankenerkennung
1 | get8key: ;/old state iwr1 iwr0 |
2 | mov iwr0, key_old ;00110011 10101010 00110011 |
3 | in key_old, key_pin ;11110000 |
4 | eor iwr0, key_old ; 11000011 |
5 | com key_old ;00001111 |
6 | mov iwr1, key_state ; 10101010 |
7 | or key_state, iwr0 ; 11101011 |
8 | and iwr0, key_old ; 00000011 |
9 | eor key_state, iwr0 ; 11101000 |
10 | and iwr1, iwr0 ; 00000010 |
11 | or key_press, iwr1 ; gedrückte Taste merken |
Bernd_Stein
Bernd Stein schrieb: > Hallo, > Sieh dir bitte die Erläuterungen zum C-Code an, die du hier Entprellung finden kannst. Diese Assemblr-Implementierung ist meiner Erinnerung nach so ziemlich eine 1:1 Kopie davon in Assembler. Und nein. Es ist nicht tragisch, wenn du den Code nicht durchblickst. Der ist tatsächlich von der Idee her recht trickreich aufgebaut.
Karl Heinz schrieb: > Sieh dir bitte die Erläuterungen zum C-Code an, die du hier > Entprellung finden kannst. > Habe ich gemacht, bin aber nun nach gut 2 Std. nicht weitergekommen, als bisher. Ich zitiere : Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich als Flipflops denken, die mit der Entprellzeit als Takt arbeiten. http://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29 Bernd_Stein
Bernd Stein schrieb: > Karl Heinz schrieb: >> Sieh dir bitte die Erläuterungen zum C-Code an, die du hier >> Entprellung finden kannst. >> > Habe ich gemacht, bin aber nun nach gut 2 Std. nicht weitergekommen, iwr0 und iwr1 realisieren 8 STück 2 Bit Zähler. Das besondere daran ist, dass die Zähler nicht wie gewohnt komplett in einer Variablen drinn sind
1 | uint8_t zaehler; |
2 | |
3 | zaehler++; |
sondern die beiden Bits des Zählers auf 2 Variablen aufgeteilt sind
1 | Bit 7 6 5 4 3 2 1 0 |
2 | #=====# |
3 | iwr0 +---+---+---+---+---+---+--!+---+! |
4 | | | | | | | | !| |! |
5 | +---+---+---+---+---+---+--!+---+! |
6 | ! ! |
7 | iwr1 +---+---+---+---+---+---+--!+---+! |
8 | | | | | | | | !| |! |
9 | +---+---+---+---+---+---+--!+---+! |
10 | ! ! |
11 | key_state +---+---+---+---+---+---+--!+---+! |
12 | | | | | | | | !| |! |
13 | +---+---+---+---+---+---+--!+---+! |
14 | ! ! |
15 | key_press +---+---+---+---+---+---+--!+---+! |
16 | | | | | | | | !| |! |
17 | +---+---+---+---+---+---+--!+---+! |
18 | ! ! |
19 | key_old +---+---+---+---+---+---+--!+---+! |
20 | | | | | | | | !| |! |
21 | +---+---+---+---+---+---+--!+---+! |
22 | #=====# |
23 | |
24 | ^ diese Bits sind für die Taste 0 |
25 | zuständig. iwr0 und iwr1 |
26 | bilden gemeinsam einen 2 Bit Zähler |
In den beiden 8 Bit Werten sind also 8 Stück 2 Bit Zähler "versteckt". Und der Code in der ISR realisiert das zählen in diesen 2-Bit Zählern. Und zwar alle 8 gleichzeitig parallel. > Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit > Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich > als Flipflops denken, die mit der Entprellzeit als Takt arbeiten. Konzentrier dich auf eine Bitposition, zb das Bit 0 und verfolge, wie es sich durch die Anweisungen verändert. In allen Registern ist für eine bestimmte Taste immer nur 1 Bit interessant. Zb ist für die Taste am Pin 3 eines Ports auch immer nur das Bit 3 in allen Registern interessant. Und nein. Ich werd mich im weiteren raushalten. Der Code ist tricky, solange man ihn nicht komplett verstanden hat. Ich denke, ich bin recht gut im Analysieren von fremden Code. Aber bis ich eine ganz gute Vorstellung hatte, was da abgeht, hab ich auch 20 Minuten gebraucht. Für einen Lernenden ist dieser Code sowieso nichts. So wie ich dich einschätze fehlen dir da noch mindestens 10000 Lines of selbst programmierten Code, bis du die Übung hast, um das in allen Feinheiten zu verstehen. Das soll dich aber nicht abhalten, ihn zu verwenden. Dazu funktioniert er zu gut.
:
Bearbeitet durch User
Karl Heinz schrieb: > Aber bis ich eine ganz gute > Vorstellung hatte, was da abgeht, hab ich auch 20 Minuten gebraucht. Für > einen Lernenden ist dieser Code sowieso nichts. > Vielen Dank, das motiviert zwar nicht, aber Du hast Dir ja mühe gegeben. Ich analysiere gerade den orginal Code mit hilfe des Logikplans ( siehe Anhang ). Ich bin mir nämlich gar nicht sicher, ob dieser Code überhaupt den Entprellzähler enthält. Beim orginal Code habe ich bisher den 2-Bit Abwärtszähler herauskristallisiert ( IC3A, IC4A, IC5A, IC7A, IC14A und IC15A ) was den folgenden ASM-Befehlen entsprechen dürfte : AND key_ct0, iwr0 AND key_ct1, iwr0 COM key_ct0 EOR key_ct1, key_ct0 Und in diesem Program finde ich das nicht wieder, deshalb vermute ich das dieser Zähler hier gar nicht vorhanden ist, da in der Quelle zu lesen ist, das die IRQ alle 24ms aufgerufen wird. Wobei wohl davon ausgegangen wird, das das Prellen dann auf alle Fälle beendet ist. http://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29
1 | .org OVF0addr ;timer interrupt 24ms |
2 | in save_sreg, SREG |
3 | get8key: ;/old state iwr1 iwr0 |
4 | mov iwr0, key_old ;00110011 10101010 00110011 |
5 | in key_old, key_port ;11110000 |
6 | eor iwr0, key_old ; 11000011 |
7 | com key_old ;00001111 |
8 | mov iwr1, key_state ; 10101010 |
9 | or key_state, iwr0 ; 11101011 |
10 | and iwr0, key_old ; 00000011 |
11 | eor key_state, iwr0 ; 11101000 |
12 | and iwr1, iwr0 ; 00000010 |
13 | or key_press, iwr1 ;store key press detect |
14 | ; |
15 | ; insert other timer functions here |
16 | ; |
17 | out SREG, save_sreg |
18 | reti |
Ach, Quelle orginal Code : Beitrag "Re: Tasten entprellen - Bulletproof" Bernd_Stein
:
Bearbeitet durch User
Bernd Stein schrieb: > Und in diesem Program finde ich das nicht wieder, deshalb vermute ich > das dieser Zähler hier gar nicht vorhanden ist Das stimmt. Der Assemblercode entspricht funktional nicht dem C-Code. Er vergleicht nur 2 Samples und nicht 4.
Peter D. schrieb: > Das stimmt. Der Assemblercode entspricht funktional nicht dem C-Code. Er > vergleicht nur 2 Samples und nicht 4. > Das mit den 4 Abtastungen ist mir wichtig, deshalb habe ich den AVR8ASM-Code leicht abgeändert, für dass bessere Nachvollziehens meinerseits. Meine Zusammenfassung wäre, dass 4 gleiche Zustände hintereinander nötig sind, um als gültiges Drücken oder Loslassen, erkannt zu werden. iwr0 und key_state müssen 1 sein, sowie der Zählerstand 0b11 bzw. 3, um key_press gesetzt zu bekommen und um key_state toggeln zu können. Wobei key_press = 1, erneutes Drücken bedeutet und key_state, ist der entprellte, invertierte Tastenzustand. Taster gedrückt = 0 -> key_state = 1. Taster losgelassen = 1 -> key_state = 0. Damit eine bereits vor dem Einschalten bzw. RESET, gedrückte Taste ignoriert wird, sollte/kann key_state mit $FF initialisiert werden. Zudem sollten key_ct0 und key_ct1, ebenfalls mit $FF initialisiert werden, damit eine bereits vor dem Einschalten bzw. vor einem RESET, gedrückte Taste, nicht unentprellt, sofort wirksam wird. Der Code in der ISR braucht nur 12 CPU-Takte und 4 untere Register ( <r16 ). Eine fallende Flanke ( Tater gedrückt bzw. Tastenpegel von 1 -> 0 ), läßt den 4-Bit-Abwärtszähler mit 0b10 bzw. bei 2 starten, 1, 0, und beim Überlauf auf 0b11 bzw. 3, wird key_state = 1 und key_press ebenfalls. Eine steigende Flanke ( Taste losgelassen bzw. Tastenpegel von 0 -> 1 ), setzt den Zählerstand auf 0b11 bzw. 3, es sei denn, key_state ist zu diesem Zeitpunkt = 1, dann wird der Zählerstand auf 0b10 bzw. 2 gesetzt und beginnt dann herunter zu zählen ( 1, 0, 3 ), was aber nichts an den 4 Abtastungen ändert ( 2, 1, 0, 3 ).
1 | ; |
2 | ;Stapelzeiger initialisieren (fuer Unterprogramme und / oder Interrupts) |
3 | ;Ist beim ATmega 2560 bereits auf $21FF eingestellt |
4 | ; |
5 | _reset: |
6 | ;ldi a,High(RAMEND) ;RAMEND, also das Ende vom SRAM, ist in der.. |
7 | ;out SPH,a ;..Definitions-datei festgelegt |
8 | ;ldi a,Low (RAMEND) |
9 | ;out SPL,a |
10 | |
11 | ; |
12 | ;Arbeitsregister (r0 bis r31 ) haben nach dem RESET einen unbestimmten Inhalt |
13 | ; |
14 | clr key_state ;Variable loeschen |
15 | clr key_press ;Variable loeschen |
16 | clr key_ct0 ;key_ct0 & key_ct1 sind nicht direkt ladbar ( < r16 ) |
17 | dec key_ct0 ;Verhindern dass ein bereits gedrueckter Taster nach.. |
18 | mov key_ct1, key_ct0 ;..einem RESET nicht entprellt durchkommt. |
19 | |
20 | ;------------------------------------------------------------------------------- |
21 | ;------------------------------------------------------------------------------- |
22 | ; Hauptprogrammschleife |
23 | ;------------------------------------------------------------------------------- |
24 | ;------------------------------------------------------------------------------- |
25 | _main: |
26 | |
27 | clr key_press ;clear, if key press action done |
28 | ; |
29 | ; Replace with your application code |
30 | ; |
31 | rjmp _main ;Endlosschleife |
32 | |
33 | ; |
34 | ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ |
35 | ;Q Timer0 Overflow ISR ( Interrupt Service Routine ) |
36 | ;QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ |
37 | ; |
38 | _OVF0addr: |
39 | in s_sreg, SREG ;Statusregister retten |
40 | |
41 | ; |
42 | ;Tasterverarbeitung nach PeDa ( Peter Dannegger ) |
43 | ; |
44 | _get8key: |
45 | in iwr0, KEY_PIN ;Tasterzustand einlesen |
46 | com iwr0 ;low active |
47 | eor iwr0, key_state |
48 | and key_ct0, iwr0 ;reset counter |
49 | com key_ct0 ;count |
50 | and key_ct1, iwr0 |
51 | eor key_ct1, key_ct0 |
52 | and iwr0, key_ct0 ;input AND last counterstate |
53 | and iwr0, key_ct1 |
54 | eor key_state, iwr0 ;toggle state |
55 | and iwr0, key_state ;0-1-transition |
56 | or key_press, iwr0 ;store key press detect |
57 | |
58 | out SREG,s_sreg ;Statusregister wiederherstellen |
59 | reti ;Ruecksprung aus _OVF0addr Interrupt Service Routine |
Bernd_Stein
Beitrag #7387776 wurde vom Autor gelöscht.
Beitrag #7387782 wurde von einem Moderator gelöscht.
Beitrag #7387789 wurde von einem Moderator gelöscht.
Beitrag #7387792 wurde von einem Moderator gelöscht.
Direkt im Eröffnungspost wurde 2014 kritisiert, dass Peter Dannegger nur noch in C schreibt und es soll hier nicht um die Programmiersprache gehen…wer hat hier etwas nicht verstanden ;)
Beitrag #7387796 wurde von einem Moderator gelöscht.
Beitrag #7388084 wurde von einem Moderator gelöscht.
um wieviel schneller oder kompakter (Anzahl bytes) ist denn die Assembler-Routine gegenüber der (kompilierten) C-Implementierung?
:
Bearbeitet durch User
Wegstaben V. schrieb: > um wieviel schneller oder kompakter (Anzahl bytes) ist denn die > Assembler-Routine gegenüber der (kompilierten) C-Implementierung? Wahrscheinlich um genau Null in beiden Fällen. In diesem Fall ist C vielleicht sogar besser als ASM, weil der C-compiler etliche Tricks kennt, gerade für solche Fälle.
Wegstaben V. schrieb: > um wieviel schneller oder kompakter (Anzahl bytes) ist denn die > Assembler-Routine gegenüber der (kompilierten) C-Implementierung? Grade in solchen Fällen ist die C-Implementierung von PeDa genauso gut da die Compiler inzwischen erheblich besser geworden sind als sie es vor 30 Jahren waren.
Beitrag #7388336 wurde von einem Moderator gelöscht.
Beitrag #7388371 wurde von einem Moderator gelöscht.
Beitrag #7388390 wurde von einem Moderator gelöscht.
Marc V. schrieb im Beitrag #7388084: > Und Tasterprellen ist damit auch gelöst, ohne EOR, AND, COM und > solchen unnützen Blödsinn. Schade, Du hast das vertical counter Prinzip in keinster Weise verstanden. Die Statements sind alle sauschnell, so daß weiteres Rumoptimieren unnötig ist. Der eigentliche Clou ist jedoch, daß beide Flanken entprellt werden und somit die Lib besonders störfest ist. Im Gegensatz zu den meisten Libs, die nur einen Zustand abzählen.
Peter D. schrieb: > Marc V. schrieb im Beitrag #7388084: >> Und Tasterprellen ist damit auch gelöst, ohne EOR, AND, COM und >> solchen unnützen Blödsinn. > > Schade, Du hast das vertical counter Prinzip in keinster Weise > verstanden. Sagt wer? > Die Statements sind alle sauschnell, so daß weiteres Rumoptimieren > unnötig ist. Das stimmt. > Der eigentliche Clou ist jedoch, daß beide Flanken entprellt werden und > somit die Lib besonders störfest ist. Im Gegensatz zu den meisten Libs, > die nur einen Zustand abzählen. Prellen beim loslassen ist bei meinem Vorschlag uninteressant, da dies nie registriert wird. Prellen beim drücken wird 100% eliminiert. Und das wichtigste: a) Man kann immer feststellen, welcher Taster zuerst gedrückt wurde. b) Man hat ohne zusätzlichen Aufwand eine "repeat key" funktion.
Beitrag #7388603 wurde von einem Moderator gelöscht.
M. K. schrieb: > Wegstaben V. schrieb: >> um wieviel schneller oder kompakter (Anzahl bytes) ist denn die >> Assembler-Routine gegenüber der (kompilierten) C-Implementierung? > > Grade in solchen Fällen ist die C-Implementierung von PeDa genauso gut > da die Compiler inzwischen erheblich besser geworden sind als sie es vor > 30 Jahren waren. > Oh, dass passt ja. Alle die vom ATMEL STUDIO 7 C-Compiler Ahnung haben, möchte ich zu diesem Thread einladen : Beitrag "Mit dem ATMEL STUDIO 7 klarkommen : Highlighting und C-Compiler ASM-Code" Bernd_Stein
Wegstaben V. schrieb im Beitrag #7388371: > Wenn es jedoch einen gut durchdachten Algorithmus in C gibt, und gut > funktionierende Compiler von C nach AVR-Assembler, dann wäre es unter > Umständen mal interessant, einen Blick auf das Compilat zu werfen. > > Vielleicht findet dann ja der geneigte Assembler-Liebhaber noch > Verbesserungs-Potential in dem übersetzten Teil. Er kann sich dann > darauf konzentrieren, gutes noch besser zu machen. Das ist ziemlich einfach zu schaffen. C-Compiler sind semmeldumm, wenn sie mit parallelem oder quasi-parallelem Code hantieren müssen, beim AVR8 insbesondere halt mit Code in ISRs (und viel von PeDas Code passiert typisch in einer Timer-ISR). Und der Trick ist einfach: das Gesamtwerk NICHT in C verfassen und so die Einschränkungen des semmeldummen Compilers komplett zu umgehen. Dann stehen einem etliche Freiheitsgrade mehr zur Optimierung zur Verfügung, gerade auch im Bezug auf die effiziente Umsetzung von ISRs (aber beileibe nicht beschränkt darauf). Siehe z.B.: Beitrag "Audio Spektrum Analyzer mit ATtiny85" Beitrag "Westminster Soundgenerator mit ATtiny85" In Jahrzehnten der Existenz des avr-gcc ist es keinem der C-Fetischisten gelungen, das (oder etwas vergleichbar Anspruchsvolles) umzusetzen, obwohl es durchaus etliche Anfragen und Wünsche nach solchen Lösungen gab. Bei größeren und komplexeren Architekturen als AVR8 wird es natürlich schwieriger, besser als die C-Compiler zu sein, zumal man hier eher nicht komplett auf C verzichten möchte, da das den Aufwand doch etwas über Gebühr in die Höhe treiben würde. Es bleibt aber möglich und wird auch oft gemacht. Siehe z.B. MP3-Decoder auf einem RaspiPico/RP2040. In plain stupid C fast unmöglich (jedenfalls für alle MP3-Bitraten), aber mit Rechenkernen in optimierten Assembler wird es machbar, sogar in der suboptimalen C-Umgebung. Kapiere es einfach endlich: Das letzte aus einem Chip rausholen, wird immer nur in seiner nativen Sprache möglich sein. Jede Abstraktion (auch die eher Schwache, die C bietet) birgt nunmal auch den Ansatz der Suboptimalität in sich.
C-hater schrieb: > Das letzte aus einem Chip rausholen, wird > immer nur in seiner nativen Sprache möglich sein. Jede Abstraktion (auch > die eher Schwache, die C bietet) birgt nunmal auch den Ansatz der > Suboptimalität in sich. Das hat ja auch nie jemand ernsthaft bestritten. Was diskutabel ist, ist die Praxisrelevanz solcher aufs letzte Bit ausgereizter Anwendungen. Manch einer nimmt dafür einfach einen größeren Prozessor, und hat bezüglich der Software andere Prioritäten. Oliver
Oliver S. schrieb: > Was diskutabel ist, ist > die Praxisrelevanz solcher aufs letzte Bit ausgereizter Anwendungen. > Manch einer nimmt dafür einfach einen größeren Prozessor, und hat > bezüglich der Software andere Prioritäten. Das ist sicherlich richtig. Aber auch denn gilt immer: mit Asm an den richtigen Stellen kann man noch mehr rausholen. Klar, das kann man mit einer noch größeren, noch teureren und noch stromfressenderen MCU beantworten. Usw. usf. Genau das ist, was seit Jahrzehnten passiert. Jeder Fortschritt der Leistungsfähigkeit der Hardware wird durch noch mehr Abstraktionsebenen bei der Software umgehend wieder aufgefressen. Muss man das gut finden? Ich jedenfalls finde das nicht gut.
Beitrag #7388870 wurde von einem Moderator gelöscht.
Hallo, C-hater schrieb: > C-Compiler sind semmeldumm, wenn sie mit parallelem oder > quasi-parallelem Code hantieren müssen, beim AVR8 insbesondere > halt mit Code in ISRs (und viel von PeDas Code passiert typisch > in einer Timer-ISR). Ich verstehe den Zusammenhang nicht. Kannst du mal an einem ein Beispiel zeigen was du genau meinst? > Und der Trick ist einfach: das Gesamtwerk NICHT in C verfassen und so > die Einschränkungen des semmeldummen Compilers komplett zu umgehen. Was ist dann die Alternative zu C wenn man Maschinensprache mal außenvor lässt? rhf
:
Bearbeitet durch User
Roland F. schrieb: > Was ist dann die Alternative zu C wenn man Maschinensprache mal außenvor > lässt? Dann genau keine. Maschinensprache/Assembler ist die einzige Alternative. Andere Hochsprachen (Basic, Pascal etc.) oder gar Skriptsprachen (Python, Lua etc.) fallen sowieso raus.
Harald K. schrieb: > Roland F. schrieb: >> Was ist dann die Alternative zu C wenn man Maschinensprache mal außenvor >> lässt? > > Dann genau keine. Maschinensprache/Assembler ist die einzige > Alternative. Andere Hochsprachen (Basic, Pascal etc.) oder gar > Skriptsprachen (Python, Lua etc.) fallen sowieso raus. wir reden hier aber von simplen Bits ein und aus schalten oder abfragen, stimmts? Komplexere mathematische Aufgabenstellungen wie FFT, Matrixtransformation oder Sortieralgorithmen, oder auch "einfache" Dinge wie eine Tastaturmatrix Abfrage oder Segmentanzeigen-Multiplex schüttelst du dir vermutlich auch nicht ohne irgendeine Vorlage mal eben so aus dem Assembler-Ärmel ....
Wegstaben V. schrieb: > Komplexere mathematische Aufgabenstellungen wie FFT, > Matrixtransformation oder Sortieralgorithmen, oder auch "einfache" Dinge > wie eine Tastaturmatrix Abfrage oder Segmentanzeigen-Multiplex > schüttelst du dir vermutlich auch nicht ohne irgendeine Vorlage mal eben > so aus dem Assembler-Ärmel .... Das ist nur eine Frage der Gewohnheit. Vorausgesetzt, man versteht den umzusetzenden Algorithmus und beherrscht beide Sprachen, ist es nicht schwerer, den in Assembler umzusetzen als in C. Es dauert nur länger. Und zwar meist nicht nur deshalb, weil man mehr tippen muss (das ist leider fast unvermeidbar so), sondern vor allem auch, weil man über mehr Sachen nachdenken muss, die mit dem Algorithmus selber eigentlich nichts zu tun haben. Aber genau dieses Nachdenken ist, was letztlich der Effizienz des Codes in der geplanten Zielumgebung gut tut... Ja, es kommt sogar recht häufig vor, dass erst dieses Nachdenken zur Wahl eines für die Aufgabe auf dem geplanten Target wirklich geeigneten Algorithmus führt. Weil man schon direkt beim Programmieren immer im Blick hat: schafft das Target das eigentlich? Dieser Überblick ist in C viel schwerer zu erhalten...
Beitrag #7389227 wurde von einem Moderator gelöscht.
Beitrag #7389232 wurde von einem Moderator gelöscht.
Beitrag #7389237 wurde von einem Moderator gelöscht.
Hallo, Harald K. schrieb: > ...oder gar Skriptsprachen (Python, Lua etc.) fallen > sowieso raus. Da hast du recht, aber gerade die Script/Interpretersprache BASIC hat nicht unwesentlich zum Siegeszug der Homecomputer beigetragen (und damit wurden durchaus brauchbare Programme erstellt). rhf
C-hater schrieb: > ist es nicht > schwerer, den in Assembler umzusetzen als in C. Jetzt klingt unser "C-Hater" exakt so wie unser beliebter "Moby". Nur auf das Zwinker-Smiley verzichtet er. Noch.
Auch sehr interessant, falls man nur 4 Taster benötigt und auch zusätzlich eine losgelassen-Funktion haben will. Manchmal möchte man ja etwas erst starten lassen, wenn der Taster logelassen wird. Beitrag "Re: Tasten entprellen - Bulletproof" Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > ... > Beim orginal Code habe ich bisher den 2-Bit Abwärtszähler > herauskristallisiert ( IC3A, IC4A, IC5A, IC7A, IC14A und IC15A ) was den > folgenden ASM-Befehlen entsprechen dürfte : > Beitrag "Re: Universelle Tastenabfrage nach PeDa in AVR Assembler" Dies stimmt leider nicht so ganz. Der unterste Link half mir zum besseren Verständnis. Es war erstaunlich zu entdecken, dass die Programmierreihenfolge, darüber entscheidet, ob es ein Vertikal 2-Bit, Ab,- oder Aufwärtszähler wird. Der Vertikal-Zähler enthält also nur die Bausteine IC5A und IC7A, also die folgenden beiden Befehle. Abwärtszähler: AVR8ASM
1 | com key_ct0 |
2 | eor key_ct1, key_ct0 |
Aufwärtszähler:
1 | eor key_ct1, key_ct0 |
2 | com key_ct0 |
https://www.compuphase.com/electronics/debouncing.htm Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Auch sehr interessant, falls man nur 4 Taster benötigt und auch > zusätzlich eine losgelassen-Funktion haben will. Manchmal möchte man ja > etwas erst starten lassen, wenn der Taster logelassen wird. > Was muss man an diesem Code verändern, damit nach einem Reset oder dem Einschalten, kein losgelassener Taster dedektiert wird (siehe Anhang ). Sondern erst, wenn dieser zuvor gedrückt wurde. Quelle : Beitrag "Re: Tasten entprellen - Bulletproof" Bernd_Stein
Bernd S. schrieb: > Was muss man an diesem Code verändern, damit nach einem Reset oder dem > Einschalten, kein losgelassener Taster dedektiert wird (siehe Anhang ). > Sondern erst, wenn dieser zuvor gedrückt wurde. Man muss ein paar Dutzend Millisekunden warten und dann die Tasten auslesen und das Ergebnis ignorieren.
Hatte den Anhang vergessen. Bernd_Stein
Bernd S. schrieb: > Was muss man an diesem Code verändern, damit nach einem Reset oder dem > Einschalten, kein losgelassener Taster dedektiert wird (siehe Anhang ). > Sondern erst, wenn dieser zuvor gedrückt wurde. > Beitrag "Re: Tasten entprellen - Bulletproof" Natürlich wieder ein Kardinalfehler meinerseits. Der Simulator setzt natürlich zu beginn Variablen bzw. GPR = 0 ( General purpose register ). Aber eben nicht nach einem Reset, was übrigens der echte µC auch nicht tut. Man sollte also GPR dementsprechend auch initialisieren. Und ganz hilfreich ist es auch, auf den Simulator zu warten bis dieser fertig ist ( siehe unterste Zeile => Ready / Stop ). Warum mal Ready und mal Stop steht, ist mir noch ein Rätsel. Der Code läuft ja .. : Hannes L. schrieb: > Im vorliegenden Fall läuft die Routine auch nicht im Interrupt, sondern > als Job der Mainloop, durch Timer und Jobflag synchronisiert. > ... > wobei ich nicht verstehe, wie die Synchronisation durch Timer und Jobflag funktioniert. Leider kann der olle Brummbär dies auch nicht mehr erklären, aber vieleicht hier jemand. http://www.hanneslux.de/index2.html Der Code zum Durchtesten als Anhang. Bernd_Stein
Universelle Tastenabfrage nach PeDa in AVR Assembler : Losgelassener Taster Hannes Lux Taktoptimiert
Wenn man in Hannes Lux seinem Programm ein weiteres GPR einsetzt, kann man noch 3 Takte rauskitzeln. Für PUSH ein MOV weiteres_Register, tmp. POP natürlich weg und ab praktisch dem EOR tas, weiteres_Register, das tmp hierfür austauschen. Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Wenn man in Hannes Lux seinem Programm ein weiteres GPR einsetzt, > kann man noch 3 Takte rauskitzeln. micro-optimization at the worst. Hört doch auf, die CPU im ppm-Bereich zu optimieren. Es bringt absolut nichts. Optimieren kann man Tasks vielleicht ab 10% CPU-Auslastung. Darunter ist es einfach nur lächerlich.
Bernd S. schrieb: > kann man noch 3 Takte rauskitzeln. Völlig unnötiger Aufwand. Denn sogar 160 Takte brauchen auf dem AVR bei 16 MHz nur 10µs. Und wenn die ISR alle 10ms aufgerufen wird, dann würde das komplette Weglassen dieser Funktion gerade mal 0,1% der Rechenleistung einsparen. Oder konkret zu den heroisch eingesparten 3 Maschninenzyklen: die brauchen beim Aufruf in einer 10ms-ISR grade mal 0,002% der Rechenleistung. Wenn es darauf auch nur ansatzweise ankommen würde, dann wäre der Controller sowieso völlig unterdimensioniert und mit der nächsten eingegebenen Codezeile eh' überlastet. Eine einzige irgendwo im Programm falsch gewählte Operandengröße (int oder gar float statt eines simplen char) kostet da wesentlich mehr Rechenleistung.
:
Bearbeitet durch Moderator
Bernd S. schrieb: > Hannes L. schrieb: >> Im vorliegenden Fall läuft die Routine auch nicht im Interrupt, sondern >> als Job der Mainloop, durch Timer und Jobflag synchronisiert. >> ... >> > > wobei ich nicht verstehe, wie die Synchronisation durch Timer und > Jobflag funktioniert. Leider kann der olle Brummbär dies auch nicht mehr > erklären, aber vieleicht hier jemand. > Könnte mir dies mal einer anhand eines AVR8ASM-Codes erklären und einfach meine Erbsenzählerei akzeptieren ? Bernd_Stein
Bernd S. schrieb: > Könnte mir dies mal einer ..... meine Erbsenzählerei akzeptieren ? nö es wird langsam langweilig und artet immer mehr in Selbstgespräche aus, alles Wichtige wurde geschrieben! Peter D. schrieb: > Hört doch auf, die CPU im ppm-Bereich zu optimieren. Es bringt absolut > nichts. > Optimieren kann man Tasks vielleicht ab 10% CPU-Auslastung. Darunter ist > es einfach nur lächerlich. Lothar M. schrieb: > Denn sogar 160 Takte brauchen auf dem AVR bei 16 MHz nur 10µs. Und wenn > die ISR alle 10ms aufgerufen wird, dann würde das komplette Weglassen > dieser Funktion gerade mal 0,1% der Rechenleistung einsparen.
Joachim B. schrieb: > nö es wird langsam langweilig und artet immer mehr in Selbstgespräche > aus, alles Wichtige wurde geschrieben! > Mein Thread, falls es dir nicht aufgefallen ist. Und wenn dir meine "Selbstgespräche" nicht passen und du hier trotzdem deinen Senf dazu gibst, hast du die 5 universellen Forumsregeln nicht beachtet oder verstanden. Und bitte ordentlich zitieren, damit der Zusammenhang bleibt. Bernd S. schrieb: >> >> wobei ich nicht verstehe, wie die Synchronisation durch Timer und >> Jobflag funktioniert. Leider kann der olle Brummbär dies auch nicht mehr >> erklären, aber vieleicht hier jemand. >> >> Könnte mir dies mal einer anhand eines AVR8ASM-Codes erklären und >> einfach meine Erbsenzählerei akzeptieren ? >> Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Und wenn dir meine "Selbstgespräche" nicht passen und du hier trotzdem > deinen Senf dazu gibst, hast du die 5 universellen Forumsregeln nicht > beachtet oder verstanden. Daß diese Forenregeln auch für Dich gelten könnten, ist Dir noch nicht gekommen?
Bernd S. schrieb: > Mein Thread Sicher nicht. Falls dir das nicht aufgefallen ist: du hast den Thread zwar eröffnet, aber mit dem Absenden dieses Posts hast du Andreas "ein einfaches, zeitlich und räumlich unbeschränktes und unentgeltliches Recht" eingeräumt, "den Beitrag im Rahmen des Forums zu nutzen" (Zitate aus den Nutzungsbedingungen). Und die im Rahmen des Forums vorgesehene Nutzung ist eben, dass sich alle daran beteiligen können. Auch mit Ansichten, die einem TO nicht 100% nach dem Strich gehen. > und einfach meine Erbsenzählerei akzeptieren ? Akzeptiert.
:
Bearbeitet durch Moderator
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.