Hallo,
ich habe ein ATtiny 26 Mikrocontroller und ein LCD, ich möchte diesen
LCD entsprechen programmieren. Ich habe mir die Seite AVR-Tutorial:LCD
(http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD) durch
gelesen und bin bei der Warteschleife hängen geblieben. Da ich ein
absoluter Beginner bin und bisher gar keine Erfahrungen auf diesem
Gebiet habe, verstehe ich nicht was da genau passiert und warum. Kann
mir jemand diesen Code schrittweise erklären??? ich weiß nicht warum
beispielsweise $21 oder $C9 genommen wurde? Da ich Attiny26 (8Mhz)
verwende, müsste ich noch eine Warteschleife dazufügen.
A.B.C schrieb:> Da ich ein> absoluter Beginner bin und bisher gar keine Erfahrungen auf diesem> Gebiet habe, verstehe ich nicht was da genau passiert und warum.
Da wäre es sinnvoll, wenn Du nicht mit Assembler sondern mit C
programmierst.
Versuchs mal bei Google: AVR LCD.
Peter schrieb:> Da wäre es sinnvoll, wenn Du nicht mit Assembler sondern mit C> programmierst.
Einspruch!
Es ist vollkommen scheiXegal, womit man anfängt.
Grundlagen lernen, das ist der Punkt!
Wenn man nicht weiß was die Befehle tun, dann schaut man sie sich im
Handbuch an. Die Zeiten stehen dabei. Takte zählen also kein Problem.
PS:
Bin selber OOP Fan.
ldi temp1, $21 Äußerer Zähler auf 33 setzen
WGLOOP0: ldi temp2, $C9 Innerner Zähler auf 201 setzen
WGLOOP1: dec temp2 Innerer Zähler um eins verringern
brne WGLOOP1 Solange bis der innere Zähler auf 0 ist
dec temp1 Äußerer Zähler um eins verringern
brne WGLOOP0 Zurück zur Inneren Schleife bis äußserer
Zähler auf 0 ist
ret Ende der Warteschleife
Das ganze sind 2 Schleifen die bei 4MHz Taktfrequenz oft genug
durchlaufen werden (jeder Befehl braucht n Takte zur Abarbeitung) das
eine 5ms Verzögerung entsteht.
Bei 8MHz müssten also aus der $21 einfach eine $42 vgemacht werden um
die selbe Verzögerung zu erhalten ($C9 * 2 = $192, passt also nicht mehr
in ein 8 Bit Register).
A.B.C schrieb:> @Ulrich: In welchem Handbuch?
im Datenblatt des Prozessors gibt es eine Liste der Befehle, und im
online-Handbuch zum AVR Assembler (-> Startseite im Atmel-Studio) sind
die Befehle auch einzeln beschrieben. Sonst gibt auch Google unter "AVR
Assembler" jede Menge Lesestoff...
Danke mir ist jetzt klar wie die Befehle funktionieren :dec ->
dekrementieren also um eins verringern usw...
Ich muss nur noch verstehen, nach welchen Kriterien ich die Durchläufe
($21, $c9) wähle bzw wie ich diese definiere.....
A.B.C schrieb:> Ich muss nur noch verstehen, nach welchen Kriterien ich die Durchläufe> ($21, $c9) wähle bzw wie ich diese definiere.....
Einfach so, daß die Ausführungszeit pro Befehl mal die Durchläufe deine
gewünschte Zeit ergibt. Mehr Geheimnis gibts da nicht :-)
Sicherlich wird es mehrere Möglichkeiten / Kombinationen geben, mit
denen du auf die gewünschte Zeit kommst. Aber welche du davon nimmst,
ist dir überlassen.
A.B.C schrieb:> Ich habe mir die Seite AVR-Tutorial:LCD [...]> durchgelesen und bin bei der Warteschleife hängen geblieben.
und ich bin grade in 'ner Lach-Schleife hängengeblieben. ;)
Danke dafür
Hi
Vielleicht hilft es, wenn du dir das Datenblatt deines Controllers
ansiehst. Du bekommst es bei ATMEL oder manchmal führt die Suche über
Google weiter. Im Teil "Instruction Set Summary" findest du alle Befehle
und die zur Ausführung erforderlichen Takte. Angenommen, dein Controller
läuft mit 8 MHz dann ist 1/8000000 die Zeit, die ein Takt braucht, also
0,000000125 s oder 125 ns. Ein Befehl wie DEC Register benötigt einen
Takt, die Auswertung auf 0 incl. Sprung 2 Takte. Setzt du das Register
vor der Schleife auf 100 dann benötigt die Schleife 300 * 125 ns. oder
eben 37,5 µs. Willst du 5 ms Erreichen, musst du nur richtig rechnen.
Aber auch alle Befehle berücksichtigen. Dazu brauchst du eben die Info
aus dem Datenblatt. Der Rest ist eben Mathe.
Gruß oldmax
Vielen Dank für die Antwort..
Ich bin auch dabei die Berechnung zu verstehen..
ich habe mir zur Hilfe das Flussdiagramm gezeichnet, um die Berechnung
aus AVR nachzuvollziehen...
A.B.C schrieb:> Ich bin auch dabei die Berechnung zu verstehen..
---Das ist die äußere Schleife---
ldi temp1, $21 ;1 Takt
--- Das ist die innere Schlefe---
ldi temp2, $C9 ;1 Takt
---Hier wird die innere Schleife abgearbeitet----
dec temp2 ;1 Takt
brne WGLOOP1 ;Sprung 2 Takte, sonst 1 Takt
---Hier wird äußere Schleife abgearbeitet----
dec temp1 ;1 Takt
brne WGLOOP0 ;Sprung zwei Takte, sonst 1 Takt
Aus AVR : Was geht hier vor? Die innere Schleife benötigt wieder 3 Takte
pro Durchlauf. Bei $C9 = 201 Durchläufen werden also 201 * 3 = 603 Takte
verbraucht. In der äußeren Schleife werden pro Durchlauf also 603 + 1 +
2 = 606 Takte verbraucht und einmal 605 Takte (weil der brne nicht
genommen wird). Da die äußere Schleife $21 = 33 mal wiederholt wird,
werden 32 * 606 + 605 = 19997 Takte verbraucht.---????
Innere Schleife benötigt doch 4 Takte (ldi, dec , brne
(Schleifendurchlaug))?
Dann werden für den äußeren Durchlauf zu den Takte der inneren Schleife
(603 Takte) drei (1+2) Takte dazu addiert. Um welchen Takten handelt es
sich bei den dreien?
:-=
Peter M. schrieb:> A.B.C schrieb:>> Ich habe mir die Seite AVR-Tutorial:LCD [...]>> durchgelesen und bin bei der Warteschleife hängen geblieben.>> und ich bin grade in 'ner Lach-Schleife hängengeblieben. ;)>> Danke dafür
Super :D
Peter schrieb:> Da wäre es sinnvoll, wenn Du nicht mit Assembler sondern mit C> programmierst.
Krasser Unsinn.
Mod
Den üblichen C Bashing entsorgt.
c-hater: eine Warnung. Achte auf deine Wortwahl. Die Mods sind sich
einig, dass wir deine fäkale Ausdrucksweise nicht mehr länger tolerieren
werden.
Die ultimative Befehlsliste mit Taktzyklen, beeinflussten Flags usw. ist
AVR 0856 - 8-Bit AVR Instruction Set:
http://www.atmel.com/Images/Atmel-0856-AVR-Instruction-Set-Manual.pdf
680 lohnenswerte kByte.
Man beachte, das nicht alle AVR auch alle Befehle bereitstellen, auch
sind z.B. die RAMP Register nicht in allen AVR enthalten.
Der Kernighan/Ritchie "The C Programming Language" hat 274 Seiten.
Mehr braucht man nicht.
Damit habe ich bisher alle Prozessoren, und das waren mehr als 1
Dutzend, bezwungen.
Es ist natürlich auch so, daß man C nur schreiben kann, wenn man ASM
versteht, oder was? Also ich kann beides und Rate mal, was ich vorziehe.
Für Anfänger haben schnelle Erfolge alá Arduino den Vorteil, daß die
Hardware funktioniert und ein C-Compiler "etwas mehr"
Plausibilitätsprüfungen macht, als ein Assembler. Den stört es nämlich
nicht, wenn man Daten überschreibt, die man eigentlich konstant halten
wollte, uvm.
Also nicht 332+274, sondern nur ein paar Tutorials zum ersten
Erfolgserlebnis und wenn dann noch mehr wissen will, dann schaut man
irgendwann die .lss-Datei an. Lernen braucht nämlich Erfolge, auch wenn
sich das bei unseren Pädagogen noch nicht rumgesprochen hat.
Bastler schrieb:> ....und ein C-Compiler "etwas mehr"> Plausibilitätsprüfungen macht, als ein Assembler. Den stört es nämlich> nicht, wenn man Daten überschreibt, die man eigentlich konstant halten> wollte, uvm.
Bei Assembler ist man aber komplett für das verantwortlich, was man tut.
Bei Fehlern kann man sich leichter erklären, was passiert sein muß, weil
der Quelltext gut durchschaubar ist, In C kann bzw. muß man allen
möglichen Kram inkludieren, den andere Leute geschrieben haben. Das
kann richtig sein, muß aber nicht.
Da ist mir ein Assembler Quelltext, den ich erst dann in den Rechner
wämmere, wenn ich ihn von Hand auf dem Papier durchsgespielt habe 10x
lieber.
(Na, sagen wir 16x, das läßt sich besser handhaben.)
;-)
MfG Paul
Paul B. schrieb:> In C kann
Das ist richtig. In ASM kann man auch fremden code verwenden.
Paul B. schrieb:> muß man allen möglichen Kram inkludieren
Das ist falsch.
Wobei gerade das Arduino Zeug zum Einstieg nicht so verkehrt ist.
Ich persönlich habe mit ASM angefangen und hab dann nach C gewechselt.
Das ist nun 18 Jahre her.
Beruflich wird mittlerweile alles nur noch in C++ programmiert, ja auch
uC!
Alleine wegen der Portierbarkeit. Ob Atmel, PIC, TI oder Infineon...
alles das selbe.
PIC gibt's auch in den Geschmacksrichtungen PDP11 (PIC24) oder MIPS
(PIC32). Beides gestandene Rechner und nicht nur mikroprogrammierbare
Logikbausteine.
C > ASM schrieb:> Frank schrieb:> C++ PIC>> Klingt interessant, welchen Kompiler nimmst du dafür?
Stimmt, da hast du mich erwischt. Das einzige Projekt wo wir einen PIC
einsetzen ist noch Objektive C.
Taugt der MPLAB XC32++ nichts?
Hi
Leute, was soll die Diskussion um Assembler und C? Gerade diese Aufgabe
ist doch so simpel und ideal, einmal dei benötigte Zeit zur
Befehlsausführung zu berechnen. Da muss man nicht einen von C erstellten
Assemblercode nachvollziehen, sondern kann gleich mit der Berechnung
loslegen. Jede Programmiersprache hat seine Daseinsberechtigung und es
ist doch jedem selbst überlassen, was er benutzt. Der sinnlose Quatsch
über Umfang von Lehrmaterial bringt doch nix. Wer sich mit C beschäftigt
wird wissen, wieviel Material durchzuarbeiten ist, um brauchbare
Ergebnisse zu bekommen. Gleiches trifft auf alle anderen Sprachen
einschließlich Assembler zu. Die einzige Hilfe, die hier geboten werden
kann ist die Erklärung, warum ein Code bei der Bearbeitung Zeit benötigt
und wieviel. im gegensatz zu menschlichem Denken ist hier von einer
festen Größe aus zu gehen. Ein Befehl sind eins. zwei oder 4 Takte und
wenn alle Befehle erfasst und berechnet sind. läßt sich eine Zykluszeit
mit den normalen Grundrechenarten bestimmen. Mag ja sin, dasa da
komfortable C-Compiler unterstützen, mir fehlt da die Erfahrung, aber
diese missionarischen Ansätze in den Diskussionen um Programmiersprachen
sind echt überflüssig.
Gruß oldmax
c-hater: eine Warnung. Achte auf deine Wortwahl. Die Mods sind sich
einig, dass wir deine fäkale Ausdrucksweise nicht mehr länger tolerieren
werden.
Aus der Zone zu kommen ist keine Entschuldigung für unzivilisiertes
Verhalten. Ich werde in Zukunft deine Postings nicht mehr moderieren
sondern einfach löschen sollte sich deine allgemeine Ausdrucksweise
nicht bessern. Wir lassen hier ohnehin so einiges durchgehen, was ich
bei mir zu Hause nicht tolerieren würde. Aber irgendwann ist jedes Fass
voll.
gez.
Karl Heinz
A.B.C schrieb:> Aus AVR : Was geht hier vor? Die innere Schleife benötigt wieder 3 Takte> pro Durchlauf. Bei $C9 = 201 Durchläufen werden also 201 * 3 = 603 Takte> verbraucht. In der äußeren Schleife werden pro Durchlauf also 603 + 1 +> 2 = 606 Takte verbraucht und einmal 605 Takte (weil der brne nicht> genommen wird). Da die äußere Schleife $21 = 33 mal wiederholt wird,> werden 32 * 606 + 605 = 19997 Takte verbraucht.---????>>> Innere Schleife benötigt doch 4 Takte (ldi, dec , brne> (Schleifendurchlaug))?
der ldi wird (im Tutorial) nicht zur inneren Schleife dazugerechnet,
weil diese Instruktion in der inneren Schleife ja nicht dauern
wiederholt wird. Dieser 1 Takt ist in der Berechnung der äusseren
Schleife drinnen. (Sollte zumindest, noch kann ich den in der Berechnung
nicht entdecken. Ich denke da steckt tatsächlich ein Fehler)
Wenn du ausrechnen willst, wieviele Takte eine Schleife benötigt, dann
darfst du logischerweise auch nur die Befehle zählen, die wiederholt
abgearbeitet werden.
Wenm du wissen willst, wie lange die Fertigung von 1 Million
Joghurtbecher benötigt, dann rechnest du ja auch nur den Tiefziehvorgang
mal 1 Million. Die Zeit, die der Maschinenbetreuer benötigt um die Form
in die Maschine zu spannen wird ja nicht 1 Million mal benötigt sondern
nur 1 mal.
Fertigst du aber 5 verschiedene Becher jeweils 1 Million mal, dann
rechnest du die Produktionszeit für 1 Becher mal 5. Die komplette
Produktionszeit setzt sich aber zusammen aus einmalig der
Formeinspannzeit und 1 Million Zeiten für das Ziehen der Becher.
Karl H. schrieb:> Schleife drinnen. (Sollte zumindest, noch kann ich den in der Berechnung> nicht entdecken. Ich denke da steckt tatsächlich ein Fehler)
Ach klar.
Der 1 Takt ist schon berücksichtigt. Allerdings könnte man das besser
formulieren.
Der letzte Durchlauf durch die innere Schleife dauert ja 1 Takt weniger,
weil der brne nicht genommen wird. Genau das ist rechnerisch der 1 Takt,
der im Gegenzug einmalig für die 'Initialisierung der inneren Schleife'
durch den ldi drauf geht.
Karl H. schrieb:> Aus der Zone zu kommen ist keine Entschuldigung für unzivilisiertes> Verhalten.
Das zeugt auch nicht gerade von zivilisiertem Verhalten, sorry!
Draco schrieb:> Karl H. schrieb:>> Aus der Zone zu kommen ist keine Entschuldigung für unzivilisiertes>> Verhalten.>> Das zeugt auch nicht gerade von zivilisiertem Verhalten, sorry!
Du kennst c-hater anscheinend noch nicht lange genug. Das Argument 'Ich
komme aus der Zone' stammt von ihm.
Abgesehen davon stösst es uns mitlerweile schon sauer auf, dass jedes 3
Wort 'scheisse' oder 'Drecksding' oder dergleichen ist. Krönung war wohl
das mitlerweile entsorgte 'Arschloch'. Sorry. wenn das die
Ausdrucksweise ist, mit der er im Forum zu glänzen gedenkt, dann können
wir gerne auf ihn verzichten.
Meinungsfreiheit bedeutet nämlich nicht, dass ihm jeder eine Plattform
zur Verfügung stellen muss.
Hi,
den Code aus AVR habe ich verstanden:
Längere Pause für manche Befehle
delay5ms: ; 5ms Pause (bei 4 MHz)
ldi temp1, $21
WGLOOP0: ldi temp2, $C9
WGLOOP1: dec temp2
brne WGLOOP1
dec temp1
brne WGLOOP0
ret ; wieder zurück
Jetzt möchte ich einen ähnlichen Code für 5ms Pause bei 16 MHz
(Attiny26) schreiben. Ich wollte noch zusätzlich eine dritte Schleife
einfügen.
16 MHz entsprechen 16 000000 Takte pro Sekunde.
5ms *16000000= 800000 Takte---> pro schleife werden ca. 3 Take (dec,
brne) gebraucht--->
Mit dieser Rechnung möchte ich jeweils die Durchläufe ermitteln. Ist
mein Vorgehensweise richtig ?