Forum: Mikrocontroller und Digitale Elektronik SRAM auslesen aund ausgeben [AtMega64]


von Bruno (Gast)


Lesenswert?

Hallo,

ich habe noch nicht sonderlich viel Erfahrung in der programmierung mit 
Assembler. Deshalb wollte ich hier mal nachfragen ob mein Quellcode so 
funktioniert oder was eben daran falsch ist.

Funktionsweise.

Ich habe im Ram 256 Byte gespeichert, die nach und nach an die Ports C 
und E ausgegeben werden sollen. Die position im Ram wird während dessen 
immer wieder neu berechnet.
1
SET_LED:
2
  
3
  mov r30, r1  ; r1: Die aktuelle Position
4
  rol r30    ; r3 mit 2 multiplizieren um die aktuelle Ramposition zu ermitteln.
5
  ldi r27, $1  ; Start Adresse des Rams erst bei 0x0100
6
  add r31, r27  ; Startadresse des Rams zur Position hinzu addieren.
7
  lds r2, Z  ; Wert aus dem Ram an adresse Z (r30, r31) in einem Register speichern
8
  out $3, r2  ; Ausgabe an PORTC
9
  inc Z    ; Z incrementieren
10
  lds r2, Z  ; Wert aus dem Ram an adresse Z in einem Register speichern
11
  out $15, r2  ; Ausgabe an PORTE

von Jörg X. (Gast)


Lesenswert?

1
LD r2, Z     ; das _s hat eine bedeutung
2
LDS r2, Z    ; macht nämlich etwas anderes
;)

>>r3 mit 2 multiplizieren um die aktuelle Ramposition zu ermitteln.
versteh ich nicht, aber ich weiß auch nicht wo der Wert in r3 her 
kommt...

von Michael U. (Gast)


Lesenswert?

Hallo,

Den benutzen Prozessor sagt mir meine Galskugel: irgendein AVR...
1
  mov r30, r1  ; r1: Die aktuelle Position
2
  rol r30    ; r3 mit 2 multiplizieren um die aktuelle Ramposition zu ermitteln.
3
  ldi r27, $1  ; Start Adresse des Rams erst bei 0x0100
4
  add r31, r27  ; Startadresse des Rams zur Position hinzu addieren.
5
  lds r2, Z  ; Wert aus dem Ram an adresse Z (r30, r31) in einem Register speichern
6
  out $3, r2  ; Ausgabe an PORTC
7
  inc Z    ; Z incrementieren
8
  lds r2, Z  ; Wert aus dem Ram an adresse Z in einem Register speichern
9
  out $15, r2  ; Ausgabe an PORTE
10
11
-----------------------
12
.def aktuell = r1 ; liest sich wesentlich besser...
13
.def temp    = r2
14
15
  mov ZL, aktuell  ; Die aktuelle Position
16
  rol ZL    ; ZL mit 2 multiplizieren um die aktuelle Ramposition zu ermitteln.
17
rol schiebt C in Bit 0, was weisst Du zu dieser Zeit in Deinem Programm über den Zustand von C?
18
Also:
19
  lsl ZL
20
Und wenn das einen Übertrag ergibt??? Ist ein 16 Bit-zeiger, also noch ein
21
  rol ZH ; hinterher, hier rol, weil Bit7 aus ZL in Bit0 von ZH muß
22
23
  lds holt einen direkten Wert, da sollte eigentlich der Assembler maulen, wenn das richtige xxxdef.inc für den AVR includet wurde...
24
Alos
25
  ld  temp,Z
26
  out PORTC, temp ; Ports haben Namen, sind auch in der xxxdef.inc definiert...
27
  inc Z gibt es nicht, da sollte der Assembler maulen...
28
  adiw Z,1 ginge, nur warum?
29
30
  statt ld temp,Z besser
31
  ld temp,Z+ , dann zeigt Z schon auf das nächste Byte und weiter mit
32
  ld temp,Z
33
  out PORTE,temp
34
35
  fertig. Nochmal sortiert:
36
37
 -----------------------
38
.def aktuell = r1 ; liest sich wesentlich besser...
39
.def temp    = r2
40
41
 mov ZL,aktuell
42
 lsl ZL  ; * 2 für Offset von 2 Byte
43
 rol ZH
44
 
45
 addi ZH,0x01 ; kann man hier machen, einen Übertrag kann es hier ja nicht geben und Addition von 0 zu ZL ändert ja nichts
46
 ld  temp,Z+
47
 out PORTC,temp
48
 ld  temp,Z
49
 out PORTE,temp

Gruß aus Berlin












von Jörg X. (Gast)


Lesenswert?

sehr schön, so macht das also ein richtiger Asm-progger :)
aber:
 "addi" gibt's nicht bei AVRs!
hast wahrscheinlich
"adiw Z, 0x01"
gemeint (gibt es bei den neueren Typen),
@ Bruno (Gast):
 auf jeden Fall das "AVR Instruction Set"-PDF von Atmel besorgen ;)

auch grüße aus Berlin...

von Bruno (Gast)


Lesenswert?

@Michael U. Jupp ist AVR. Hab ich aber auch in der Überschrift erwähnt.

Danke für eure Hilfe, ich find C dann doch irgendwie einfacher.

Habe mir das AVR Instruction Set herunter geladen, damit ist vieles 
einfacher.

von Michael U. (Gast)


Lesenswert?

Hallo,

@Jörg X: aua aua, das kommt davon, wenn man mehr auf die eigenen 
Kommentare achtet, stimmt natürlich.

adiw geht auch nicht, das kann nur 0...63 als Wertebereich, es müßten 
aber in 16Bit 0x100 addiert werden

subi ZH, -0x01 dagegen geht...

Eigentlich würde ich es aber eher so machen:

{avrasm]
-----------------------
.DSEG
.org 0x0100
DATENTAB .byte 256

.CSEG

.def aktuell = r1 ; liest sich wesentlich besser...
.def temp    = r2

 ldi ZH,high(DATENTAB)
 ldi ZL,low(DATENTAB)
 mov YL,aktuell
 clr YH
 lsl YL
 rol YH
 add ZL,YL
 adc ZH,YH

 ld  temp,Z+
 out PORTC,temp
 ld  temp,Z
 out PORTE,temp

{/avrasm]

ist universeller und unabhängig von der Ram-Position der Wertetabelle.
Man hat nur an einer Stelle was anzupassen. ;)
Wenn ich nicht wieder auf die Schnelle Fehler eingebaut habe...

Eigentlich mache ich dazwischen an den KS0108-Routinen für mein 
"AVR-Radio weiter, das irritiert dann manchmal ;)

Gruß aus Berlin
Michael


von Michael U. (Gast)


Lesenswert?

Hallo,

typisch, diesmal eben die Klammern beim avrasm-TAG... grrrr

Gruß aus Berlin
Michael

von Jörg X. (Gast)


Lesenswert?

@Michael U.: verdammt, da hab ich nicht aufgepasst :)

@Bruno:
> ich find C dann doch irgendwie einfacher.
was treibt dich zu Asm? schau mal oben links "AVR-GCC-Tutorial" :)

von Bruno (Gast)


Lesenswert?

Mein chef will das so.

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.