Es sollen 64 Zahlen in einer Tabelle abgelegt werden. Da sie über 255
gehen, werden zwei Byte benötigt.
Deshalb muss ich beim Auslesen eines gewünschten Wertes, der sich in der
Tabelle in der Spalte n befindet, immer zum Z-Pointer 2n addieren. Es
wäre also nützlich, wenn das Low-Byte des Z-Pointers beim Addieren nicht
überlaufen würde. Ansonsten müsste ich es ja beachten.
Wenn ich die Tabelle nun so ablege, dass das Low-Byte der Adresse 0 ist,
kann ich mir sicher sein, dass kein Überlauf stattfindet.
Naja, die Frage steht eigentlich schon in der Überschrift. ;)
Nutze AVR Studio + Assembler
Noch eine Frage: Warum multipliziert man hier die Adresse "daten" mit
zwei?
ldi ZL, LOW(daten*2)
ldi ZH, HIGH(daten*2)
Hallo Maxim,
1. indem Du den ".org" Befehl verwendest
2. eigentlich ist die Lage der Adresse "wurscht", solange der Zugriff
über z.B.:
"LD temp,Z+" erfolgt.
3. Das ist einfach so.....
Gruss Otto
Maxim wrote:
>> Noch eine Frage: Warum multipliziert man hier die Adresse "daten" mit> zwei?> ldi ZL, LOW(daten*2)> ldi ZH, HIGH(daten*2)
Weil der Flash wortadressiert ist und nicht Byteadressiert.
Als Konsequenz daraus rechnet der Assembler in Wörtern und
gibt der eine Adresse als Wortadresse. Du willst hier aber
eine Byteadresse haben, daher *2
Komisch, wenn ich das hier assembliere:
.ORG 0x0010
.DB 0b10101010
erscheint das Byte an der Adresse 0x0020. Allgemein erscheint das Byte
im ROM doppelt so weit im Speicher als ich es mit dem .ORG-Befehl
angebe.
@Karl heinz Buchegger: Das erklärt natürlich alles. Danke.
@Otto: Der Befehl ADIW funktioniert mit Z nicht:
ADIW Z, R1
oder auch
ADIW ZL, R1
geht nicht.
Hi
Der Speicher ist Word-weise organisiert. $10 Word = $20 Byte. Aus diesem
Grund auch die Multiplikation mit 2. Oder für dich besser: erst den
Offset addieren und dann
lsl ZL
rol ZH
Entspricht einer 16 Bit Multiplikation mit 2.
Abgesehen davon. Du kannst die Tabelle mit einem Label versehen. Dann
ist es egal wo die Tabelle ist. Zugriff mit:
ldi ZL,Low(Tabelle)
ldi ZH,High(Tabelle)
MfG Spess
Hier als Beispiel ein Ausschnitt aus einem Programm für Tiny15:
1
ldi zl,low(2*sounds) ;Z-Pointer auf
2
ldi zh,high(2*sounds) ;Adressliste
3
mov wl,num ;Soundnummer kopieren
4
lsl wl ;und mal 2
5
add zl,wl ;doppelte Soundnummer
6
adc zh,null ;mit Übertrag addieren
7
lpm ;L-Byte Soundadresse holen
8
mov r1,r0 ;und sichern
9
add zl,eins ;Z-Pointer (L-Byte) auf Flash erhöhen
10
adc zh,null ;mit evtl. Übertrag im Carry
11
lpm ;H-Byte holen
Die "Klimmzüge" mit LPM und Z-Pointer-Erhöhung sind aufgrund des
eingeschränkten Befehlssatzes (gegenüber Mega16) erforderlich.
Zum Adresse * 2 sei noch angemerkt, dass das nur dann der Fall ist, wenn
der Z-Pointer für den Befehl LPM vorbereitet wird. Siehe auch Hilfe zum
Befehl LPM. Es gibt auch andere Befehle, die mit Z-Pointer arbeiten, die
Befehlsreferenz ist Dein Freund.
Tip: Solltest Du Hilfe zu einem ASM-Befehl benötigen, dann setze mal den
Cursor des Editors in AVR-Studio auf den entsprechenden Befehl und schau
mal, was passiert, wenn Du dann die F1-Taste betätigst.
...
Irgendwie funktioniert mein Programm nicht richtig.
Es sollen die Daten aus der Tabelle ausgelesen und in PortD geschrieben
werden. Da Ich die Werte mit .DW ablege, müsste ja das High-Byte immer
255 und das Low-Byte immer 0 sein. Somit sollte am PortD abwechselnd 1
und 0 anliegen. Das klappt schon beim Debugger nicht.
Hier
LDI ZL, LOW(TABELLE)
LDI ZH, HIGH(TABELLE)
musst du die Adresse mal 2 nehmen, weil dir der Assembler
die Adresse von Tabelle als Wortadresse liefert
LDI ZL, LOW(2*TABELLE)
LDI ZH, HIGH(2*TABELLE)
wohingegen du hier
MOV TEMP, R20
LSL TEMP //*2
die Multiplkation mit 2 brauchst oder auch nicht brauchst, je
nachdem, was der Wert in R20 aussagt.
LD TEMP, Z //Lade Low-Byte aus der Tabelle
Schon. Aber dazu muss die Tabelle auch im SRAM liegen. Bei dir
liegt die Tabelle aber im Flash Edit: und daher muss die Adresse
auch mal 2 genommen werden). Daher erfolgt der Ladevorgang
nicht mittels LD TEMP, Z sondern über LPM und das geladene Byte
ist dann im Register R0
ev. solltest du mal die Tutorial Abschnitte
http://www.mikrocontroller.net/articles/AVR-Tutorial:_SRAM
und
http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige
vergleichen. In beiden kommt eine Art von Tabelle vor und beide
zeigen den Unterschied zwischen Auslesen aus SRAM und Auslesen
aus Flash.
Hannes Lux wrote:
> Die "Klimmzüge" mit LPM und Z-Pointer-Erhöhung sind aufgrund des> eingeschränkten Befehlssatzes (gegenüber Mega16) erforderlich.
Darf man fragen wie das bei einem Mega16, einfacher geht?
Ich hab das auf einem m169 nämlich genauso gemacht und wäre natürlich
schwer an Verbesserungsmöglichkeiten interessiert. -wiebel
Michael Waiblinger wrote:
> Hannes Lux wrote:>> Die "Klimmzüge" mit LPM und Z-Pointer-Erhöhung sind aufgrund des>> eingeschränkten Befehlssatzes (gegenüber Mega16) erforderlich.> Darf man fragen wie das bei einem Mega16, einfacher geht?
Man darf... ;-)
1
ldi zl,low(2*sounds) ;Z-Pointer auf
2
ldi zh,high(2*sounds) ;Adressliste
3
mov wl,num ;Soundnummer kopieren
4
lsl wl ;und mal 2
5
add zl,wl ;doppelte Soundnummer
6
adc zh,null ;mit Übertrag addieren
7
lpm r16,z+ ;L-Byte nach r16 holen und Pointer erhöhen
8
lpm r17,z ;H-Byte nach r17 holen
Die neueren und größeren AVRs unterstützen bei LPM das Incrementieren
des Z-Pointers und die Angabe des Zielregisters. Die älteren AVRs
dagegen kannten nur den Befehl LPM ohne Parameter, das Zielregister war
immer R0. Auch das ADIW/SBIW gab es bei einigen älteren kleinen AVRs
nicht. Daher das Addieren von vordefinierten Registern im oberen
Beispiel, wobei das Vordefinieren von "null" und "eins" den Hauptgrund
in der Geschwindigkeit hat (kein unnötiges LDI). Das komplette Programm,
aus dem ich die Zeilen kopierte, kannst Du hier finden:
http://www.hanneslux.de/avr/divers/index.html
@Maxim:
Hast Du eigentlich bei MAXIM nachgefragt, ob Du deren rechtlich
geschützten Namen als Nick im Forum verwenden darfst? Nicht dass Dich
der Freiherr noch abmahnt. ;-)
...
Hannes Lux wrote:
> Die neueren und größeren AVRs unterstützen bei LPM das Incrementieren> des Z-Pointers und die Angabe des Zielregisters. Die älteren AVRs> dagegen kannten nur den Befehl LPM ohne Parameter, das Zielregister war> immer R0.
Alles klar, danke. Man kann aber via LPM nur und aussschliesslich ein
postincrement machen, also ein predec oder ein offset, richtig?
Das hilft aber schon gewaltig.
> Das komplette Programm,> aus dem ich die Zeilen kopierte, kannst Du hier finden:> http://www.hanneslux.de/avr/divers/index.html
Klasse Seite, danke. Es kann nicht genug doku geben. ;)
Ich hab erst letztens mit einem Tiny45 den Melodiencode von elm-chan
getestet, das klingt unglaublich gut, aber ich hab den Code noch nicht
verstanden, und dann zählt's ja nicht. ;) ->
http://elm-chan.org/works/mxb/report_e.html
Von daher werd ich mir jetzt erstmal deine Seite zu Gemüte führen.
-wiebel
Maxim wrote:
> Es ist also völlig normal, dass der ATMega warm wird? Das wurde er bei> mir noch nie und ich habe nirgendwo davon gehört.
Wärme (in der Elektronik) kommt nicht mal eben so. Meist entsteht durch
das Verheizen elektrischer Leistung (Strom mal Spannung). Strom und
Spannung kann man mit einfachen Mitteln (Multimeter) messen. Beim
Verdacht, ein Bauteil "wird warm", fällt mir als erstes ein, die
Stromaufnahme (der Versorgungsspannung) zu messen. Das kann erstmal
bestätigen oder ausschließen, dass sich der Chip elektrisch erwärmt.
Vor über 15 Jahren hatte ich mal einen 8501-Prozessor, den ich für
übermäßig warm hielt. Nach Trennen sämtlicher Leitungen von dem
Heimcomputer kühlte sich die CPU immer noch nicht ab. Sie befand sich im
Brennpunkt einer 2m entfernten Halogenlampe (Auto-Nebelscheinwerfer ohne
Streuscheibe) und erwärmte sich daher auch ohne direktes Verheizen von
Strom in der CPU.
Ehe Du nun den Controller aktiv kühlst, solltest Du die Ursache der
Erwärmung ermitteln. In Frage käme evtl. zu hohe Betriebsspannung, zu
hohe Last an den Ausgängen, falsche Programmierung (Kurzschluss am
versehentlich als Ausgang programmierten Eingangspin), Belastung der
Schutzdioden durch Eingangspegel außerhalb des
Versorgungsspannungsbereiches usw. Möglichkeiten gibt es da viele, Du
kannst durch systematische Fehlersuche eine Möglichkeit nach der anderen
ausschließen.
...
Hannes Lux wrote:
> Maxim wrote:>> Es ist also völlig normal, dass der ATMega warm wird?
Nein, da ist definitiv was faul, z.B. kurzgeschlossene IOs, LEDs ohne
Vorwiderstand usw.
> Vor über 15 Jahren hatte ich mal einen 8501-Prozessor, den ich für> übermäßig warm hielt.
Hatte ich auch.
Aber das war der alte NMOS-Typ, da ist das normal (~200mA Verbrauch).
Peter
Hannes Lux wrote:
> Vor über 15 Jahren hatte ich mal einen 8501-Prozessor, den ich für> übermäßig warm hielt. Nach Trennen sämtlicher Leitungen von dem> Heimcomputer kühlte sich die CPU immer noch nicht ab. Sie befand sich im> Brennpunkt einer 2m entfernten Halogenlampe (Auto-Nebelscheinwerfer ohne> Streuscheibe) und erwärmte sich daher auch ohne direktes Verheizen von> Strom in der CPU.
Nein, ich frag nicht nach, nein ich frag nicht nach ... ich will das
bestimmt auch gar nicht wissen .... .... ok, verloren ....
WTF??? Warum? -wiebel
Michael Waiblinger wrote:
> Hannes Lux wrote:>> Vor über 15 Jahren hatte ich mal einen 8501-Prozessor, den ich für>> übermäßig warm hielt. Nach Trennen sämtlicher Leitungen von dem>> Heimcomputer kühlte sich die CPU immer noch nicht ab. Sie befand sich im>> Brennpunkt einer 2m entfernten Halogenlampe (Auto-Nebelscheinwerfer ohne>> Streuscheibe) und erwärmte sich daher auch ohne direktes Verheizen von>> Strom in der CPU.> Nein, ich frag nicht nach, nein ich frag nicht nach ... ich will das> bestimmt auch gar nicht wissen .... .... ok, verloren ....> WTF??? Warum? -wiebel
Manche Leute nehmen sowas als Tischbeleuchtung, und? ;)
PS: Ich finde Halogenlampen VIEL VIEL angenehmer von der Lichtfarbe beim
Arbeiten als normale Glühbirnen.
Simon Küppers wrote:
> Michael Waiblinger wrote:>> Hannes Lux wrote:>>> Vor über 15 Jahren hatte ich mal einen 8501-Prozessor, den ich für>>> übermäßig warm hielt. Nach Trennen sämtlicher Leitungen von dem>>> Heimcomputer kühlte sich die CPU immer noch nicht ab. Sie befand sich im>>> Brennpunkt einer 2m entfernten Halogenlampe (Auto-Nebelscheinwerfer ohne>>> Streuscheibe) und erwärmte sich daher auch ohne direktes Verheizen von>>> Strom in der CPU.>> Nein, ich frag nicht nach, nein ich frag nicht nach ... ich will das>> bestimmt auch gar nicht wissen .... .... ok, verloren ....>> WTF??? Warum? -wiebel
Hmmm, ääähhh, muss ich das JETZT verstehen?
>> Manche Leute nehmen sowas als Tischbeleuchtung, und? ;)
Ach sooooo war das gemeint...
Stimmt... - Defektes Glas vom Nebelscheinwerfer entfernt, gefreut, dass
das Teil so prima bündelt, so an die Zimmerdecke geschraubt, dass es
direkt auf den Arbeitsplatz strahlt.
>> PS: Ich finde Halogenlampen VIEL VIEL angenehmer von der Lichtfarbe beim> Arbeiten als normale Glühbirnen.
HO (Hannes oooch...)
Maxim wrote:
> Habe DDR versehentlich falsch gesetzt. :D
Na prima, dann ist die Ursache ja gefunden. Hoffentlich hat der AVR noch
keinen Schaden genommen.
...