mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Von FLASH in den SRAM kopieren


Autor: Roland Bumm (rolandb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo AVR Gemeinde,

ich versuche die ganze Zeit etwas aus dem FLASH in den SRAM zu kopieren.
ASM AVR Stduio 4.13:
open_container:
ldi     YL,LOW(daten_sensor_c)          
ldi     YH,HIGH(daten_sensor_c)
ldi     ZL,LOW(write_file*2)          
ldi     ZH,HIGH(write_file*2)
  ldi temp1,(Anz_Write)
open_c:
  lpm    r16,Z+
  st    Y+,r16
  dec    temp1
  tst    temp1
  brne  open_c
ret

daten_sensor_c  wird folgendermaßen initialisiert:
daten_sensor_c:    .BYTE 95


und write_file folgendermassen:
write_file:    .db 0x45,0x0D,....

Eigentlich muss ich doch das Y Register mittels STS speichern? Das geht 
aber laut dem Compiler nicht.

Könnt ihr mir da bitte helfen, wie bekomme ich ein Byte vom Flash in den 
SRAM?


mfg
Roland B.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht doch ganz gut aus. Indirekte Adressierung der Pointer wird mit 
"st"und "ld" anstatt "sts" und "lds" unternommen, da hat der Assembler 
schon Recht. Das "tst tmp1" kannst Du übrigens sparen, da die Bedingung 
bei 0 automatisch erfüllt ist.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit lpm kommt das byte ins R0 Register, mit sts 0x0060, R0 kommst ins 
Ram an die Adresse 0x0060

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Liegt dein 'aten_sensor_c' auch in .dseg ? Eigentlich kann ich auf den 
ersten Blick keinen Fehler erkennen.

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

@Martin: Es gibt lpm-> nach r0 und lpm register,Z/Z+/-Z siehe 
Instruction Set.

MfG Spess

Autor: Roland Bumm (rolandb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Travel Rec. wrote:
> Sieht doch ganz gut aus. Indirekte Adressierung der Pointer wird mit
> "st"und "ld" anstatt "sts" und "lds" unternommen, da hat der Assembler
> schon Recht. Das "tst tmp1" kannst Du übrigens sparen, da die Bedingung
> bei 0 automatisch erfüllt ist.

@Martin

Danke ist mir auch bewusst. Wollte nur halt r16 nehmen, was laut 
Datenblatt auch richtig ist.

qSpess53

Ja, liegt auch im dseg. Vielleicht habe ich da irgendwo einen anderen 
Bug.. Muss mal suchen.
Danke erstmal, ich suche dann :-)

mfg

Autor: Roland Bumm (rolandb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht denn untenliegendes Konstrukt? Ich möchte sogesehen einen Offset 
auf die Adresse schreiben?
ldi  ZL,LOW(daten_sensor_c+Anz_Write+1)          
ldi  ZH,HIGH(daten_sensor_c+Anz_Write+1)

Sollte doch gehen?


mfg

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich habe deinen Code mal durch den Simulator laufen lassen. 
Funktioniert.
Frage: Welches Register ist temp1?

Deine Frage: Müsste gehen.

MfG Spess

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

am Rande: tst temp1 ist überflüssig, dec beeinflußt Z.

Gruß aus Berlin
Michael

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>dec beeinflußt Z.   ???????????????

MfG Spess

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Zero-Bit im SREG ist gemeint. Nicht das Z-Pointerregister-päärchen.

Autor: Roland Bumm (rolandb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch allen. Aber es scheint ein Problem mit meiner gesamten 
Adressierung zu geben. Die Pointer werden zwar auf die richtigen 
Adressen gesetzt, allerdings werden nach einigen ldi Initialsierungen 
die Inhalte der Speicherzellen vertauscht. Ich muss vlt nochmal kurz 
erklären was ich erreichen möchte:

Es soll ein zusammenhängendes Paket über SPI Emulation versendet werden. 
Dazu brauche ich folgende Kette:

<Write_Anz(#19)><Daten(#64)><Close_Anz(#12)> <-- diese Kette senden

Habe mir also ein Container eingerichtet. Dieser beeinhaltet oben 
genannte Länge 19+64+12=95 Bytes

Im .DSEG:
.org 0x62
daten_sensor_c:    .BYTE (TEMP_SENS+Anz_Write+Anz_Close)

Startadresse: 0x0062 Endadresse : 0x00C1
Im .CSEG:
write_file: .db 0x45,0x0D,0x09,0x20,"TET.DAT",0x0D,0x08,0x20,0x00,0x00,0x00,0x40,0x0D
close_file: .db 0x0D,0x0A,0x20,"TET.DAT",0x0D,0xFE

Als Terminierung habe ich 0xFE gewählt, im write_file steht keine 
Terminierung, da dort dirket die Daten angefügt werden sollen.

Nun mein Code:
modeA:
.
.
.
  rcall open_container
//Hier beginnt SPI Emulation -Initialsierung-
.
.
.
//
;  rcall close_container //<--
  ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
    ldi     YH,HIGH(daten_sensor_c)
  lpm r16,Z+
  rcall SPI_START
  
rjmp modeA


//Subroutines
open_container:
  ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
    ldi     YH,HIGH(daten_sensor_c)
  ldi     ZL,LOW(write_file*2)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
    ldi     ZH,HIGH(write_file*2)
  ldi temp1,(Anz_Write)
open_c:
  lpm    r16,Z+
  st    Y+,r16
  dec    temp1
  brne  open_c
ret


close_container:
  ldi     YL,LOW(daten_sensor_c+Anz_Write+TEMP_SENS+1)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
    ldi     YH,HIGH(daten_sensor_c+Anz_Write+TEMP_SENS+1)
  ldi     ZL,LOW(close_file*2)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
    ldi     ZH,HIGH(close_file*2)
  ldi temp1,(Anz_Close-1)
close_c:
  lpm    r16,Z+
  st    Y+,r16
  dec temp1
  brne  close_c
ret

Wenn ich jetzt im AVR Studio den Simualtor laufen lassen, dann passiert 
schon folgendes komsiches Ereignoiss. Das Unterprogramm open_container 
funktioniert einwandfrei, es schiebt alle Daten an die richtige Position 
aus dem Flash in den SRAM, nach dem ret wird mit der Anweisung:
ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
ldi     YH,HIGH(daten_sensor_c)
lpm r16,Z+
  rcall SPI_START
Bereits der Inhalt des SRAM falsch angezeigt? Die Adress wird zwar 
richtig geladen, allerdings stimmt der Inahlt nicht mehr? Es muss dort 
das erste von write_byte erscheinen, also 0x45 stattdessen spring er 
nach 0x20 also 4 Speicherstellen weiter?

Wie kann das sein? Ich lade doch das SRAM Segment wieder neu?

mfg
Roland

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

lpm ist ja hier auch falsch, der liest aus dem Flash.
Du willst aus dem Ram lesen,

also ld  r16,Z+

Flash Byte-weise: Adresse * 2 nehmen und mit lpm lesen
SRAM: Adresse und mit ld lesen (indirekt, Z/X/Y als Zeiger-Register)

PS: @ spess53: sorry, hätte da besser Zero-Flag schreiben sollen.

Gruß aus Berlin
Michael

Autor: Roland Bumm (rolandb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arghhhhhh,

danke.. Ich habe den Fehler auch gerade gefunden. Hatte zwei unabhängige 
Dreher mit lpm und ld.. Jetzt gehts wunderbar!!! Danke euch allen.. Nun 
funktioniert Atmega8<>SPI<>VNC1l :-)


Danke

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.