Hallo,
ich bin neu in dem Thema, und möchte erstmal Assembler für
Mikrocontroller lernen.
Ich hab mir meine eigene Platine mit einem Atmega8 gebastelt von der ich
4 Led´s und einen Modellbauservo programmieren könnte. (Bilder im
Anhang)
Die Led´s schaffe ich zu programmieren, mehr aber auch nicht.
Könnt Ihr mir Bücher für dieses Thema empfehlen oder habt Ihr andere
Ideen für mich die mich in dem Thema weiterbringen.
Ich denke für mich ist es gut erstmal alles Grundlegende in Assembler zu
lernen um zu verstehen "Warum".
Danke schonmal.
Gruss Dennis
Dennis schrieb:> Die Led´s schaffe ich zu programmieren, mehr aber auch nicht
Na, das ist doch ein Anfang. Zumindest bist du nicht so behornt wie
manch anderer, der als kleines Anfängerprojekt mal eben einen
Autopiloten für einen Airbus bauen will.
Dennis schrieb:> Könnt Ihr mir Bücher für dieses Thema empfehlen oder habt Ihr andere> Ideen für mich die mich in dem Thema weiterbringen.
Hast du da:
http://www.mikrocontroller.net/articles/AVR-Tutorial
schon reingeguckt?
mfg.
Dennis schrieb:> Könnt Ihr mir Bücher für dieses Thema empfehlen oder habt Ihr andere> Ideen für mich die mich in dem Thema weiterbringen.
Ich habe 2000 mit den Klassik-AVR damit angefangen:
http://www.amazon.de/AVR-Mikrocontroller-Praxis-m-CD-ROM-Safinaz-Volpe/dp/3895760633/ref=sr_1_2?ie=UTF8&qid=1367614697&sr=8-2&keywords=avr-mikrocontroller+praxis
Mega AVRs gab es damals noch nicht, aber der Mega8 ist ja auch schon
sehr veraltet. Ich finde dieses Buch für den Assembler-Einsteiger recht
gut.
Die Hälfte des Buches besteht allerdings aus einer Referenz zum
Befehlssatz in deutsch.
Aber für den Anfang ist das auch nicht schlecht.
Übrigens - Bilder mit 3,8MB schaue ich mit meiner langsamen
Internetverbindung nicht an!
egbert schrieb:> GENIAL!>> 6,5 MB für zwei vollkommen aussagefreie Bilder!>> TAGESREKORD!!!
Kein Wunder, daß die Telekom die Bandbreite drosseln will, wenn
vollkommen ohne Nachdenken riesen Datenmengen hoch- und
runtergeschaufelt werden.
Dennis schrieb:> (Bilder im Anhang)
Nichts gegen Bilder mit 6,5MByte, wenn sie nötig und brauchbar sind.
Aber wenn du so ein Bild ohne jeglichen Informationsverlust um den
Faktor 20 reduzieren kannst, dann werden es dir Hilfewillige danken,
denn nicht jeder hängt an einer hochpotenten DSL-Strippe...
Dennis schrieb:> möchte erstmal Assembler für Mikrocontroller lernen.> Die Led´s schaffe ich zu programmieren, mehr aber auch nicht.
Also gut, das bedeutet also, dass du noch ein wenig mit diesen LEDs und
einem Taster herumspielen kannst (Lauflicht, mitverstellbarer
Geschwindigkeit, programmierbar). Danach siehst du dir mal die serielle
Schnittstelle an, dann steuerst du ein LCDisplay an, dann das Servo
(erst mit delay, dann mit Timer). Also einfach Schritt für Schritt
weitermachen.
Hier gilt: der Appetit kommt mit dem Essen... ;-)
Dennis schrieb:> oder habt Ihr andere Ideen für mich die mich in dem Thema weiterbringen.
Das Internet wäre eine weitere Anlaufstelle. Alleine über die Suche hier
im Forum finden sich fast 2000 Threads, die sich mit Servoansteuerung
beschäftigen. Da sind auch viele Erklärungen zur Erzeugung der Pulse mit
einem Timer und Beispielcode in AVR Assembler bei.
asm schrieb:> Die Hälfte des Buches besteht allerdings aus einer Referenz zum> Befehlssatz in deutsch.
Diesen Satz ließt man auch sehr häufig unter Buch Kritiken. Ja wovon
soll da sonst was stehen? Es ist doch nun mal der Befehlssatz den du
brauchst.
Es kommt nur drauf an wie gut jemand diesen Befehlssatz und die Sprache
rüber bringen kann.
Hab mir hier ein Buch gekauft, von Schwabl-Schmidt, das kann ich nicht
mal lesen. Sicher, das ist so ein Guru und wahrscheinlich hat er
Assembler noch vor der Muttersprache gelernt. Mir wird das Buch
(vielleicht auch seine anderen nachfolgenden) erst in ein paar Jahren
etwas nützen.
Am besten finde ich im Moment noch das "Instruction Set" von AVR selbst.
Spess53 wies da schon weiter oben drauf hin.
Außer die Blätter (ich würde das immer ausdrucken) ist es zudem noch
kostenlos.
ich hatte mir auch ein Buch von Amazon zugelegt.
Mikrocomputertechnik mit Controllern der Atmel AVR-Risc-Familie
5.Auflage von Günter Schmitt
oldenburg.de (ISBN 978-3-486-58988-7)
Speziell für Mega8
Spess hat natürlich Recht, das Instructions Set von AVR ist nicht
zu übertreffen.
Grüße
Rolf
Hi
>für alle die sich auch dafür interessieren kann ich das hier empfehlen :>http://www.weigu.lu/a/index.html
Nett, 'F1 Assembleranweisungen', PDF mit 2 A4 Seiten fast 27MB. Und
nicht mal für AVR-Assembler2.
MfG Spess
Spess schrieb:
>Nett
Richtig. Das ist nett, es ist nämlich in deutscher Sprache verfasst.
>'F1 Assembleranweisungen', PDF mit 2 A4 Seiten fast 27MB.
Ich schlage vor, die richtigen Dateien herunterzuladen. Allein der
1. Teil hat schon 110 Seiten...
-Sherlock Holmes sein Schwager-
Hi
>Ich schlage vor, die richtigen Dateien herunterzuladen. Allein der>1. Teil hat schon 110 Seiten...
Welcher 1.Teil? 'F1 Assembleranweisungen' beinhaltet die 'Assembler
directives' der Assembler Hilfe des AVR Studios. Und das sind nur 24
Anweisungen die kaum 110 Seiten beanspruchen.
MfG Spess
>Welcher 1.Teil?
Preisfrage: Wieviele erste Teile kann es geben?
Du hast auch schon intelligentere Fragen gestellt und wesentlich bessere
Antworten gegeben als im Moment hier...
-Sherlock Holmes sein Schwager-
Dennis schrieb:> Die Led´s schaffe ich zu programmieren
Den Code hast du sicher mehr oder weniger irgendwoher kopiert, ohne ihn
wirklich zu verstehen. Das ist durchaus was anderes als es "schaffen zu
programmieren".
> mehr aber auch nicht.
Tja, mühsam ernährt sich das Eichhörnchen. Man muß leider immer ganz
unten anfangen. Das beginnt bei JEDER Sprache damit, daß man erstmal die
verfügbaren Sprachmittel kennenlernt. Die Referenz für AVR-Assembler
hast du ja bereits mehrfach im Thread genannt bekommen.
Das Blöde ist nur: Die Kenntnis der Sprachmittel ist zwar die
unverzichtbare Grundlage, genügt aber leider nicht, man muß sie dann
auch noch sinnvoll anwenden, um sein Ziel zu erreichen. Leider kann man
gerade das nicht wirklich gelehrt bekommen, sondern nur selber lernen.
Indem man es tut, aus Fehlern lernt, wieder tut, usw...
Der Code anderer Leute ist dabei auch immer gut. Man kann daraus viel
lernen. Manchmal auch, wie man es besser nicht machen sollte. Sowas wird
dir aber frühestens in ein paar Monaten auffallen...
Viel Spaß. Und wenn's am Anfang auch oft nervt, weil nix funktioniert:
Immer daran denken: jeder hat mal so angefangen. Es ist definitiv
möglich, den Scheiß zu beherrschen.
> Könnt Ihr mir Bücher für dieses Thema empfehlen
Fachbücher sind Mist, die kosten nur unnötig Geld und veralten schneller
als das Papier verrotten kann, auf dem sie gedruckt sind.
Das nötige Faktenwissen kannst du den relevanten Referenzdokumenten
entnehmen und das Programmieren an sich kann dir niemand beibringen
außer du dir selbst. Denn das lernt man nur, indem man es tut (bzw. am
Anfang: es zumindest versucht).
Mit der Zeit lernt man es, seine Programmier-Ziele als logisch
konsistente Abstraktion formulieren zu können. Das ist der schöpferische
Teil der Sache. Der Rest, nämlich den Kram dann mit den Mitteln der
verfügbaren Sprache in ein funktionierendes Programm zu verwandeln, ist
dann nur noch Handwerk. Eigentlich nur sowas wie eine Übersetzung.
Außer für die C-ler natürlich. Mit DER Sprache gerät schnell mal dieses
primitive Handwerk zur Kunstform. Aber das ist ein ganz anderes Thema,
was dich ja glücklicherweise (noch) nichts angeht. Das Problem ist nur:
Über kurz oder lang wirst du nicht drumrum kommen, den C-Scheiß
zumindest lesen zu können.
Jedenfalls, wenn du deine Bemühungen, Programmieren zu lernen, nicht
sehr bald aufgibst, weil du auf den Sachverhalt stößt, daß das alles
doch verdammt viel ARBEIT macht, bevor irgendwelche nennenswerten
Erfolge sichtbar werden.
c-hater schrieb:> Außer für die C-ler natürlich. Mit DER Sprache gerät schnell mal dieses> primitive Handwerk zur Kunstform. Aber das ist ein ganz anderes Thema,> was dich ja glücklicherweise (noch) nichts angeht. Das Problem ist nur:> Über kurz oder lang wirst du nicht drumrum kommen, den C-Scheiß> zumindest lesen zu können.
Wie sieht es denn dann mit aktuelleren Hoch- und Skriptsprachen aus?
Python? Lua? Java? C#? Objective-C? Javascript? Ruby?
Ist euch eigentlich aufgefallen, dass Dennis nie wieder geantwortet hat?
Es ist eine gute Idee mit Assembler anzufangen.
Aber ich würde damit auch nicht allzu viel Zeit verschwenden und bald
auf C umsteigen.
BASCOM ist sicher auch OK, wenn es nur darum geht eine Aufgabe schnell
und pragmatisch zu lösen.
Aber wer höher hinaus will, der kommt um C nicht herum.
> Wie sieht es denn dann mit aktuelleren Hoch- und Skriptsprachen aus?> Python? Lua? Java? C#? Objective-C? Javascript? Ruby?
Spielt alles auf der von Dennis gewählten Plattform keine Rolle.
Und auch sonst nicht, wenn es darum geht den uC direkt zu programmieren.
Sobald auf dem uC ein OS läuft sieht das wieder anders aus.
Was immer geht ist C++.
Oder halt solche Insellösungen wie BASCOM.
Sherlock Holmes sein Schwager schrieb:>> Ich schlage vor, die richtigen Dateien herunterzuladen. Allein der> 1. Teil hat schon 110 Seiten...>
Aber nicht von den 110 Seiten abschrecken lassen.
Einfach mal anfangen sich die Sache durchzulesen, dann merkt man relativ
schnell, ob einem der Kurs zusagt oder nicht. Ich bin jedenfalls froh,
das es so etwas kostenfrei gibt. Denn da steckt ganz ganz viel Mühe
hinter.
http://www.weigu.lu/a/pdf/MICEL_MODUL_A.pdf
Bernd_Stein
Bernd S. schrieb:
Läuft gerade ein Wettbewerb, in dem es irgendwie darum geht, möglichst
alte Threads wiederzubeleben?
Dann hast du verloren. Die Leiche, die du ausgebuddelt hast, stinkt
noch. Gerade mal vier Jahre unter der Erde...
c-hater schrieb:> Dann hast du verloren. Die Leiche, die du ausgebuddelt hast, stinkt> noch. Gerade mal vier Jahre unter der Erde...
... was die beiden Links nicht weniger interessant macht. Danke Bernd
Stein!
Rolf H. schrieb:> Spess hat natürlich Recht, das Instructions Set von AVR ist nicht> zu übertreffen.
Das sehe ich etwas anders, zumindest in einem, allerdings nicht ganz
unwichtigen Punkt dürfte das "Original" sehr leicht zu übertreffen sein:
nämlich bei der Darstellung der Verzweigungen.
Man braucht z.B. als Einsteiger doch eine ganze Weile, ehe man dahinter
kommt, dass es fast die Hälfte davon garnicht wirklich gibt...
Ansonsten aber volle Zustimmung, selten habe ich eine so kurz-prägnante
und dabei doch leicht verständliche Beschreibung eines µC-Befehlssatzes
gelesen.
Liegt natürlich durchaus auch daran, dass der Befehlssatz selber einfach
ziemlich gut durchdacht ist. Es gibt eigentlich nur sehr wenig, was sich
daran verbessern ließe. Meine persönlichen Favoriten für nachzurüstende
Instruktionen sind "eori", "cpci" und "cpsne", dafür könnte man ganz gut
auf "adiw" und "sbiw" verzichten, ganz sicher aber zumindest darauf,
dass sie sich auch auf R25:R24 anwenden lassen.
Bernd S. schrieb:> wundere mich das rjmp -1 im Atmel Studio 7 nicht> funktioniert.
Das funktioniert schon, macht aber was völlig anderes als du glaubst,
was es machen müsste. Um das zu erreichen, was du willst, musst du das
so schreiben:
rjmp PC-1
oder auch so
endless:
rjmp endless
c-hater schrieb:> rjmp PC>> Wäre richtig gewesen.>
Nicht wäre. I S T !
Ist schon blöd, wenn sich Tutoren irren. Rjmp -1 würde ja auf den Befehl
davor zeigen und nicht auf sich selbst.
Der Simulator ist leider wieder nicht kooperativ. Stürzt bei dieser
Variante ab. Ausserdem zeigt der Disassembler für diesen Befehl PC +
$01F3 die .lss-Datei jedoch $C1F2.
Bernd_Stein
Arduino Fanboy D. schrieb:> Mein Disassembler sagt:> rjmp .-2> Für einen Sprung auf sich selbst.>
Tja, ist halt Arduino. Warum der erste Befehl rjmp _reset wohl nur ein
Takt benötigt kriegt so ein Arduino Fanboy wohl auch nicht erklärt oder
?
Tag3 bringt die Lösung, aber passt halt nicht mit dem Simulator.
" anhalten durch Sprung auf sich selbst: rjmp -1 ; 1100 1111 1111 1111
"
Bernd_Stein
Bernd S. schrieb:> Tja, ist halt Arduino.
Was hat Arduino damit zu tun?
1
1aa:ffcfrjmp.-2;0x1aa<main+0x86>
Bernd S. schrieb:> Warum der erste Befehl rjmp _reset wohl nur ein> Takt benötigt kriegt so ein Arduino Fanboy wohl auch nicht erklärt oder> ?
Nö, das ist mir tatsächlich neu!
Dann, bitte, erkläre es mir!
Arduino Fanboy D. schrieb:> Nö, das ist mir neu!> Dann, bitte, erkläre es mir!>
OK.
" Der erste Befehl eines Programms hat eine um einen Taktzyklus längere
Ausführungszeit als der gleiche Befehl an anderer Stelle des Programms,
da hier der Instruction Fetch nicht parallel zur Ausführung des
vorhergehenden vorgenommen werden kann. "
Das ist aus dem Buch von Wolfgang Trampert Seite 15 des Buches AVR-RISC
Mikrocontroller und zeigt wieder einmal, das man dem Simulator nicht
wirklich zu 100% vertrauen darf.
Im Flashspeicher ist die Sache auch nicht richtig abgebildet ( $FFF ).
Was soll der Punkt bei rjmp .-2 ?
-2 müsste jedoch $FFE sein, deswegen Arduino.
Bernd_Stein
Stefanus F. schrieb:> Warum rechnet ihr überhaupt? Lasst das doch den Assembler erledigen,> dazu ist er da:>
Was steht mit in der Threadüberschrift ? Richtig - lernen ;-)
Bernd_Stein
Bernd S. schrieb:> Was soll der Punkt bei rjmp .-2 ?>> -2 müsste jedoch $FFE sein, deswegen Arduino.
Der Punkt ist gleichzusetzen mit PC oder auch manchmal $.
Wobei, wenn ich mich richtig erinnere, dies auch nicht bei allen
Compilern gleich behandelt wird, da bei manchen der PC immer noch
auf rjmp zeigt und erst bei nächstem Befehl (welches nicht existiert,
bzw. nie geholt wird) erhöht wird.
Bernd S. schrieb:> Was soll der Punkt bei rjmp .-2 ?>> -2 müsste jedoch $FFE sein, deswegen Arduino.
Ja, das ist Auszug aus einem Disassembler Listing eines Arduino
Programms.
Aber was Arduino damit zu tun hat, ist doch damit gar nicht ersichtlich.
Denn es ist doch die gleiche Toolchain, welche vom Atmel Studio genutzt
wird.
Bernd S. schrieb:> " Der erste Befehl eines Programms hat eine um einen Taktzyklus längere> Ausführungszeit als der gleiche Befehl an anderer Stelle des Programms,> da hier der Instruction Fetch nicht parallel zur Ausführung des> vorhergehenden vorgenommen werden kann. "
So so....
Bernd S. schrieb:> Warum der erste Befehl rjmp _reset wohl nur ein> Takt benötigt
Laut AVR Doku braucht rjmp 2 Takte.
Laut deinem Zitat, braucht der rjmp, wenn er als erster Befehl kommt, 3
Takte.
Wie du jetzt draus auf 1 Takt kommst, kann ich nur deinem
ArduinoUserHass zuschreiben. Denn rationale Begründungen sind aus deiner
Argumentation, oder der Doku, nicht zu entnehmen.
Ich schätze mal, dass dir da ein (peinlicher) Lapsus unterlaufen ist.
Tipp:
> Irren ist menschlich.> Im Irrtum verharren, ist Dummheit.
Bernd S. schrieb:> Was soll der Punkt bei rjmp .-2 ?>> -2 müsste jedoch $FFE sein, deswegen Arduino.
Den .xx kenne ich auch nicht.
Der rjmp macht von Hause aus +1. Deshalb muß man -2 machen, damit man
wieder vor rjmp landet.
Setze doch aber einfach eine Marke und springe dorthin.
Bei Änderungen kriegt man schnell Schwierigkeiten mit festen Werten.
Es gibt noch eine kleine Feinheit zu beachten. Atmels Software rechnet
bei Code in Worten, von GNU infizierte Versionen aber in Bytes. Was
manches -1 zu -2 werden lässt.
Bernd S. schrieb:> " Der erste Befehl eines Programms hat eine um einen Taktzyklus längere> Ausführungszeit als der gleiche Befehl an anderer Stelle des Programms,> da hier der Instruction Fetch nicht parallel zur Ausführung des> vorhergehenden vorgenommen werden kann. "
Selbst wenn das tatsächlich so sein sollte (ich weiss es nicht, die
Begründung klingt allerdings logisch), ist das doch wirklich ziemlich
irrelevant gegenüber der Variabilität der sonstigen Sachen, die so
zwischen Reset-Signal und Programmstart stattfinden können.
Sprich: kein Schwein interessiert's wirklich. Jedenfalls nicht jenseits
des Simulators. Denn bei den echten Teilen sind die Möglichkeiten, einen
Reset taktgenau auszulösen, doch ziemlich begrenzt, um nicht zu sagen:
gleich Null.
Bernd S. schrieb:> Was steht mit in der Threadüberschrift ? Richtig - lernen ;-)
Und, hast du?
Die Sache ist doch ziemlich simpel zu verstehen. Der Atmel Assembler
erwartet
ein absolute Adresse als Eingabe für alle Verzweigungs- und
Sprungbefehle. Den eigentlich für den Opcode benötigten relativen Offset
berechnet er aus dem gegenwärtigen PC (genauer: dem PC am Beginn der
Operation) und dem Sprungziel.
Das bedeutet: wenn man im Quelltext selber mit relativen Offsets
operieren will (wovon ich dringend abraten würde, weil sehr
fehlerträchtig, siehe meinen Fehler in diesem Thread) muss man den "PC"
als Bezug benutzen und zwar genau so, wie ihn auch der Atmel-Assembler
benutzt.
Andere Assembler haben andere Konventionen. Z.B. halt der des avr-gcc.
Da werden halt relative Offsets nicht durch PC+- angegeben, sondern
durch einen schlichten Punkt vor dem Argument und er benutzt als Bezug
auch nicht die Adresse der Operation selber, sondern die der darauf
Folgenden. Was bezüglich des zu encodierenden Opcodes durchaus einen
Sinn ergibt, insbesondere, wenn man die Prüfung auf wrap-arounds
effizient machen will.
Marc V. schrieb:> Wobei, wenn ich mich richtig erinnere, dies auch nicht bei allen> Compilern gleich behandelt wird, da bei manchen der PC immer noch> auf rjmp zeigt und erst bei nächstem Befehl (welches nicht existiert,> bzw. nie geholt wird) erhöht wird.>
Mir geht es um den Simulator und da zeigt der PC eindeutig auf die
Adresse $000C, wo ja auch der rjmp-Befehl hinterlegt ist ( Also im
Little-Endian-Format ). Habe also den Flashspeicher im vorherigem
Posting falsch interpretiert, was ich hier nun richtig stelle.
An Adresse $000C ist $F2C1 hinterlegt. $C ist ja der Code für rjmp.
$1F2 bedeutet für mich, das um 498 Adressen vorwärts gesprungen werden
soll.
Was der Adresse 498+12 = 510 -> $01FE entspricht.
Diese ganze Theorie passt leider gar nicht zu dem was der Simulator
macht, denn er springt nach Adresse $0000.
Arduino Fanboy D. schrieb:> Laut AVR Doku braucht rjmp 2 Takte.> Laut deinem Zitat, braucht der rjmp, wenn er als erster Befehl kommt, 3> Takte.>> Wie du jetzt draus auf 1 Takt kommst, kann ich nur deinem> ArduinoUserHass zuschreiben. Denn rationale Begründungen sind aus deiner> Argumentation, oder der Doku, nicht zu entnehmen.>> Ich schätze mal, dass dir da ein (peinlicher) Lapsus unterlaufen ist.>
Ich hege keinen Arduino-User-Hass. Mir ist bewusst, das man mit dieser
art Programmierung schnell zum Ziel kommt. Dem ist natürlich geschuldet,
das hier "meistens" kein Detailwissen vorhanden ist und auch gar nicht
gewünscht. Deswegen meine Skepsis dir gegenüber.
Um es jetzt noch mal deutlich zu schreiben. Nicht ich kam auf 1 Takt,
sondern der Simulator. Ich wollte damit also klar machen, das man dem
Simulator nicht trauen darf.
Er ist halt ein Simulant ;-)
Ja, manchmal sind mir Fehler peinlich, meistens aber nicht.
A. K. schrieb:> Es gibt noch eine kleine Feinheit zu beachten. Atmels Software rechnet> bei Code in Worten, von GNU infizierte Versionen aber in Bytes. Was> manches -1 zu -2 werden lässt.>
Hm - werde ich mal bei Lust und Laune drüber nachdenken.
Bernd_Stein
c-hater schrieb:> Die Sache ist doch ziemlich simpel zu verstehen. Der Atmel Assembler> erwartet> ein absolute Adresse als Eingabe für alle Verzweigungs- und> Sprungbefehle. Den eigentlich für den Opcode benötigten relativen Offset> berechnet er aus dem gegenwärtigen PC (genauer: dem PC am Beginn der> Operation) und dem Sprungziel.>
Ich verstehe trotzdem nicht wie der Assembler bei rjmp -1 auf den Opcode
von c1f2 an Adresse $000c kommt ( siehe lss-Datei.jpg weiter oben ).
Vielleicht jemand von den bisher 123 Leuten, die sich den Screenshot
angesehen haben.
Bernd_Stein
Bernd S. schrieb:> Ich verstehe trotzdem nicht wie der Assembler bei rjmp -1 auf den Opcode> von c1f2 an Adresse $000c kommt ( siehe lss-Datei.jpg weiter oben ).>> Vielleicht jemand von den bisher 123 Leuten, die sich den Screenshot> angesehen haben.
Klar doch!
Es gilt 3 Fragen zu beantworten:
1. du spinnst
2. dein Simulator spinnt
3. dein Assembler baut Mist
Also damit eine Gegenprobe:
Stefanus F. schrieb:> ende:> rjmp ende
Das ist exakt das, was bei meinem System zu
> rjump .-2
führt
Dann den generierten Code anschauen.
Im Simulator testen.
Und du wirst sehen: Du spinnst.
(das sagt zumindest meine Glaskugel)
------------
Bernd S. schrieb:> Deswegen meine Skepsis dir gegenüber.
Offensichtlich bist du mit Vorurteilen angefüllt.
Das befähigt dich, aus meinem Namen hier im Forum, darauf zu schließen,
dass ich ein Idiot (wie alle anderen Arduino User auch) bin.
Alle in einen Sack, und drauf hauen.
Eine solche Gelegenheit kannst du dann nicht liegen lassen.
Dummer weise, hast du eine Fehlinformation (egal, wo sie nun her kommt)
verwendet, um einen Erniedrigungsversuch einzuleiten.
Das hat dann nicht so geklappt... oder?
Ja, ich finde das sollte dir peinlich sein.
Mir wäre eine solche Blamage sehr peinlich.
Hi
>Ich verstehe trotzdem nicht wie der Assembler bei rjmp -1 auf den Opcode
von c1f2 an Adresse $000c kommt ( siehe lss-Datei.jpg weiter oben ).
Für welchen Controller ist das Programm assembliert?
MfG Spess
c-hater schrieb:> Fachbücher sind Mist, die kosten nur unnötig Geld und veralten schneller> als das Papier verrotten kann, auf dem sie gedruckt sind.
Ach nö. Wirkliche Fachbücher wie z.B. der alte Lampe-Jorke-Wengel sind
auch noch nach Jahrzehnten nicht veraltet, weil sie eben neben dem
einfachen Befehlssatz des gerade als Beispiel herangezogenen Chips das
vermitteln, was eigentlich vonnöten ist: Algorithmen erlernen.
Wenn du allerdings diese hinlänglich bekannten
Schnellschuß-Zusammenklatsch-Pseudo-Fachbücher ("alles über den XY180")
meinst, dann geb ich dir völlig Recht. Diese sind schon vor ihrem Druck,
ja sogar vor der Manuskript-Reinfassung obsolet.
W.S.
Bernd S. schrieb:> Ich verstehe trotzdem nicht wie der Assembler bei rjmp -1 auf den Opcode> von c1f2 an Adresse $000c kommt
Hallo, wenn auch zu Übungszwecken so etwas durchgekaut werden
sollte...kein Mensch, der in Assembler programmiert, benutzt irgendwo
absolute Werte (wenn er nicht unbedingt muß). Das macht der Assembler
für uns! Also "Schleife zurück" = rjmp/jmp "Schleife zurück". Alles
andere kann man den sogenannten Cracks überlassen! Lern' was, was dir
was bringt!! Oder kapiere das, was dir sicher nichts bringt :-)
Gruß Rainer
Bernd S. schrieb:> Ich verstehe trotzdem nicht wie der Assembler bei rjmp -1 auf den Opcode> von c1f2 an Adresse $000c kommt ( siehe lss-Datei.jpg weiter oben ).>
Mit Hilfe des doch richtig funktionierenden Simulators im ATEMEL Studio
7 und dem folgenden Programm, ist es mir gelungen den Opcode *$C1F2*, an
Adresse *$000C*, der im Listingfile zum Befehl rjmp -1 erzeugt wurde,
zu verstehen.
1
.CSEG ;Beginn des Programmspeichers
2
.ORG $0000 ;Anfangsadresse einstellen
3
rjmp _reset ;Dies ist die Reset-Vektoradresse ( $0000 )
4
nop
5
nop
6
nop
7
nop
8
nop
9
nop
10
nop
11
nop
12
nop
13
14
_reset: ;Programmstartaddresse ( $000A )
15
sbi DDRB,1 ;PortB1 als Ausgang konfigurieren
16
sbi PORTB,1 ;PortB1 Ausgang auf High setzen
17
18
rjmp -1 ;Vermeintlicher Sprung auf sich selbst ( $000C ),..
19
nop ;..also Endlosschleife
20
nop
21
nop
22
23
.EXIT ;Ende der Assemblierung
Die -1 ist die höhste Flashadresse ( $01FF ).
Zum Befehl rjmp steht folgendes : PC = PC + k + 1.
Um nun von der Adresse $000C, wo der Befehl rjmp steht, zur FLASH_END
Adresse zu gelangen, ist laut Formel ein Offset ( k ) von $01F2
erforderlich.
$000C rjmp bzw. PC
+$01F2 k
+$0001 +1
----------
$01FF PC
Noch was.
Welche Formatierung bekommt ihr zu sehen ?
Ich hoffe die Ok-Version ( siehe Anhang ).
Bernd_Stein
Dennis schrieb:> ich bin neu in dem Thema, und möchte erstmal Assembler für> Mikrocontroller lernen.Bimbo. schrieb:> Lerne C.
Das ist wieder einfach klasse!
Jemand schreibt: "Ich möchte Volleyball lernen...".
Jemand anderer Antwortet: "Lerne Minigolf."
Alles wie immer... ach ja: heute ist ja Freitag! :)
M.A. S. schrieb:> Das ist wieder einfach klasse!> Jemand schreibt: "Ich möchte Volleyball lernen...".> Jemand anderer Antwortet: "Lerne Minigolf."> Alles wie immer... ach ja: heute ist ja Freitag! :)
Genau, dann setzt jegliche Intelligenz aus.
(offensichtlich: bei dir auch)
Bernd S. !== Dennis
Arduino Fanboy D. schrieb:> Genau, dann setzt jegliche Intelligenz aus.> (offensichtlich: bei dir auch)>> Bernd S. !== Dennis
Mußt DU ja wissen. Wo kommt in meinem Beitrag "Bernd S." vor?
PS: Gut, ok, habe gerafft, dass "lern C" nicht an den TO gerichtet war.
Sorry. Trotzdem selbst schuld, wenn ohne Zitat geantwortet wird, ist
nicht klar, wem.
Rudi D. schrieb:> Dennis schrieb:>>> ich bin neu in dem Thema, und möchte erstmal Assembler für>> Mikrocontroller lernen.
Ja, das war vor knapp 6 Jahren (2013).
Inzwischen hat er's gelernt, nebenher sein Studium abgeschlossen und
programmiert erfolgreich in höheren Programmiersprachen.
Diese Thread kann damit geschlossen werden.
Gruss
Bernd S. schrieb:> Die -1 ist die höhste Flashadresse ( $01FF ).> Zum Befehl rjmp steht folgendes : PC = PC + k + 1.> Um nun von der Adresse $000C, wo der Befehl rjmp steht, zur FLASH_END> Adresse zu gelangen, ist laut Formel ein Offset ( k ) von $01F2> erforderlich.>> $000C rjmp bzw. PC> +$01F2 k> +$0001 +1> ----------> $01FF PC
Bis auf, das FLASH_END in der Betrachtung nicht vorkommt, der Sprung
nicht zu FLASH_END führt, und -1 auch nicht 0x1FF ist, stimmt das nicht.
> Zum Befehl rjmp steht folgendes : PC = PC + k + 1.
Das ist richtig. Allerdings solltest du auch in der Doku zu deinem
Assembler lesen, was da zum Befehl rjmp steht.
Weil da aber auch schin viele andere drauf reingefallen sind, lies
einfach, was z.B google als erstes dazu findet:
https://www.makerconnect.de/index.php?threads/rjmp-x.3593/
Oliver
Erich schrieb:> Rudi D. schrieb:>> Dennis schrieb:>>>>> ich bin neu in dem Thema, und möchte erstmal Assembler für>>> Mikrocontroller lernen.>>> Ja, das war vor knapp 6 Jahren (2013).>> Inzwischen hat er's gelernt, nebenher sein Studium abgeschlossen und> programmiert erfolgreich in höheren Programmiersprachen.>> Diese Thread kann damit geschlossen werden.
Danke für den Hinweis. Ein alter Thread der wieder auflebte. Sorry, hab
nicht aufs Datum geschaut.
Erich hat recht.
Bernd S. schrieb:> Mit Hilfe des doch richtig funktionierenden Simulators im ATEMEL Studio> 7 und dem folgenden Programm, ist es mir gelungen den Opcode *$C1F2*, an> Adresse *$000C*, der im Listingfile zum Befehl rjmp -1 erzeugt wurde,> zu verstehen.
Lass es erst mal sein, dich mit diesen Problem rumzuärgern.
Es gibt interessantere Sachen in Assembler.
Vielleicht gibt es eine Möglichkeit, das Argument relativ einzugeben.
Ähnlich wie beim Z-80.
Ich habe da auch mal mit dem alten Assembler rumgespielt.
Mit Marken.
Beim Sprung auf sich selbst, also rückwärts, bekomme ich
FF CF
Um ähnliche Werte vorwärts
.. C0
Wie kommst du auf die Idee, den Wert direkt einzugeben?
In der Assembler-Anleitung ist das erst mal nicht vorgesehen.
Benutze Marken!
Also jetzt noch mal ganz klar: PC-Adressen direkt zu maipulieren ist
kein Anfängerthema!! Und wie der TO auch immer drauf gekommen sein
mag...Quatsch, Quatsch, Quatsch.
Gruß Rainer
Sehe erst jetzt, dass das Ursprungsthema von 2013 ist.... war durchaus
an den TO gerichtet - jetzt aber nicht mehr, sondern eher an die
Allgemeinheit ;).
Assembler schön und gut. Ich würde erstmal C lernen. Wenn man dann mal
irgendwas zeitkritisches programmieren muss, dann macht man einen
Zwischenkurs Assembler. Oder halt irgendwann nach C um ggf. mal das
Output vom Compiler nachvollziehen zu können. Aber professionell oder
hobbymäßig in reinem Assembler zu programmieren, das ist Masochismus.
Wenn man als erstes Assembler lernen tut, dann haben in der Zwischenzeit
haben die sogenannten "Makerkids" schon ganze Stacks und CV Libs in C
programmiert und der erste Roboter fährt durch den Garten.
Bimbo. schrieb:> Assembler schön und gut. Ich würde erstmal C lernen.
Der Punkt ist: man kann C eigentlich frühestens dann kompetent
benutzen, wenn man sich mit der binären Repräsentation von Zahlen und
Zeichen und dem Konzept von Indirektionen auskennt. Dazu muss man zwar
nicht notwendigerweise irgendeinen Assembler-Dialekt erlernen, aber es
hilft doch schon dramatisch, wenn man einen beherrscht, idealerweise den
des Zielsystems...
Geht man nicht so vor und lernt nur den ganzen C-Syntax-Bombast, fällt
man über kurz oder lang auf die Schnauze. Genau so bauen diese ganzen
C-only-Typen immer und immer wieder Sicherheitslücken in ihre Machwerke
ein (bis sie dann irgendwann gelernt haben, was sie eigentlich von
Anfang an hätten wissen müssen). Und jede neue
C-only-Programmierer-Generation tut das auf's Neue...
Das ist eben das Problem von C: es gibt nicht alle Freiheiten, die
Assembler bietet, aber erlaubt (fast) alle Knieschüsse, die man sich
auch in Assembler verpassen kann. Die sind dann aber (zumindest
manchmal) immerhin "portabel", man kann sich damit also auf jedem
Zielsystem mit demselben Quelltext gleichermaßen ausknocken. Toller
Vorteil...
Auch den Umgang mit Brotmessern will gelernt werden.
Dass Anfänger Anfängerfehler machen, ist nun wirklich auch keine
besondere Neuigkeit.
Sondern eher Teil eines Prozesses, welchen man lernen nennt.
c-hater schrieb:> ...
Leichte Realitätsverzerrung heute wieder?
Deinen polemischen Schleim will doch keine(r) hier hören, oder?
Bist du der "Priester mit der traurigen Gestalt", oder wer war der Type,
mit den Windmühlen?
Oliver S. schrieb:> Bis auf, das FLASH_END in der Betrachtung nicht vorkommt, der Sprung> nicht zu FLASH_END führt, und -1 auch nicht 0x1FF ist, stimmt das nicht.>
Lies dir nochmal das Posting 7 auf der von dir verlinkten Seite durch,
dann verstehst du vielleicht, dass ich nichts anderes behaupte. Außerdem
lass das Programm mal durch den Simulator laufen, vielleicht verstehst
du dann.
https://www.makerconnect.de/index.php?threads/rjmp-x.3593/
1
.CSEG ;Beginn des Programmspeichers
2
.ORG $0000 ;Anfangsadresse einstellen
3
rjmp _reset ;Dies ist die Reset-Vektoradresse ( $0000 )
4
nop
5
nop
6
nop
7
nop
8
nop
9
nop
10
nop
11
nop
12
nop
13
14
_reset: ;Programmstartaddresse ( $000A )
15
sbi DDRB,1 ;PortB1 als Ausgang konfigurieren
16
sbi PORTB,1 ;PortB1 Ausgang auf High setzen
17
18
rjmp -1 ;Vermeintlicher Sprung auf sich selbst ( $000C ),..
19
nop ;..also Endlosschleife
20
nop
21
nop
22
23
.ORG FLASHEND ;$01FF Ende des 1 kB bzw. 512 Word Flashbereichs
Ok, ich korrigiere mich: Der Sprung führt zu FLASH_END.
AVR Studio macht auf dem Sprungziel mit Adresse -1 ein Wrap-Around im
Flash, und ladet damit bei FLASH_END. Kann man machen, muß man aber
nicht.
gcc erzeugt daraus einen Befehl, der tatsächlich die Adresse -1 (bzw.
-2) als Sprungziel hätte, und überlässt es dem Prozessor, was er damit
anfängt. Kann man machen, muß man aber nicht.
Oliver
Oliver S. schrieb:> AVR Studio macht auf dem Sprungziel mit Adresse -1 ein Wrap-Around im> Flash, und ladet damit bei FLASH_END...>
Bei rjmp 1 macht er einen Überlauf ( Wrap Around ), hierbei jedoch
nicht.
$000C rjmp 1
+$0FF4 k bzw. Adresse 1
+$0001
------
$1001 Wrap Around
$000C rjmp -1
+$01F2 k bzw. FLASHEND
+$0001
------
$01FF
Bernd_Stein
Bernd S. schrieb:> $000C rjmp 1> +$0FF4 k bzw. Adresse 1> +$0001> ------> $1001 Wrap Around
Das ist kein wrap around. k ist eine vorzeichenbehafte Zahl, daher
entspricht 0xff4 -11. 12-11 = 1.
Bernd S. schrieb:> $000C rjmp -1> +$01F2 k bzw. FLASHEND> +$0001> ------> $01FF
Da ist der wrap around. Das 0x1f2 berechnet das Studio aus dem
Sprungziel -1, welches durch wrap around zu flash_end (=0x1ff) wird.
Oliver
Oliver S. schrieb:> Das ist kein wrap around. k ist eine vorzeichenbehafte Zahl, daher> entspricht 0xff4 -11. 12-11 = 1.>
Nur nebenbei $FF4 ist -12.
Der Simulator bzw. Assembler führt immer das Selbe für den Befehl rjmp,
mit dem Programmcounter ( PC ), durch. Nämlich wie im Befehl rjmp
beschrieben
PC = PC + k + 1.
Der Flash reicht von $0000 bis $01FF. Das sind die Wordadressen 0 bis
511, also 512 Adressen.
Der Offset ( k ) kann in jede Richtung 2048 Byteadressen bzw. 1024
Wordadressen springen. Weil der Flash des AtTiny13 nur 512 Wordadressen
hat, ist der Assembler vermutlich auf Wrap Around eingestellt und
springt nur vorwärts ( in Richtung höherer Adressen ).
Oliver S. schrieb:> Das 0x1f2 berechnet das Studio aus dem> Sprungziel -1, welches durch wrap around zu flash_end (=0x1ff) wird.>
Nach deiner Rechnung oben :
0x1f2 -3598. 12-3598 = -3586 -> 0xe02
0xe02 ist ungleich 0x1ff.
Da du mir das mit deinen Beispielen nicht klar erklären kannst, bleibe
ich bei meiner Sicht der Dinge, die mir viel plausibeler erscheint.
In älteren Versionen konnte man den Assembler anweisen mit Wrap Around
zu arbeiten. Die neuen Versionen werden es, wie bereits geschrieben,
vermutlich automatisch an Hand der xyz.def einstellen.
Bernd_Stein
Bernd S. schrieb:> Der Offset ( k ) kann in jede Richtung 2048 Byteadressen bzw. 1024> Wordadressen springen. Weil der Flash des AtTiny13 nur 512 Wordadressen> hat, ist der Assembler vermutlich auf Wrap Around eingestellt und> springt nur vorwärts ( in Richtung höherer Adressen ).
Das wäre widersinnig.
Der Atmel Studio Assembler berechnet k aus einer negativen absoluten
Zieladresse durch wrap around mit der Flash Größe eine positive (bzw. Er
rechnet vermutlich modulo Flash_size). So wird aus -1 Flash_end, aus -2
wird Flash_end-1, usw. Ob der das mit positiven Sprungadressen größer
flash_end auch macht, hab ich nicht probiert, kann aber sein.
Ist das Sprungziel positiv oder Null, berechnet der k der natürlich auch
für einen Sprung rückwärts.
gcc macht das alles nicht, der berechnet k stur aus der absoluten
Zieladresse, egal, ob die negativ ist, oder nicht.
Oliver
Bernd S. schrieb:> Nur nebenbei $FF4 ist -12.
Nur nebenbei:
$FF4 ist immer 4084(int oder uint)
$FFF4 ist -12 (int) oder 65524 (uint)
$F4 ist -12 (signed char) oder 244(char)
P.S.
Atmel sagt folgendes:
Relative jump to an address within PC - 2K +1 and PC + 2K (words).
Deswegen kann alles bis 8KB mit rjmp angesprungen werden, alles
über 8KB benutzt jmp.
P.P.S.
Ev. Wrap Around (und die daraus resultierende Adresse) ist demzufolge
nichts anderes als ((PC + Rel. Jump Offset) MODULO Flashsize).
Marc V. schrieb:> Nur nebenbei:> $FF4 ist immer 4084(int oder uint)
Da es sich per Definition um einen vorzeichenbehafteten 12-Bit Wert
handelt, ist das in dem speziellen Fall, um den es hier geht, falsch.
int oder uint oder sonstwas gibt es auf dem Level nicht. Was das "immer"
dann auch etwas relativiert.
Marc V. schrieb:> Ev. Wrap Around (und die daraus resultierende Adresse) ist demzufolge> nichts anderes als ((PC + Rel. Jump Offset) MODULO Flashsize).
So isses.
Oliver
Oliver S. schrieb:> ...(bzw. Er> rechnet vermutlich modulo Flash_size)...>Marc V. schrieb:> P.P.S.> Ev. Wrap Around (und die daraus resultierende Adresse) ist demzufolge> nichts anderes als ((PC + Rel. Jump Offset) MODULO Flashsize).>
An euch beide.
Wie sieht diese Modulo-Rechnung aus ? ( Formel mit Werten )
Bernd_Stein
c-hater schrieb:> Das Problem ist nur:> Über kurz oder lang wirst du nicht drumrum kommen, den C-Scheiß> zumindest lesen zu können.
LOL!
Dir gelingt es trotz all des Blödsinns den Du oftmals verzapfst hin und
wieder tatsächlich immer noch mich zum Lachen zu bringen!
Oliver S. schrieb:> Was genau ist jetzt deine tatsächliche Frage? Doch wohl nicht die> Modulo-Berechnung?>
Ja, doch. Was für Werte setzt du bzw. ihr da ein ?
Das Ergebnis werde ich versuchen selber zu ermitteln ;-)
Bernd_Stein
Zieladresse und Flashgröße. Ergibt eine korrigierte Zieladressee
innerhalb 0..flash_end. Aus der wird dann k berechnet.
Beitrag "Wieso ist -1 mod 26 = 25 ?"
Oliver
Oliver S. schrieb:> Ach je, stell dich nicht dümmer, als du bist. Du kriegst das raus.>
Ok, verstehe. Es ist also nur eine Vermutung die sich nicht beweisen
läßt.
Mir ging es ja darum warum rjmp -1 an Adresse $000C den Opcode $C1F2
erzeugt.
Das ist mir nun klar. Wie die CPU dies genau macht bzw. welchen
Algorithmus oder was auch immer der Assembler macht ist mir nicht so
wichtig.
Bernd_Stein
Bernd S. schrieb:> Ok, verstehe. Es ist also nur eine Vermutung die sich nicht beweisen> läßt.
Natürlich ist die Berechnung dahinter nur eine Vermutung, da Atmel
selber die ja nicht öffentlich dokumentiert hat. Aber die Berechnung,
wie das Studio das vermutlich macht, kriegt man ja schnell raus, und das
lässt sich an Hand einiger schneller Tests dann auch bestätigen (oder
widerlegen).
Eigentlich steht das schon alles in den letzten Beiträgen, du musst es
nur noch hinschreieben. Das darfst du aber selber machen.
Bernd S. schrieb:> Mir ging es ja darum warum rjmp -1 an Adresse $000C den Opcode $C1F2> erzeugt.> Das ist mir nun klar. Wie die CPU dies genau macht bzw. welchen> Algorithmus oder was auch immer der Assembler macht ist mir nicht so> wichtig.
Na ja, die Frage nach dem warum ist die Frage nach dem Algorithmus
dahinter. Wie sonst soll man beantworten, wie der Atmel Studio Assembler
von der absoluten Adresse -1 auf die relative Sprungweite k zu $1F2
kommt?
Oliver
Bernd S. schrieb:> Warum wird mit dieser Initialisierung nur einmal in die ADC-ISR> gesprungen ?>
Weil der Free Running Mode auch nur ein " Autotrigger Mode " ist,
welcher durch ADIF getriggert wird. Und die ADC Auto Trigger Logic
braucht nun mal das Bit ADATE.
Außerdem ist der ODER-Baustein Flankengesteuert.
Bernd_Stein
Es ist wirklich schade, dass das Datenbuchstudium unter Microchip eine
Glückssache geworden ist.
Aus diesem einen Satz entnehme ich, das der Free Running Mode nicht
dazu geeignet ist, mit Kanalwechseln oder Referenzqeullenwechseln zu
arbeiten.
In dem von Spess verlinkten DB gibt es diesen Satz nicht mehr.
Bernd_Stein
Bernd S. schrieb:> Aus diesem einen Satz entnehme ich, das der Free Running Mode nicht> dazu geeignet ist, mit Kanalwechseln oder Referenzqeullenwechseln zu> arbeiten.
Das ist so nicht ganz richtig....
Man wird eben die erste Messung nach einem Kanalwechsel verwerfen
müssen, da man nicht genau weiß, in welchem Augenblick/ADCTakt der
Wechsel stattgefunden hat.
Und der Wechsel der Referenz braucht auch eine Einschwingzeit.
Ins besondere, wenn die interne dafür erst noch "hochgefahren" werden
muss.
Das ist an anderer Stelle sicherlich beschrieben.
Bernd S. schrieb:> warum ändert diese Programmsequenz nicht den Systemtakt ?
Der Thread wurde von Dennis für seinen ATmega8 eröffnet.
Dein letzter Beitrag, wo du ein Mikrocontroller-Modell nanntest, bezog
sich auf den ATtiny13.
Zwischendurch zegtest du einen Ahnag für den ATmgea88.
Jetzt sind wir beim ATmega6490.
Ich finde das ziemlich verwirrend. Ich habe gerade eine Menge Text
geschrieben und wieder gelöscht, weil diese Erkenntnis zu spät kam.
In deinem Programm sehe ich keinen Fehler. Die Problemursache muss in
dem Teil sein, denn du weg geschnitten hast. Waren zum Beispiel
Interrupts freigegeben? Wie hast du den Erfolg (bzw. Misserfolg)
überprüft?
Bitte eröffne einen eigenen neuen Thread für deine Frage und bitte nur
ein Thema pro Thread.
Das Umschalten geht recht einfach; Atmel hat allerdings eine
Sicherheitsmassnahme gegen versehentliches Umschalten des Taktes
eingebaut:
Man muss zunächst lediglich das oberste Bit im Register CLKPR auf "1"
setzen (alle anderen Bits müssen "0" sein) und hat dann 4 Takte Zeit,
durch Beschreiben der 4 unteren Bits die neue Taktrate einzustellen (das
oberste Bit muss dabei auf "0" stehen). Auch müssen Interruts
deaktiviert sein, damit sie nicht in das 4-Takte-Zeitfenster
„hineinfunken“.
Quelle :
http://www.elektronik-labor.de/AVR/CLKPR.html
Ob ATtiny13 oder AtMega6490P ist für dieses Problem uninteressant.
Auf den Simulator ist leider wieder kein Verlass.
CLKPCE wird noch richtig gesetzt, aber der Teilerwert $05 bzw. 32 (
CLKPS2 & CLKPS0 ) wird einfach mal als $06 bzw. 64 übernommen.
Aber das Hauptproblem ist, das sich das Signal nicht ändert.
Im Anhang ist das komplette Programm für das ATMEL STUDIO 7, falls es
wirklich jemand interessiert.
Bernd_Stein
Bernd, kannst du mal erklären, warum du immer wieder fragen zu so
komischen Corner-Cases stellst und sie kurze Zeit danach selbst
beantwortest? Was soll das werden, eine Kampagne gegen Microchips bzw.
deren Simulator?
Anders kann ich mir dies in Kombination mit den zahlreichen Wechseln der
Mikrocontroller nicht mehr erklären.
(Dass der Kacke ist, wissen wir alle, das ist keine neue Erkenntnis).
Stefanus F. schrieb:> Bernd, kannst du mal erklären, warum du immer wieder fragen zu so> komischen Corner-Cases stellst und sie kurze Zeit selbst beantwortest?> Was soll das werden, eine Kampagne gegen Microchip?>> Anders kann ich mir dies in Kombination mit den zahlreichen Wechseln der> Mikrocontroller nicht mehr erklären.>
Was sind Corner-Cases ?
Ich arbeite halt an verschiedenen Sachen und wundere mich dann, dass es
nicht so funktioniert wie ich es mir gedacht habe. Und irgendwie kommen
immer noch irgendwelche Dinge hinzu die ich erstmal nicht verstehe.
Das Problem ist nämlich noch nicht gelöst, obwohl ich laut allen Quellen
die ich genutzt habe, meine alles richtig gemacht zu haben.
Ich weiß Assembler ist verpönt, aber in der ursprünglichen
Threadüberschrift ist ja klar zu lesen, dass es um ASM geht und es ist
meistens nötig diese Sprache zu beherrschen, um mir bei meinen Problemen
helfen zu können.
Bernd_Stein
Bernd S. schrieb:> Ich arbeite halt an verschiedenen Sachen und wundere mich dann, dass es> nicht so funktioniert wie ich es mir gedacht habe. Und irgendwie kommen> immer noch irgendwelche Dinge hinzu die ich erstmal nicht verstehe.
Wenn das so ist, dann trenne Dich vom Simulator. Der war schon immer
zickig und fehlerhaft. Du kannst besser mit echten AVR Controllern in
Kombination mit einem Atmel ICE Debugger lernen.
Stefanus F. schrieb:> Du kannst besser mit echten AVR Controllern in> Kombination mit einem Atmel ICE Debugger lernen.>
Selbst mit dem ATMEL ICE hab ich seltsame Effekte per JTAG.
Die neue Adapterplatine mit 3x 0402 100nF KERKOs an den Versorgungspins
10&11; 31&32; sowie 80&81 hat mich zwei Stunden gekostet und ich kann
erstmal wieder über beide Schnittstellen ( ISP & JTAG ) auf den
AtMega6490P zugreifen.
Kommentiere ich die Systemtaktumstellung aus, lande ich nach dem Klicken
auf Continue ( F5 ) brav beim Breakpoint wie zu sehen. Nehme ich
allerdings diese Programsequenz rein läuft das Programm endlos und durch
klicken von Pause bzw. Break All ( Crtl+F5 ) lande ich immer beim
Reset-Vektor.
Einzelschritt bzw. Step Into ( F11 ) erzeugt ebenfalls ein Endloslauf
des Programms, was durch klicken von Pause ebenfalls beim Reset-Vektor
landet.
Der Systemtakt wurde laut CLKPR ( Clock Prescaler Select Bits ) richtig
auf 32 eingestellt ( $05 ).
Es ist zum Wahnsinnig werden.
1
;
2
;Programmstart nach RESET ( Interrupt Vektoren Tabelle )
3
;
4
.CSEG ;Was ab hier folgt kommt in den FLASH-Speicher
5
.ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000..
Bernd S. schrieb:> Nehme ich allerdings diese Programsequenz rein läuft das Programm endlos
Ich erkenne den Zusammenhang zur Taktfrequenz nicht. Das wirft Fragen
auf. Kannst du mal den ganzen Quelltext posten (oder ist es immer noch
der aus dem obigen Zip-File)?
> Was sind Corner-Cases?
Seltene spezielle Situationen, die im Normalfall nicht vorkommen.
Stefanus F. schrieb:> Ich erkenne den Zusammenhang zur Taktfrequenz nicht. Das wirft Fragen> auf. Kannst du mal den ganzen Quelltext posten (oder ist es immer noch> der aus dem obigen Zip-File)?>
Ich auch nicht.
Eine Erklärung wäre das das Debuging damit nicht zurecht kommt, aber
warum funktioniert die Systemtaktumstellung nicht im µC ?
Ja, bis auf die eine Zeile die ich im Debugger verwenden wollte, um zu
sehen welchen Wert den jetzt CLKPR hat ( lds a,CLKPR ).
Bernd_Stein
In dem oben beschrieben Tutorial hier aus dem Forum auf der Seite 46,
zur vorzeichenlosen Division, müsste es für mich bei dieser Sequenz so
im Kommentar heissen :
1
cp r19,r17 ;Ist der Divisor groesser?
2
brlo div_zero ;wenn JA, dann bleibt die 0
3
sbr r20,1 ;wenn NEIN, dann jetzt die 0 durch eine 1 austauschen ...
Bernd S. schrieb:> machen mich total kirre>> Ist bla, bla grösser? -> springe wenn kleiner
Vielleicht ist sowas zwecks Nutzung mancher Assembler-Befehle
zweckmässig (ich weiss es nicht, ich nutze kein Assembler seit langer
Zeit)
Ist halt wie manche Abfrage in einem populären Desktop-Betriebssystem:
"Soll diese Datei nicht gelöscht werden? [Ja NEIN]"
Ich habe festgestellt dass man sich nicht einfach vor den PC setzen und
ein Assembler-Programm schreiben kann.
Statt dessen muss man eine Art Flussplan schreiben mit möglichst kleinen
Schritten. Diese Schritte übersetzt man dann in die Maschinensprache.
Also man erzeugt Variablen oder berechnet etwas oder macht eine bedingte
Verzweigung usw.
H-G S. schrieb:> Ich habe festgestellt dass man sich nicht einfach vor den PC setzen und> ein Assembler-Programm schreiben kann.>> Statt dessen muss man eine Art Flussplan schreiben ...
Dieser Ansatz empfiehlt sich auch bei "Hochsprachen". Juhu, die
Assembler-Fraktion entdeckt die strukturierte Vorgehensweise.
Wegstaben V. schrieb:> Dieser Ansatz empfiehlt sich auch bei "Hochsprachen".
Datenflussdiagramme und UML-Klassendiagramme haben auch ihren Wert.
(vielleicht sogar noch mehr als Programmflussdiagramme)
Hallo,
wegen der Taktumstellung. Kann es sein das der Schreibschutz auf das
entsprechende Register noch nicht aufgehoben wurde? Manche kritische
Register können/sind mit einem Schreibschutz versehen der direkt vor
Änderung temporär aufgehoben werden muss. Kann das irgendwie sein und du
nur einen Buffer siehst?
H-G S. schrieb:> Ich habe festgestellt dass man sich nicht einfach vor den PC setzen und> ein Assembler-Programm schreiben kann.>> Statt dessen muss man eine Art Flussplan schreiben mit möglichst kleinen> Schritten. Diese Schritte übersetzt man dann in die Maschinensprache.
Kaum. Das macht der Assembler. Der Mensch schreibt Assemblerbefehle.
> Also man erzeugt Variablen oder berechnet etwas oder macht eine bedingte> Verzweigung usw.
Na das ist ja mal ne Erkenntnis! Ich ruf schon mal in Stockholm an!
H-G S. schrieb:> Ich habe festgestellt dass man sich nicht einfach vor den PC setzen und> ein Assembler-Programm schreiben kann.>> Statt dessen muss man eine Art Flussplan schreiben mit möglichst kleinen> Schritten.
Das trifft generell für alle Programmiertätigkeiten zu, nicht nur für
Assembler.
Leider sieht man auch viele, die das nicht einsehen wollen, obwohl sie
keine Anfänger mehr sind.
Die richtige Planung erspart mindestens 80% der Programmierarbeit und
90% Frust bei der Fehlersuche.
So mancher Programmierer traut sich zu, ohne Plan einfach drauf los
programmieren zu können.
Man sollte aber bedenken, dass es später oft andere Leute sind, die
Fehler analysieren oder Erweiterungen einbauen müssen. Wenn das ganze
Konstrukt (nicht nur der Quelltext) dann nicht gut durchdacht ist,
blickt nur der erste Autor durch.
Ein Plan zu Erstellen hilft dabei, das Konstrukt zu durchdenken und zu
dokumentieren.
Ich seh das mittlerweile komplett anders. Wer ein UML oder Flußdiagramm
braucht um seinen Code zu erklären, der braucht ein Refactoring. Das
Zeug is ok um sich über Ideen zu unterhalten oder Notfalls einen
komplexen Algorithmus zu dokumentieren, ansonsten halt ich es für eher
hinderlich. Die ersparte Zeit sollte man lieber in gute Tests stecken.
Vincent H. schrieb:> Ich seh das mittlerweile komplett anders. Wer ein UML oder Flußdiagramm> braucht um seinen Code zu erklären, der braucht ein Refactoring.
Du hast das falsch verstanden. Den Plan erstellt man vorher. Man
benutzt ihn, um danach den Code einzuhacken. Der Plan sorgt auch
dafür, daß man erst gar kein Refactoring braucht, bzw. deutlich weniger
Schritte.
Wenn er ordentlich erstellt ist, kann man ihn aber auch als
Dokumentation behalten.
Die Crux an solchen Plänen ist, dass man das Problem nicht richtig
verstanden hat bevor man es zumindest 1x gelöst hat. Viele Details sind
vorher nicht klar und die Gefahr von overengineering ist allgegenwärtig.
sbr r20,1 ;wenn NEIN, dann jetzt die 0 durch eine 1 austauschen ...
Um mal wieder konkret auf das Problem einzugehen, danach kommt auch von
meiner Seite wieder etwas Bla, bla mit Korintenscheisse ;-)
Was im genannten µC-Tutorial steht stimmt nicht, der obige Kommentar von
mir ist also richtig.
Der Compare-Befehl subtrahiert r17 von r19. Also den Divisor vom
Zwischenergebnis.
Der Branch-Befehl verzweigt, wenn das Carry-Flag gesetzt ist ( brlo =
brcs ). Das heißt - wenn das Carry-Flag gesetzt ist, ist der Divisor
grösser als das Zwischenergebnis und somit kann die Null im
Zwischenergebnis bestehen bleiben.
Im Umkehrschluss ist dann das Zwischenergebnis ( r19 ), kleiner als
der Divisor ( r17 ) und somit wird gesprungen.
Die Befehlsbeschreibung ( Branch if lower ( unsigned )) bezieht sich auf
das Zielregister ( r19 ). Ich glaube, dies ist bei der
Befehlsbeschreibung generell so.
Das Programm läßt sich meiner Meinung nach besser nachvollziehen wenn
Namen für die Register benutzt werden. Deshalb hier noch mal das
Programm mit sinnigen Registernamen :
Sorry für die beschissene Formatierung, bei mir sieht es im
Erstellugsfenster jedoch gut aus.
.CSEG ;was ab hier folgt kommt in den FLASH-Speicher
12
.ORG $0000 ;Programm beginnt an der FLASH-Adresse 0x0000.CSEG
13
14
_loop:
15
ldi divident,109 ;Dividend
16
ldi divisor,9 ;Divisor
17
;Division r16: r17
18
ldi schritte,8 ;8 Bit Division
19
clr z_ergebnis ;Register für die Zwischenergebnisse / Rest
20
clr ergebnis ;Ergebnis
21
22
_divloop:
23
lsl divident ;Zwischenergebnis mal 2 nehmen und das
24
rol z_ergebnis ;nächste Bit des Dividenden anhängen
25
lsl ergebnis ;das Ergebnis auf jeden Fall mal 2 nehmen, ;das hängt effektiv eine 0 an das Ergebnis an. ;Sollte das nächste Ergebnis-Bit 1 sein, dann wird ;diese 0 in Folge durch eine 1 ausgetauscht
26
cp z_ergebnis,divisor;ist der Divisor größer?
27
brlo _div_zero ;wenn ja, dann bleibt die 0
28
sbr ergebnis,1 ;wenn nein, dann jetzt die 0 durch eine 1 austauschen ...
29
sub z_ergebnis,divisor;... und den Divisor abziehen
30
31
_div_zero:
32
dec schritte ;das Ganze 8 mal wiederholen
33
brne _divloop ;in r20 steht das Ergebnis der Division
34
35
rjmp _loop
36
37
.EXIT ;Ende des Quelltextes
Ich benutze aus Faulheit immer erst dann Flussdiagramme, wenn ich nicht
mehr durchsteige.
Und hier noch etwas Korintenscheisserkommentar und die nicht so gewollte
Formatierung. Seltsam, nachdem ich dies in "" gesetzt habe passt die
Formatierung. Im Vorschaubild jedoch nicht :-(
"Ich will jetzt nicht klugscheissen, aber dennoch eine Unterscheidung
zwischen Assembler und Maschinencode darstellen, wobei bedacht
werden muss, dass es bei dem Ausdruck ASSEMBLER einmal um das
"Assembler-Übersetzungsprogramm" gehen kann und zum Anderen um die
Programmiersprache, was ich jetzt meine.
Das du das weisst ist mir bekannt, aber ich schreibe halt für alle die
hier mitlesen.
Das ist Asssembler ( Programmiersprache ) : NOP
und dies Maschinencode : 0000 0000 0000 0000
Deshalb hat man den Assembler erschaffen um nicht für uns Menschen diese
Binärcodes bzw. Hexadezimalzahlen als Programm schreiben zu müssen."
Bernd_Stein
Vincent H. schrieb:> Die Crux an solchen Plänen ist, dass man das Problem nicht richtig> verstanden hat bevor man es zumindest 1x gelöst hat. Viele Details sind> vorher nicht klar und die Gefahr von overengineering ist allgegenwärtig.
Die Gefahr von Murks und Drauflosfrickeln noch viel mehr . . .
> Sorry für die beschissene Formatierung, bei mir sieht es im> Erstellugsfenster jedoch gut aus.
Du verwendest vermutlich TABs zum Formatieren.
Das Problem mit TABs ist, dass sie je nach Umgebung (Editor, Webseite,
e-Mail) unterschiedlich interpretiert werden. So kann z.B. eine
Webseite, die Code darstellt, nicht wissen, ob du lokal die TAB-Weite
auf 4, 8 oder was anderes eingestellt hast.
Zeitgemäße Editoren erlauben es, Spaces anstatt TABs zu verwenden, und
man merkt in der Handhabung dann auch kein Unterschied. (Der einzige
Fall, wo das nicht geht, ist wenn TAB syntaktisch erforderlich ist wie
in Makefiles.)
Damit ist dann sichergestellt, dass Formatierungen überall gleich gut
und frustfrei lesbar sind.
Vincent H. schrieb:> Die Crux an solchen Plänen ist, dass man das Problem nicht richtig> verstanden hat bevor man es zumindest 1x gelöst hat.
Dann ist eher das Problem, daß man dem Kunden alle Anforderungen erstmal
umständlich aus der Nase popeln muß. Oft hat sich der Kunde selber keine
Gedanken gemacht, was er eigentlich haben will.
Für den Entwickler ist es nicht schön, wenn er Sachen mehrfach ändern
muß. Aber genau dabei zahlt es sich aus, wenn er vorher einen Plan
gemacht hat und damit die Programme leicht wartbar und erweiterbar
gehalten hat. Manche Erweiterungen und Schnittstellen kann man so auch
schon vorausschauend implementieren.
Und oft kann man durch die Nacharbeiten auf Kundenwunsch auch einen
Gewinn erwirtschaften, wenn das eigentliche Projekt sehr knapp
kalkuliert war.
Hallo zusammen,
bei der Assemblerprogrammierung lernt man ja jedes Bit des µC einzeln
kennen.
Habe das im Screnshot zu sehende Programm zum Festellen des Systemtaktes
benutzt. Das Oszi zeigt eine Frequenz von 14,660kHz an PB4 ( Pin3 ), an.
Dies mal 8 ergibt -> 117,280kHz
Das Multimeter ( MM ) zeigt 14,705kHz an ( 117,640kHz ).
Die Versorgungsspannung mit dem MM an Vcc ( PIN 8 ) gemessen, ist 4,78V.
Die Befehlszeile " in a,OSCCAL " war zu diesem Zeitpunkt noch nicht
eingefügt.
1. Warum zeigt mir das Atmel Studio 7 ( AS7 ) mit DebugWire nicht das
OSCCAL -Register an ?
2. Habe ich OSCCAL mit 67dez richtig ausgelesen?
67 würde ja ca. 52% oder 104% bedeuten.
52% mehr würde bei mir ca. 167kHz ergeben bei einer Nominalfrequenz bei
4,75V und 25°C, wenn ich hier 110300Hz laut Kennlinie festsetze.
Selbst im Temperaturbereich von 20-40°C hätte ich ja nur eine Abweichung
von ca. 1,1kHz zusätzlich zu berücksichtigen.
Wie kommt die Diskrepanz zwischen der festgestellten Frequenz von 117kHz
und der errechneten von 167kHz zu stande ?
Wo ist mein Fehler ?
Bernd_Stein
Bernd S. schrieb:> Habe ich OSCCAL mit 67dez richtig ausgelesen?> 67 würde ja ca. 52% oder 104% bedeuten.
Die möglichen Werte liegen zwischen 0 und 127. Ich denke nicht, dass man
das so einfach in Prozent umrechnen kann. Da stellt sich doch die Frage:
Prozent von was?
> Wie kommt die Diskrepanz zwischen der festgestellten Frequenz> von 117kHz und der errechneten von 167kHz zustande ?
Der R/C Oszillator unterliegt (wie jeder R/C Oszillator) starken
Material-Streuungen. Deswegen werden die Chips schon in der Fabrik
einzeln kalibriert. Beim Reset kopiert der Chip automatisch den
Kalibrier-Wert ins Register. Die Angabe, dass das Register initial den
Wert 0 hat ist daher irreführend.
Du kannst ebenso nicht davon ausgehen, dass der Chip bei einem
bestimmten Wert eine bestimmte Frequenz liefert. Jeder Chip hat initial
einen anderen Wert, um (in der Fabrik) auf die 100% zu kommen.
Bernd S. schrieb:> Wie kommt die Diskrepanz zwischen der festgestellten Frequenz von 117kHz> und der errechneten von 167kHz zu stande ?
Und was hat das mit "Assembler lernen" zu tun?
Stefan ⛄ F. schrieb:> Die möglichen Werte liegen zwischen 0 und 127. Ich denke nicht, dass man> das so einfach in Prozent umrechnen kann. Da stellt sich doch die Frage:> Prozent von was?>
Ich interpretiere dies für den 128kHz Oszillator so :
Mit dem Wert $00, kann der Oszillator mit 64kHz oder aber auch mit
128kHz schwingen. Mit $7F, mit 128kHz oder 256kHz.
Stefan ⛄ F. schrieb:> Die Angabe, dass das Register initial den> Wert 0 hat ist daher irreführend.>
Im vom mir benutztem DB wurde dies bereits in " Device Specific
Calibration Value " geändert.
Stefan ⛄ F. schrieb:> Der R/C Oszillator unterliegt (wie jeder R/C Oszillator) starken> Material-Streuungen. Deswegen werden die Chips schon in der Fabrik> einzeln kalibriert.>
Ja genau, deshalb ja auch die Kennlinien im vorherigem Post. Daraus
sollte man dann aber auch ungefähr ( vom mir aus +/- 2kHz ) die Frequenz
bei einer bestimmten Versorgungsspannung und Temperatur herausbekommen
können, da der Oszillator ja bereits bei der Fertigung kalibriert wurde.
Peter D. schrieb:> Bernd S. schrieb:>> Wie kommt die Diskrepanz zwischen der festgestellten Frequenz von 117kHz>> und der errechneten von 167kHz zu stande ?>> Und was hat das mit "Assembler lernen" zu tun?>
Dir ist sicherlich nicht entgangen dass der Screenshot aus AS7,
Assembler beinhaltet. Deshalb möchte ich ( über die Threadüberschrift )
nur Leute erreichen die sich hiermit auskennen, denn die Anderen
interessiert oftmals nicht was Bit für Bit in den SFR passiert und
können deshalb auch nichts zu meinen Fragen antworten :
Bernd S. schrieb:> 1. Warum zeigt mir das Atmel Studio 7 ( AS7 ) mit DebugWire nicht das> OSCCAL -Register an ?>> 2. Habe ich OSCCAL mit 67dez richtig ausgelesen?>
Bernd_Stein
Bernd S. schrieb:> denn die Anderen> interessiert oftmals nicht was Bit für Bit in den SFR passiert und> können deshalb auch nichts zu meinen Fragen antworten :
Es mag Dich zwar erstaunen, aber auch in sämtlichen anderen
Programmiersprachen (C, Bascom, Pascal, Forth usw.) kann man ganz
selbstverständlich auch SFRs und ihre Bits ansprechen. In der Regel
haben sie die gleichen Namen, wie im Datenblatt.
Die magische Zeile dafür lautet unter C:
Warum man einen Thread nicht kapern sollte, ist ganz einfach:
Viele lesen nicht den ganzen Schmonz bis zum Ende, sondern antworten
weiter auf das Ursprungsthema.
Bernd S. schrieb:> Haben die neueren AVR's nicht schon sehr genaue interne RC-Oszillatoren,> so dass ich vom ATtiny13A zu etwas neuerem wechseln sollte ?
Wie lauten denn deine Anforderungen? Solange der ATtiny13A gut genug
ist, sehe ich keinen Grund, zu einem anderen zu wechseln.
> Tja, ich benutze ja schon andere Überschriften und man sollte schon> lesen worauf man antworten will. Diese Art von Leuten wird mir> sicherlich auch nicht helfen können.
Für wen hältst du dich? Du bist hier der, der um Hilfe bittet. Je
ordentlicher deine Frage gestellt ist, umso besser werden die Antworten
sein. Die richtigen Experten sind sich nämlich teilweise zu fein, auf
schlampige Fragen einzugehen. Wenn du wirklich auf deren Expertise
keinen Wert legst, dann hast du überhaupt keine hilfreiche Antwort
verdient.
Außerdem ist dein Verhalten dem Thread Owner gegenüber unfair. Wenn
jetzt abwechselnd für ihn und für dich geantwortet wird, bricht hier das
große Chaos aus. Dann würdest du sagen "ist nicht mein Problem". Wie
lässt sich das jetzt noch vermeiden?: Indem man nur noch Dir antwortet.
Daher der Begriff "kapern".
Mache es nächstes mal bitte rücksichtsvoller.
Stefan ⛄ F. schrieb:> Wie lauten denn deine Anforderungen? Solange der ATtiny13A gut genug> ist, sehe ich keinen Grund, zu einem anderen zu wechseln.>
12,5% Abweichung.
Heute habe ich 123kHz gemessen.
Ich nehme jetzt mal wieder 128kHz als Nominalfrequenz. Dann sind 117kHz
-8,6% und 123kHz -3,0% Abweichung.
Bei einer Versorgungsspannung von 4,8V und einem Temperaturbereich von
-40°C bis 85°C entnehme ich den vorher geposteten Kennlinien eine
Differenz von 6kHz, was auf 128kHz bezogen eine Abweichung von knapp 5%
entspricht. Was mal wieder nicht so in meine Praxiserfahrung passt (
siehe 117kHz = -8,6% ).
Der ATtiny13A sollte also trotzdem hierfür zu gebrauchen sein.
Und jetzt dass im Forum beliebte Offtopic - nicht persönlich nehmen :
Stefan ⛄ F. schrieb:> Für wen hältst du dich? Du bist hier der, der um Hilfe bittet. Je> ordentlicher deine Frage gestellt ist, umso besser werden die Antworten> sein.> ...>
Du bist wenigstens einer, der versucht durch Gegenfragen oder Hinweise
auf den Kern des Problems, zu helfen.
Der ursprüngliche Threadersteller hat sich genau einmal hier unter dem
Gastnamen " Dennis " zu Wort gemeldet. Gästen antworte ich sehr, sehr
ungern, weil man meistens nicht erfährt, was jetzt schlussendlich
herausgekommen ist. Diese Thread ist ein glänzendes Beispiel hierzu.
Wer sich für AVR8ASM interessiert schaut sicherlich in den wenigen
Threads hierzu wenigstens mal kurz rein, bekommt also eine
Benachrichtigung, wenn es was neues gibt, falls er das Häkchen bei "
Thread beobachten " gesetzt hat. Dann liest man sich dieses " Neue "
durch und antwortet dementsprechend oder halt nicht.
Wer meine Threads aufmerksam verfolgt, wird bemerkt haben, dass ich
versuche keine " Datenleiche " zu erzeugen. Das heißt für die Mitleser
einen Nutzen zu erbringen. Der hierzu erzeugte Aufwand wird sehr, sehr
selten gelobt und ist mir auch gar nicht so wichtig. Natürlich freue ich
mich, wenn ich mit meinen Problemen Anderen helfen konnte und dies auch
noch erfahre.
Ich bin schon lange genug hier und lasse mich von den ganzen Trollen
auch nicht von dieser Richlinie abbringen und werde jetzt noch
verstärkter " Offtopic-Beiträge " ignorieren.
Ein " spassiges Experiment " trifft den Nagel auf den Kopf.
http://www.avr-asm-tutorial.net/avr_de/beginner/asm_beginner.html
Bernd_Stein
Bernd S. schrieb:> Das heißt für die Mitleser> einen Nutzen zu erbringen.
Tust Du aber nicht.
Niemand wird später was themenfremdes finden, was irgend jemand nach
gefühlt 1000 Posts mal unten angehängt hat.
Wer wirklich anderen helfen will, der erstellt zu jeder Frage auch ein
neues Topic. Und dann gibt es auch viel mehr Antworten dazu.
Bernd S. schrieb:> Der hierzu erzeugte Aufwand wird sehr, sehr> selten gelobt und ist mir auch gar nicht so wichtig.
Einen Hijacker loben, sonst noch Wünsche?
Peter D. schrieb:> Bernd S. schrieb:>> Das heißt für die Mitleser>> einen Nutzen zu erbringen.>> Tust Du aber nicht.> Niemand wird später was themenfremdes finden, was irgend jemand nach> gefühlt 1000 Posts mal unten angehängt hat.>
Ein Bild sagt mehr als tausend Worte. Mehr sage ich jetzt nicht.
Bernd_Stein
Bernd S. schrieb:> Ein Bild sagt mehr als tausend Worte.
Dann kommt man auf den Ursprungspost, scrollt vielleicht noch 10
Postings weiter und guckt dumm aus der Wäsche.
Warum willst Du unbedingt die Suche besonders schwer machen?
Bernd S. schrieb:> Bei einer Versorgungsspannung von 4,8V und einem Temperaturbereich von> -40°C bis 85°C entnehme ich den vorher geposteten Kennlinien eine> Differenz von 6kHz, was auf 128kHz bezogen eine Abweichung von knapp 5%> entspricht. Was mal wieder nicht so in meine Praxiserfahrung passt (> siehe 117kHz = -8,6% ).>
Habe mich in anderen Threads gewundert warum diese öfter dort erwähnten
+/- 10% Toleranz für den kalibrierten internen RC-Oszillator genannt
wurden.
Endlich habe ich es auch gefunden ( Calibrated Internal RC Oscillator
Accuracy -> siehe Screenshot ).
Bernd_Stein
Bernd S. schrieb:> was auf 128kHz bezogen
Jetzt fällt es mir erst auf, Du nimmst ja den WD-Oszillator. Der läßt
sich nicht kalibrieren und ist super ungenau.
Kalibriert ist nur der RC-Oszillator 9,6MHz.
Bei meinen Tests war er in der Regel so genau, daß es für eine UART
taugte.
Peter D. schrieb:> Jetzt fällt es mir erst auf, Du nimmst ja den WD-Oszillator. Der läßt> sich nicht kalibrieren und ist super ungenau.>
Oh, Mann ist dass wieder eine schwer zu überschaubare Sache. Und wieder
ein Bild ...
Danke.
Bernd_Stein
Bernd S. schrieb:> warum wird dies im AS7 mit debugWire im Einzelschritt nicht korrekt> ausgeführt?
Weil zwischen den Befehlen dank des "Eiznelschrittes" zu viele CPU-Takte
"vergehen"?
Aus dem RTFM:
1
Write the Clock Prescaler Change Enable (CLKPCE) bit to one and all other bits in CLKPR to zero.
2
Within four cycles, write the desired value to CLKPS while writing a zero to CLKPCE.
BTW:
Was kommt bei dieser Rechnung heraus:
~1<<CLKPCE|1<<CLKPS2|1<<CLKPS1|1<<CLKPS0
Wie sind die Prioritäten der drei Operanden?
Wenn du das nicht sofort sicher sagen kannst, dann fehlen da ein paar
Klammern.
Lothar M. schrieb:> Was kommt bei dieser Rechnung heraus:> ~1<<CLKPCE|1<<CLKPS2|1<<CLKPS1|1<<CLKPS0> Wie sind die Prioritäten der drei Operanden?> Wenn du das nicht sofort sicher sagen kannst, dann fehlen da ein paar> Klammern.>
Durch deine Anregung habe ich mal im Simulator verschiedene Sachen
ausprobiert. Die Klammersetzung war nicht dass eigentliche Problem,
sondern der Umstand dass der SBR-Befehl identisch mit dem ORI-Befehl
ist.
Ich lese ja das Clock Prescaler Register aus und überschreibe es per
OR-Befehl mit einer Maske ( ORI-Befehl ).
Mit OR kann man natürlich nur Bits setzen !!!
Das zweite Ueberschreiben per OR-Befehl mit 0 für CLKPCE bewirkt
natürlich nichts für dieses Bit.
Im Auslieferungszustand beginnend :
0000 0011 CLKPR
1000 0000 ORI
---------
1000 0011 CLKPR
0000 0111 ORI
---------
1000 0111 CLKPR
;
;Systemtakt ( 128kHz ) nochmals durch 128 teilen ( 1kHz )
;
Hat natürlich wie immer bei mir große Probleme verursacht, die ich euch
demnächst nicht vorenthalten werde.
Bernd S. schrieb:> Oliver S. schrieb:>> RTFM. In dem Fall das zu sbr.>>>>> Wer es nicht besser weiß, schreibt halt irgend einen Scheiß.>
Endschuldigung.
Hätte mir halt solch eine Ausführung gewünscht und dementsprechend
verstanden, was du mir damit mitteilen wolltest. Ich war so beschränkt
zu denken, es liegt am AS7 Assembler dessen Operatorfunktion : Bitweises
NOT nicht so arbeitet wie ich es glaubte.
Bernd_Stein
Bernd S. schrieb:> dass eigentliche Problem.. der Umstand dass der SBR-Befehl identisch> mit dem ORI-Befehl ist.> Mit OR kann man natürlich nur Bits setzen !!!
SBR heisst ja auch Set Bit in Register. Das Gegenstück dazu ist CBR
Clear Bit in Register.
Ich bin erstaunt, dass du etwas anderes erwartet hast.
Stefan ⛄ F. schrieb:> Ich bin erstaunt, dass du etwas anderes erwartet hast.>
Bei meinem verschrobenem Denken dachte ich, setze BitX = 0 ;-)
Bernd_Stein
Leider wieder einmal nicht in meiner Muttersprache :
https://www.youtube.com/watch?v=LquFL2dlvDE
Wer kennt Übungsaufgaben im www die genau das ab ca. 19:20 behandeln.
Also die wirkliche Subtraktion von vorzeichenbehafteten Dualzahlen, wo
der Subtrahend grösser ist als der Minuend.
Nicht die Additon des Zweierkomplements !
Ich glaub die Allerwenigsten raffen es wirklich, wie das hierbei mit dem
Borgen geht. Trotzdem Danke an :
https://www.youtube.com/watch?v=gdd_RR62HMk
Bernd_Stein
Verhält sich das V-Flag ( Zweierkomplement Überlauf / Unterlauf Anzeige
) bei der subtraktion genauso wie hier beschrieben ?
" Ein Überlauf bei vorzeichenbehaftet betrachteten Zahlen kann nur dann
auftreten, wenn beide Operanden negativ oder beide positiv sind und ein
Vorzeichenwechsel (Bit 7 kippt) erfolgt. "
Ich denke es ist der Vorzeichenbitwechsel im Ergebnis gemeint oder ?
Quelle :
Beitrag "Re: Overflow Bit bei Addition"
Nicht genug dass mich dieses V-Flag wahnsinnig macht, da muss mich
natürlich auch noch der scheiss Simulator von Microchip verarschen.
Übe gerade die wirkliche schriftliche Subtraktion von Dualzahlen, also
nicht die Addition mit dem Zweierkomplement.
0011 1111 $3F
-0111 1101 $7D
--------------
1100 0010 $C2
Warum wird dass V-Flag hier nicht gesetzt ?
Wie geht ihr vor um dass Setzen des V-Flags zu erkennen ?
Bernd_Stein
Peter S. schrieb:> Weil kein Überlauf stattfindet. $3f - $7d ist eine als 2-er complement> darstellbare zahl. (63-125=-62).>
Liest sich logisch, dann muss ich die Aussage in meinem Lehrbuch falsch
interpretieren oder es gilt nicht Allgemein, aber dann sollte es in
einem Lehrbuch wenigstens erwähnt werden und nicht den Anschein
erwecken, dass dies eine Regel für dass V-Flag wäre.
Es geht hier um AVR8-Assembler ( AVR8ASM ) :
V=1 => Rd7=0, Rr=0 & R7=1
=> Rd7=1, Rr=1 & R7=0
Gegenbeispiel :
$7F 127
+$01 + 1
---- -----
$80 -128
Hier ( bei der Addition ), passt es nämlich bei der vorzeichenbehafteten
Sichtweise. Ich addiere zwei positive Zahlen, jedoch dass Ergebnis ist
negativ, aber im erlaubten Zahlenbereich ( -128 <--- 0 ---> +127 ).
-128 ist ja auch eine als 2-er complemt darstellbare Zahl, wenn auch
eine böse ;-)
Beitrag "Re: Overflow Bit bei Addition"
Bernd_Stein
Bernd S. schrieb:> V=1 => Rd7=0, Rr=0 & R7=1> => Rd7=1, Rr=1 & R7=0
Steht das genau so in deinem Lehrbuch? Dann ist es ein Fehler.
Richtig wäre
V=1 <=> Rd7=0 & Rr7=0 & R7=1 |
Rd7=1 & Rr7=1 & R7=0
Yalu X. schrieb:> Bernd S. schrieb:>> V=1 => Rd7=0, Rr=0 & R7=1>> => Rd7=1, Rr=1 & R7=0>> Steht das genau so in deinem Lehrbuch? Dann ist es ein Fehler.>> Richtig wäre>> V=1 <=> Rd7=0 & Rr7=0 & R7=1 |> Rd7=1 & Rr7=1 & R7=0>
Für mich schreibst du dass Selbe. Jetzt mal in Worten:
" Wenn beide Operatoren dass gleiche Vorzeichen haben, aber das Ergebnis
ein anderes, dann wird das V-Flag gesetzt ( V= 1 ) ".
So ist es auch mit der Logik im Rechenwerkmodell des Schaubildes
dargestellt.
Bernd_Stein
Bernd S. schrieb:> Für mich schreibst du dass Selbe. Jetzt mal in Worten:
In der ursprünglichen Version fehlt bei Rr der Index (7). Außerdem ist
nicht ganz klar, was die Kommata bedeuten sollen. Letztendlich stehen
sie genauso wie das "&" für ein logisches "und". Schließlich muss der
zweite Folgepfeil ein logischen "oder" sein.
> " Wenn beide Operatoren dass gleiche Vorzeichen haben, aber das Ergebnis> ein anderes, dann wird das V-Flag gesetzt ( V= 1 ) ".
Genau, das ist die Aussage. Der Vollständigkeit halbe könnte man noch
das "Wenn" durch "Genau dann, wenn" ersetzen um auszudrücken, dass in
allen anderen Fällen V=0 wird.
Aber dann ist doch alles in Ordnung. Wo siehst du da einen Widerspruch?
Yalu X. schrieb:> In der ursprünglichen Version fehlt bei Rr der Index (7). Außerdem ist> nicht ganz klar, was die Kommata bedeuten sollen.> ...>
Danke, ich brauch wohl mal eine Pause, meine Schusseligkeitsfehler
machen Euch wahrscheinlich auch noch wahnsinnig.
Hier noch mal mein Problem, dass beide Operatoren positiv sind und das
Resultat ( Ergebnis ) negativ, aber das V-Flag = 0.
Bernd S. schrieb:> Übe gerade die wirkliche schriftliche Subtraktion von Dualzahlen, also> nicht die Addition mit dem Zweierkomplement.>> 0011 1111 $3F> -0111 1101 $7D> --------------> 1100 0010 $C2>> Warum wird dass V-Flag hier nicht gesetzt ?>> Wie geht ihr vor um dass Setzen des V-Flags zu erkennen ?>
Bernd S. schrieb:> Hier noch mal mein Problem, dass beide Operatoren positiv sind und das> Resultat ( Ergebnis ) negativ, aber das V-Flag = 0.
Ach so, jetzt verstehe ich dein Problem.
Bernd S. schrieb:> " Wenn beide Operatoren dass gleiche Vorzeichen haben, aber das Ergebnis> ein anderes, dann wird das V-Flag gesetzt ( V= 1 ) ".
Diese Regel gilt nur für die Addition. Für die Subtraktion heißt die
Regel:
"Wenn das Ergebnis und der zweite Operand (Subtrahend) das gleiche
Vorzeichen haben, aber der erste Operand (Minuend) ein anderes, dann
wird das V-Flag gesetzt (V=1)"
Das ergibt sich aus der obigen Regel für die Addition und dem folgenden
Zusammenhang:
Ergebnis = Minuend - Subtrahend
<=> Minuend = Ergebnis + Subtrahend
Es ist so, mit 8-bit kann man ganze Zahlen im Bereich -128 bis 127
darstellen (2-er complement). Das V Flag wird dann gesetzt wenn das
Resultat der Addition oder Subtraktion, durchgeführt im Bereich der
ganzen Zahlen, nicht mehr in diesem Bereich liegt. Z.Bsp. (wir verwenden
SUB und ADD, nicht SBC, ADC, das braucht man erst bei Erweiterungen auf
16-, 32-, .. bit)
127+1 = 128 liegt nicht mehr im Bereich -128 bis 127 -> V gesetzt
$3f-$7d = 63 - 125 = -62 liegt im Bereich -128 bis 127 -> V nicht
gesetzt
$C2-$7D = -62 - 125 = -187 liegt nicht im Bereich -128 bis 127 -> V
gesetzt
$C2-$FF = -62 - -1 = -61 liegt im Bereich -128 bis 127 -> V nicht
gesetzt
Das gilt dann auch für 16-bit, 32-bit etc. arithmetik.
Hallo zusammen,
da ich mich in der Praxis bisher nie mit vorzeichenbehafteten Zahlen
herumschlagen musste, fällt es mir schwer den Sinn des S-Flags zu
verstehen.
Als Unterscheidung, ob eine Bitkombination nun als negative oder
positive Zahl gewertet werden soll, dient doch schon das N-Flag.
Das das S-Flag ja in Verbindung mit dem V-Flag steht, verstehe ich auch
nicht, was es bringen soll, wenn V=1 anzeigt, also das Ergebnis der
Rechnung eh falsch ist, es dann doch von Nutzen sein soll, dass dieses
falsche Ergebnis aber anhand des S-Flags nun das richtige Vorzeichen
anzeigt.
Dieses hier läßt mich vermuten, dass das S-Flag nur die Befehle BRGE &
BRLT bedient und ansonsten uninteressant ist.
https://www.mikrocontroller.net/articles/AVR-Tutorial:_Vergleiche#Signed_.28S.29
Bernd_Stein
Den Sinn habe ich selber nicht herausfinden können und muss somit
glauben, dass der wirklich Nutzbare darin besteht, dass man wie beim
C-Flag bestimmen kann, ob ein Wert gleich, kleiner oder größer als der
Andere ist.
Dies natürlich für negative Werte z.B. Rd= -4 & Rr= -3 -> S=1.
S=1 bei Rd kleiner Rr ( S=1 (-)Rd < (-)Rr ).
Bernd_Stein
Jimi H. schrieb:> http://www.rjhcoding.com/avr-asm-sreg.php>
Der Vorzeichenmerker (S)
Der Vorzeichenmerker ist ein zusätzliches Logikbit, mit dem bestimmt
werden kann, ob das Ergebnis einer vorherigen Operation positiv oder
negativ ist. Es handelt sich um die exklusive ODER-Verknüpfung des
Negativ- und des Zweierkomplement-Überlauf-Flags. Es wird gesetzt, wenn
das eine oder das andere gesetzt ist, aber nicht beide.
Betrachten wir die Subtraktion von 10 von -120. Es ist offensichtlich,
dass das Ergebnis -130 ist, aber wenn wir dies versuchen
ldi r16,0x88 ; lade r16 mit 0x88 (-120)
ldi r17,0x0A ; lade r17 mit 0x0A (10)
sub r16,r17 ; subtrahiere r17 von r16 (Ergebnis = 0x7E = 126)
Das Ergebnis ist nicht -130, da dieser Wert für eine 8-Bit-Zahl mit
Vorzeichen zu groß ist. Nach dem Sub-Befehl wird der Negative Flag nicht
gesetzt, da Bit 7 des Ergebnisses gelöscht ist. Der Vorzeichenmerker
wird jedoch gesetzt, was korrekt anzeigt, dass das Ergebnis negativ sein
sollte.
Betrachten Sie stattdessen die Addition
ldi r16,0x78 ; lade r16 mit 0x78 (120)
ldi r17,0x0A ; lade r17 mit 0x0A (10)
add r16,r17 ; addiere r17 zu r16 (Ergebnis = 0x82 = 130)
Hier wird das Negative Flag gesetzt, obwohl das Ergebnis eindeutig
positiv ist. Da jedoch ein Zweierkomplement-Überlauf auftrat, wird der
Vorzeichenmerker nicht gesetzt, was korrekt anzeigt, dass das Ergebnis
positiv ist.
Die Verwendung des Vorzeichen-Flags kann Ihnen eine bessere Vorstellung
davon vermitteln, ob ein Ergebnis positiv oder negativ ist. Es ist sehr
nützlich bei der Erstellung alternativer Verzweigungen, um Fälle wie die
oben gezeigten zu behandeln.
Übersetzt mit www.DeepL.com/Translator (kostenlose Version)
Toll, erklärt jedoch immer noch nicht meine Frage :
Bernd S. schrieb:> Als Unterscheidung, ob eine Bitkombination nun als negative oder> positive Zahl gewertet werden soll, dient doch schon das N-Flag.>> Das das S-Flag ja in Verbindung mit dem V-Flag steht, verstehe ich auch> nicht, was es bringen soll, wenn V=1 anzeigt, also das Ergebnis der> Rechnung eh falsch ist, es dann doch von Nutzen sein soll, dass dieses> falsche Ergebnis aber anhand des S-Flags nun das richtige Vorzeichen> anzeigt.>> Dieses hier läßt mich vermuten, dass das S-Flag nur die Befehle BRGE &> BRLT bedient und ansonsten uninteressant ist.>
Bernd_Stein
Bernd S. schrieb:> Dieses hier läßt mich vermuten, dass das S-Flag nur die Befehle BRGE &> BRLT bedient und ansonsten uninteressant ist.
Richtig. Das ist eine Besonderheit der AVRs.
Etliche Architekturen haben für Nutzung durch Sprungbedingungen die 4
Flags N=negative, Z=zero, V=overflow, C=carry, wenngleich nicht durchweg
mit diesen Namen. In den Sprungbedingungen können dann schon mal
komplizierte Terme stehen, die gleich 2-3 Flags auswerten, wie N,V für
GE/LT und N,V,Z für GT/LE.
AVRs jedoch testen in den Sprungbedingungen stets exakt ein Flag. Das
macht es notwendig, bereits die Flags passend zu definieren und es führt
zu diesem S-Flag. Man neigt allerdings gerne dazu, es mit dem S-Flag der
x86 zu verwechseln, das dem N-Flag der AVRs entspricht.
Hintergrund ist eine Vereinfachung der Implementierung. Denn dadurch
ähnelt die Arbeitsweise der bedingten Sprungbefehle den Befehlen
SBIS/SBIC, angewandt auf das Statusregister, manifestiert in den
eigentlichen bedingten Sprungbefehlen BRBS,BRBC. BRGE ist nur eine
elegante Schreibweise des Befehls BRBC d,4.
Diese Eigenheit erklärt auch, weshalb es bei AVRs zwar die eher selten
genutzten Befehle BRIE,BRID gibt, nicht aber die Vergleiche > und <=,
mit und ohne Vorzeichen.
(prx) A. K. schrieb:> Bernd S. schrieb:>> Dieses hier läßt mich vermuten, dass das S-Flag nur die Befehle BRGE &>> BRLT bedient und ansonsten uninteressant ist.>> Richtig. Das ist eine Besonderheit der AVRs.>> Etliche Architekturen haben für Nutzung durch Sprungbedingungen die 4> Flags N=negative, Z=zero, V=overflow, C=carry, wenngleich nicht durchweg> mit diesen Namen. In den Sprungbedingungen können dann schon mal> komplizierte Terme stehen, die gleich 2-3 Flags auswerten, wie N,V für> GE/LT und N,V,Z für GT/LE.>> AVRs jedoch testen in den Sprungbedingungen stets exakt ein Flag. Das> macht es notwendig, bereits die Flags passend zu definieren und es führt> zu diesem S-Flag.> ...>
Danke (prx) A. K.,
dies ist eine super Erklärung die ich glauben und verstehen kann.
Unglaublich ich habe etwas richtig vermutet ;-).
(prx) A. K. schrieb:> Diese Eigenheit erklärt auch, weshalb es bei AVRs zwar die eher selten> genutzten Befehle BRIE,BRID gibt, nicht aber die Vergleiche > und <=,> mit und ohne Vorzeichen.>
Dies ist mir jetzt allerdings schon wieder zu hoch, wie man auf solch
eine Schlußfolgerung kommt.
Ist > und <= nicht durch vertauschen der Operanden hinzu kriegen ?
Bernd_Stein
Hier ist doch was faul. Einsprung bei dec_out:
Bei einer dreistelligen Zahl z.B. 255, werden die Hunderter richtig
angezeigt, für die Zehner wird Space ( $20 ) erzeugt und ...
Bernd S. schrieb:> Hier ist doch was faul.
Weil der Code von peda ist versteige ich mich zu der Behauptung: Ich
glaube, du liegst falsch.
> Bei einer dreistelligen Zahl z.B. 255, werden die Hunderter richtig> angezeigt, für die Zehner wird Space ( $20 ) erzeugt
Hast du das ausprobiert? Woher soll denn das Space überhaupt kommen?
> und ...
Und was?
c-hater schrieb:> Mit der Zeit lernt man es, seine Programmier-Ziele als logisch> konsistente Abstraktion formulieren zu können.
Sorry, aber so ein abgehobener Satz in Verbindung mit:
> Fachbücher sind Mist, die kosten nur unnötig Geld und veralten schneller> als das Papier verrotten kann, auf dem sie gedruckt sind.
zeugt einfach nur von undurchdachtem Gelaber. Ohne Fachbücher, z.B. über
höhere Algorithmen, kommt beim Coden eben doch nur ineffizientes
Herumgehacke heraus, das man in einem größeren Projekt besser wieder
entfernt, da viel zu fehlerträchtig.
> Der Rest, nämlich den Kram dann mit den Mitteln der> verfügbaren Sprache in ein funktionierendes Programm zu verwandeln, ist> dann nur noch Handwerk. Eigentlich nur sowas wie eine Übersetzung.
Das ist zum größten Teil falsch.
Aber er dauert eben viele Jahrzehnte, bis man vieles durchschaut und
tatsächlich ein wirklich erfahrener Programmierer ist.
Justin S. schrieb:>> Der Rest, nämlich den Kram dann mit den Mitteln der>> verfügbaren Sprache in ein funktionierendes Programm zu verwandeln, ist>> dann nur noch Handwerk. Eigentlich nur sowas wie eine Übersetzung.
Blödsinn....brauchst dich ja hier nur umschaun...und du siehst das
Hanwerk blühen.
Rainer
Lothar M. schrieb:>> Bei einer dreistelligen Zahl z.B. 255, werden die Hunderter richtig>> angezeigt, für die Zehner wird Space ( $20 ) erzeugt> Hast du das ausprobiert? Woher soll denn das Space überhaupt kommen?>
Vermutlich hast du Recht, denn PeDa steuert das LCD über einen Chip an,
welcher die Daten seriell bekommt.
Einfach mal a0 = $FF setzen, bei
_dou5:
rjmp lcd_data
rjmp lcd_data durch ret ersetzen und dies dann im Simulator beobachten.
Dann siehst du wie Space zu stande kommt und ..., was halt mit der
Einer-Stelle falsch läuft. Richtig müsste in der Zeile _dou5: nach
einander 2, 5, 5 erscheinen.
Hier ist übrigens die Quelle des Übels ;-)
Beitrag "Zeit + Temperatur auf LCD mit AVR"
Bernd_Stein
Bernd S. schrieb:> Hier ist übrigens die Quelle des Übels ;-)>> Beitrag "Zeit + Temperatur auf LCD mit AVR"
Danke für den Link. Sollte ein Fragesteller immer machen, wenn er was
aus dem Kontext heraus reißt.
Bernd S. schrieb:> Hier ist doch was faul. Einsprung bei dec_out:> Bei einer dreistelligen Zahl z.B. 255, werden die Hunderter richtig> angezeigt, für die Zehner wird Space ( $20 ) erzeugt und ...
Wie schon gesagt, es wird am Aufrufer liegen. Die Funktion selber gibt
nur 1..3 Ziffern linksbündig aus.
Peter D. schrieb:> Wie schon gesagt, es wird am Aufrufer liegen. Die Funktion selber gibt> nur 1..3 Ziffern linksbündig aus.>
Erst mal Entschuldigung, denn nur in meiner Birne ist etwas faul.
Und Danke für solch eine Trickreiche "Byte in ASCII" Routine.
Habe natürlich wieder Schusseligkeitsfehler gemacht und nicht verstanden
wie das Ganze funktioniert, also dementsprechend zusätzlichen Mist
gebaut.
Lernt man solche Programmiertricks in der Ausbildung oder kommt man im
Laufe der Berufserfahrung auf so etwas ?
Bernd_Stein
Bernd S. schrieb:> Lernt man solche Programmiertricks in der Ausbildung oder kommt man im> Laufe der Berufserfahrung auf so etwas ?
Erfahrung. In der Ausbildung lernt man natürlich auch was, aber das
Lernen endet bei Softwareentwicklern nie.
Hallo zusammen,
jetzt mal ein anderes Problem bei der AVR8-Assemblerprogrammierung.
Der DS18B20 hat ja eine Auflösung von 12-Bit.
Wie sieht eine AVR8ASM-Routine aus, die die volle Auflösung auf einem
LCD anzeigt ?
Ich weiß er hat nur eine Genauigkeit von +/- 0,5°C und das Ganze macht
wenig Sinn, aber ich möchte trotzdem mal eine AVR8ASM-Routine sehen und
verstehen, die z.B. 21,0625°C oder 21,9375°C auf einem LCD anzeigt (
2^-4 oder 2^-1 + 2^-2 + 2^-3 + 2^-4 ).
Bernd_Stein
Bernd S. schrieb:> Ist > und <= nicht durch vertauschen der Operanden hinzu kriegen ?
Weshalb das nicht weiter stört. Und beim Vergleich mit einer Konstanten
(CPI) kommt man mit Anpassung der Konstanten weiter. Das fällt lediglich
auf, wenn man diverse andere Architekturen kennt, die trotzdem den
vollständigen Satz an Bedingungen bieten.
Bernd S. schrieb:> aber ich möchte trotzdem mal eine AVR8ASM-Routine sehen und> verstehen, die z.B. 21,0625°C oder 21,9375°C
Also erstens mal halte ich Dich für fähig die selber zu entwickeln
da ich Dir sonst zweitens unterstellen würde hier nur bequem Aufträge
für andere zu erteilen die drittens im Grundsatz simpel umzusetzen sind:
Mit Rechenoperationen hinreichender Stellenanzahl arbeiten und Ergebnis
in ASCII umwandeln ist jetzt nicht das große Problem. Und nein, ich
machs trotzdem nicht für Dich weil ich die Routine nicht brauche. Auf
die Sinnlosigkeit der Aufgabenstellung in Zusammenhang mit der
Genauigkeit des DS18B20 hattest Du ja dankenswerterweise schon
hingewiesen. So wie Temperaturmessungen dieser Stellenzahl hinter dem
Komma überhaupt meist wenig bringen.
Bernd S. schrieb:> aber ich möchte trotzdem mal eine AVR8ASM-Routine sehen und verstehen,
Wenn du weißt wie man den ganzzahligen Anteil anzeigt, und wie man eine
Tabelle mit 16 Einträgen verwendet, dann kennst du einen möglichen Weg..
Jimi H. schrieb:> So wie Temperaturmessungen dieser Stellenzahl hinter dem Komma überhaupt> meist wenig bringen.
Die 16tel Grade der Sensoren sind zwar ungenau, aber der Trend einer
Temperaturveränderung lässt sich daraus sehr wohl ablesen.
(prx) A. K. schrieb:> Jimi H. schrieb:>> So wie Temperaturmessungen dieser Stellenzahl hinter dem Komma überhaupt>> meist wenig bringen.>> Die 16tel Grade der Sensoren sind zwar ungenau, aber der Trend einer> Temperaturveränderung lässt sich daraus sehr wohl ablesen.
Also erstens ist wenig ungleich gar nichts, zweitens die Diskussion ab
welcher Stelle nun wirklich jeder Sinn verloren geht´eine um des Kaisers
Bart und drittens die praktische Relevanz jedweder Temperaturänderung ab
der zweiten Stelle hinter dem Komma oft nicht mehr gegeben da hochgradig
variabel je nach Ort und Installation (im Falle etwa eines
Außentemperatursensors).
Bernd S. schrieb:> Wie sieht eine AVR8ASM-Routine aus, die die volle Auflösung auf einem> LCD anzeigt ?
Für 1/16 muß man den Wert mit 1000 multiplizieren und dann ein gedachtes
Komma vor das 3-letzte Digit setzen.
Für negativ festellen, ob negativ, den Betrag bilden (x=0-x) und ein '-'
davor ausgeben.
Im Prinzip löst man Aufgaben in Assembler genau so, wie in Hochsprachen,
d.h. man zerlegt das Problem in einzelne Schritte. In Hochsprachen hat
man aber oft schon fertige Libs für Grundlagen, z.B. float für
Kommazahlen.