Forum: Mikrocontroller und Digitale Elektronik Wie kann ich in AVR-Assembler ein Feld erzeugen?


von Andreas H. (Gast)


Lesenswert?

Hallo,
ich programmiere nicht mit dem AVR-Studio, daher funktioniert der 
".db"-Befehl bei mir (offensichtlich) nicht.
Für eine Ausgabe auf der Anzeige (mein µC ist ein atmega16) würde ich 
aber gerne die dazu benötigten Bitmuster im Speicher (Flash oder SRAM) 
abspeichern, wobei die einzelnen Bitmuster nebeneinander im Speicher 
stehen können/sollten... Aber wie mache ich das? Hier in den Tutorials 
wird das immer mit ".db" gemacht, geht das anders aus? Z-Zeiger 
vielleicht? Aber wie?

Vielen Dank!

von Karl H. (kbuchegg)


Lesenswert?

Andreas H. wrote:
> Hallo,
> ich programmiere nicht mit dem AVR-Studio,

Es wäre gut, wenn du uns dann sagen würdest, welchen Assembler
du statt dessen benutzt. Letztendlich ist das nämlich eine
Frage dessen, welches Kürzel dem Programmierer deines
Assemblers am sympatischten war.

> daher funktioniert der
> ".db"-Befehl bei mir (offensichtlich) nicht.

Wieso offensichtlich?
So offensichtlich ist das nicht.

> wird das immer mit ".db" gemacht, geht das anders aus?

Das hängt ganz und gar von deinem Assembler ab.
Normalerweise müsste sowas in der Doku zu finden sein.

> Z-Zeiger
> vielleicht?

sicherlich wird es letztendlich auf eine Verwendung des
Z-Zeigers hinauslaufen. Aber das ist ja jetzt noch gar nicht
dein Problem. Jetzt musst du erst mal das Feld (den Text)
anlegen und dann kannst du dir überlegen, wie dein Programm
ihn wieder auslesen kann/soll.

von Otto (Gast)


Lesenswert?

nenn mal ein konkretes Beispiel, in dem ".db" nicht funktioniert.

Gruss Otto

von spess53 (Gast)


Lesenswert?

Hi

.db funktioniert nur im Flash. Beim Zugriff musst du aber beachten, das 
der Flash Wortweise organisiert ist. Der Zugriff über z.B. Z erfolgt 
Bytweise. Wenn du auf dein Feld zugreifen willst musst du Z mit der 
Adresse * 2 laden.


Feld:     .db 11,22,33,44,....


ldi ZL, low(Feld*2)
ldi ZH, high(Feld*2)

MfG Spess

von Andreas H. (Gast)


Lesenswert?

hallo, danke für deine antwort.

ich habe hier mal einen kleinen beispielcode programmiert. ich möchte 
also einfach nur diese 3 zufällig angelegten 8-bit-werte am PORTC 
ausgeben mittels z-pointer. fehlermeldung bekomme ich keine, jedoch 
leuchtet die anzeige meines DIGIT0 an allen stellen auf (also 
anscheinend bekommt es lauter einser), obwohl das natürlich nirgends in 
meiner tabelle steht. was mache ich falsch?! danke für jeden hinweis!
1
.include "m16def.inc"
2
3
.equ temp, 0x10
4
.org 0x0000
5
.section .text
6
7
.global Main
8
9
ldi  temp,hi8(RAMEND)    ;Stackpointer initialisieren
10
out SPH, temp          
11
ldi  temp,lo8(RAMEND)  
12
out SPL, temp
13
14
ldi ZL, lo8(Data)        ;Z-Zeiger anlegen
15
ldi ZH, lo8(Data)
16
17
ldi temp, 0xFF            ;PORTD ist Ausgang (Versorgungsspannung für Anzeige)
18
out DDRD, temp
19
ldi temp, 0b00000001    ;Digit0 aktivieren
20
out PORTD, temp
21
22
ldi temp, 0xFF    ;PORTC ist Ausgang für Daten
23
out DDRC, temp
24
25
loop:
26
        lpm temp,Z+     ;Daten ausgeben und Z-Zeiger erhöhen
