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


von Roland B. (rolandb)


Lesenswert?

Hallo AVR Gemeinde,

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

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


und write_file folgendermassen:
1
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.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


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.

von Martin (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von Roland B. (rolandb)


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

von Roland B. (rolandb)


Lesenswert?

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

Sollte doch gehen?


mfg

von spess53 (Gast)


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

von Michael U. (amiga)


Lesenswert?

Hallo,

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

Gruß aus Berlin
Michael

von spess53 (Gast)


Lesenswert?

Hi

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

MfG Spess

von Sebastian (Gast)


Lesenswert?

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

von Roland B. (rolandb)


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:
1
.org 0x62
2
daten_sensor_c:    .BYTE (TEMP_SENS+Anz_Write+Anz_Close)

Startadresse: 0x0062 Endadresse : 0x00C1
Im .CSEG:
1
write_file: .db 0x45,0x0D,0x09,0x20,"TET.DAT",0x0D,0x08,0x20,0x00,0x00,0x00,0x40,0x0D
2
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:
1
modeA:
2
.
3
.
4
.
5
  rcall open_container
6
//Hier beginnt SPI Emulation -Initialsierung-
7
.
8
.
9
.
10
//
11
;  rcall close_container //<--
12
  ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
13
    ldi     YH,HIGH(daten_sensor_c)
14
  lpm r16,Z+
15
  rcall SPI_START
16
  
17
rjmp modeA
18
19
20
//Subroutines
21
open_container:
22
  ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
23
    ldi     YH,HIGH(daten_sensor_c)
24
  ldi     ZL,LOW(write_file*2)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
25
    ldi     ZH,HIGH(write_file*2)
26
  ldi temp1,(Anz_Write)
27
open_c:
28
  lpm    r16,Z+
29
  st    Y+,r16
30
  dec    temp1
31
  brne  open_c
32
ret
33
34
35
close_container:
36
  ldi     YL,LOW(daten_sensor_c+Anz_Write+TEMP_SENS+1)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
37
    ldi     YH,HIGH(daten_sensor_c+Anz_Write+TEMP_SENS+1)
38
  ldi     ZL,LOW(close_file*2)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
39
    ldi     ZH,HIGH(close_file*2)
40
  ldi temp1,(Anz_Close-1)
41
close_c:
42
  lpm    r16,Z+
43
  st    Y+,r16
44
  dec temp1
45
  brne  close_c
46
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:
1
ldi     YL,LOW(daten_sensor_c)          ; den Z-Pointer mit dem Start der Sensoren Bytes laden
2
ldi     YH,HIGH(daten_sensor_c)
3
lpm r16,Z+
4
  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

von Michael U. (amiga)


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

von Roland B. (rolandb)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.