mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie lege ich die Startadresse einer Tabelle fest?


Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi und Danke.

Bevor ich den Wert aus der Tabelle holle, muss ich ja zuerst das Offset 
(also die Zeilennummer der Tabelle) zum Z addieren.

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dafür gäbe es "adiw" (o.ä.)

Gruss Otto

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja "R1" ist nicht herade eine Konstante.....

Gruss Otto

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier als Beispiel ein Ausschnitt aus einem Programm für Tiny15:
 ldi zl,low(2*sounds)       ;Z-Pointer auf
 ldi zh,high(2*sounds)      ;Adressliste
 mov wl,num                 ;Soundnummer kopieren
 lsl wl                     ;und mal 2
 add zl,wl                  ;doppelte Soundnummer
 adc zh,null                ;mit Übertrag addieren
 lpm                        ;L-Byte Soundadresse holen
 mov r1,r0                  ;und sichern
 add zl,eins                ;Z-Pointer (L-Byte) auf Flash erhöhen
 adc zh,null                ;mit evtl. Übertrag im Carry
 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.

...

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
////////////////////////////////////////////////////////////////////////////////////////////////

START:  LDI R20, 255

LOOP:  INC R20   //R20 ist ein Zähler
    
    CPI   R20, 64   //Er soll bis max. 63 Zählen
    BREQ  START

    LDI  ZL, LOW(TABELLE)
    LDI  ZH, HIGH(TABELLE)

    MOV  TEMP, R20
    LSL  TEMP         //*2
    ADD  ZL, TEMP     //Addiere Offset zum Pointer
    LDI TEMP, 0       //mit eventuellem Übertrag
    ADC ZH, TEMP

    LD  TEMP, Z       //Lade Low-Byte aus der Tabelle
    OUT  PORTD, TEMP  //und schreibe es nach PortD

    NOP
    NOP
    NOP
    NOP
    NOP

    LDI  TEMP, 1     //Addiere 1 zum Pointer
    ADD  ZL, TEMP    //um an das High-Byte zu kommen
    LDI  TEMP, 0
    ADC  ZH, TEMP

    LD  TEMP, Z       //holle das High-Byte
    OUT  PORTD, TEMP  //und gib es aus

    RJMP LOOP


////////////////////////////////////////////////////////////////////////////////////////////////

TABELLE:  .DW  255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 255
      .DW 223

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-Tutori...

vergleichen. In beiden kommt eine Art von Tabelle vor und beide
zeigen den Unterschied zwischen Auslesen aus SRAM und Auslesen
aus Flash.

Autor: Michael Waiblinger (wiebel42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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... ;-)
 ldi zl,low(2*sounds)       ;Z-Pointer auf
 ldi zh,high(2*sounds)      ;Adressliste
 mov wl,num                 ;Soundnummer kopieren
 lsl wl                     ;und mal 2
 add zl,wl                  ;doppelte Soundnummer
 adc zh,null                ;mit Übertrag addieren
 lpm r16,z+                 ;L-Byte nach r16 holen und Pointer erhöhen
 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. ;-)

...

Autor: Michael Waiblinger (wiebel42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, es funktioniert. Aber irgendwie wird der ATMega8 jetzt warm!

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast sicher keine Wasserkühlung installiert, oder? Daran könnts 
liegen!

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ne, aber ich habe hier noch zwei 120 Watt Peltier rumliegen. Reichen 
die? Ich meine, so ein 8-Bit-uC verbraucht ja richtig Strom ...

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst bei der Erstinitialisierung des Kühlkörperbausteins 
Wasserkühlung einstellen. SOnst wird per default Konvektion angenommen
;-)
processor_cooling.init ( c_water );

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael Waiblinger (wiebel42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Maxim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe DDR versehentlich falsch gesetzt. :D

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.