27
        out PORTC, temp
28
        rjmp loop
29
30
;Tabelle:
31
;========
32
33
Data:
34
  .byte 0b10101011
35
  .byte 0b00001110
36
  .byte 0b11110000

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


Lesenswert?

Dein Z-Pointer wird falsch initialisiert:

 ldi ZL, low(Data*2)
 ldi ZH, high(Data*2)

muß das heißen.

Außerdem läuft Deine Schleife zu schnell, da erkennst Du nie etwas.

von Andreas H. (Gast)


Lesenswert?

wenn ich das so wie du sagst programmiere, dann bekomme ich die 
Fehlermeldung:

"Error: invalid sections for operation on 'Data' and 'lo8'"!

Diese Fehlermeldung bekomme ich ohne (data*2) nicht...

Dass die Schleife zu schnell läuft, stört mich jetzt für die testzwecke 
einmal nicht, das werde ich dann ändern, wenn das mit dem Z-Register mal 
klappen sollte, aber danke!

von Karl H. (kbuchegg)


Lesenswert?

Andreas H. wrote:
> wenn ich das so wie du sagst programmiere, dann bekomme ich die
> Fehlermeldung:
>
> "Error: invalid sections for operation on 'Data' and 'lo8'"!

Schau dir nochmal deinen Code und den von Travel Rec. genau
an. Insbesondere den Teil in dem du 'lo8' und Travel Rec 'Low'
bzw. 'High' geschrieben hat.

von spess53 (Gast)


Lesenswert?

Hi

Was ist das für ein Assembler?

Noch etwas: in einer .db-Zeile muss eine geradzahlige Anzahl von Werten 
stehen. Da die nächste Zeile eine neue Wortadrsse darstellt hast du 
sonst immer ein ungenutztes Byte dazwischen und dein Adressierung stimmt 
nicht mehr.

MfG Spess

von Alexander L. (lippi2000)


Lesenswert?

Also da sind doch gleich richtig viele Fehler drinne:

- temp soll ein Register zugewiesen werden --> .def temp=r16
- An Adresse 0x000 im Flash steht Resetvektor
 .org 0x000
 rjmp MAIN

 MAIN:

- Stackpointer laden: ldi temp,HIGH(RAMEND)...
- Z-Pointer wird bei dir 2x mit LOW-Werten von Daten initialisiert und 
muss mit 2 Multipliziert werden (wegen Wort)
- Die Daten werden mit .db angelegt und durch Komma hintereinander 
aufgelistet (bei einer ungeraden Zahl, ergänzt der Compiler ein Byte mit 
Null)=

Hab den Code im AVR getestet und läuft ohne Problem, außer das die 
Schleife nicht abgebrochen wird.
1
.include "m16def.inc"
2
3
.def temp=r16
4
.org 0x0000
5
rjmp Main
6
7
Main:
8
9
ldi  temp,HIGH(RAMEND)    ;Stackpointer initialisieren
10
out  SPH, temp          
11
ldi  temp,LOW(RAMEND)  
12
out  SPL, temp
13
14
ldi ZH, HIGH(Data<<1)        ;Z-Zeiger anlegen
15
ldi ZL, LOW(Data<<1)
16
17
ldi temp, 0xFF            ;PORTD ist Ausgang (Versorgungsspannung für Anzeige)
18
out DDRD, temp
19
ldi temp, 0b00000001    ;Digit0 aktivieren
20
out PORTD, temp
21
22
ldi temp, 0xFF    ;PORTC ist Ausgang für Daten
23
out DDRC, temp
24
25
loop:
26
        lpm temp,Z+     ;Daten ausgeben und Z-Zeiger erhöhen
27
        out PORTC, temp
28
        rjmp loop
29
30
;Tabelle:
31
;========
32
33
Data:
34
.db 0b10101011,0b00001110,0b11110000

Gruß Alexander

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


Lesenswert?

Dumme Zwischenfrage: warum nutzt der Kollege das AVR-Studio und dessen 
Assembler nicht?

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.