hallo
versuch jetzt schon stundenlang ein anscheinend simples programm
zuschreiben aber irgendwie steh ich auf der leitung,...
wie kann man bei einem atmega 16 ein array für 15 werte (bytes)
definieren und mittels indirekter adressierung zugreifen?
bzw. wo legt man das arry am besten an? flash? eeprom? daten sollen
nicht flüchtig sein aslo kein sram
bzw. wie kann man dann mittels x,y,z drauf indirekt zufreifen
(pointer)
thx
ldi ZL,low(array*2) ; z-pointer auf startaddresse
ldi ZH,high(array*2)
ldi test,z+ ; test mit dem wert, auf den z+ steht
speichern, z +1
array:
.db "Hallo Dies ist ein tst",$13
vielleicht so??? habe leider nicht mehr input, wie du dir das
vorstellst
.section .text
.global main
.org 0x0000
feld: .byte 0xff, 0xff, 0xf0, 0xff
main:
ldi YL,lo8(feld)
ldi YH,hi8(feld)
ld r16, Y
ldi r17, 0xff
out DDRC, r17
out PORTC, r16
rjmp main
mit ld r16, Y soll nach r16 der wert geladen werden auf den Y
zeigt,..es läßt sich fehlerlos übersetzten nur in r16 steht 0x00, es
sollte aber 0xff drinnenstehen
hmmm
so wie ich das sehe versuchst du was ausm Flash zu holen ...
1. geht das nur mitm Z Register
2. geht das nur mit LPM ...
richtiger wäre demnach:
.
.
.
main:
ldi ZL,low(feld*2)
ldi ZH,high(feld*2)
lpm r16, Z
ldi r17, 0xff
out DDRC, r17
out PORTC, r16
.
.
.
Jedenfalls sagen das meine bescheidenen Assemblerkenntnisse ,,,
Asche auf mein Haupt...
Natürlich LPM anstatt LDI wo habe ich nur meine Gedanken :-(
LPM r16,Z+ ; incrementiert den Z-Pointer nach dem lesen
Gruß,
Tubie
und Sorry für die falsche Antwort
@rudi ratlos:
Vielleicht solltest du wirklich erstmal schreiben, was du vorhast.
Mag ja sein, dass der Begriff 'indiziert adressieren' oder 'Array'
nur für das SRAM gelten, aber es gibt schon Möglichkeiten, Listen oder
Tabellen (mit Konstanten, Texten usw) im Programmspeicher (Flash)
abzulegen und darauf indiziert (also über Index) zuzugreifen.
Die Daten legt man mit .db oder .dw im Flash ab.
Der Zugriff erfolgt über den Z-Pointer und LPM.
Dabei ist zu beachten:
- Die Daten gehören nicht ins .dseg sondern ins .cseg, denn es sind
keine Variablen sondern Konstanten, die wie Code gespeichert werden. --
Die Daten gehören auch grundsätzlich nicht an Adresse 0, denn dort
gehört die Interrupt-Sprungtabelle hin und nix anderes. Also die Daten
immer schön an das Programmende.
- Der Flash ist wordweise organisiert, die Daten müssen also immer
paarweise (bei .db) angelegt werden.
- LPM liest byteweise, der z-Pointer muss also die doppelte Adresse
enthalten.
- Vor den Daten ist ein Label zu setzen, damit die Basisadresse der
Datentabelle verfügbar ist.
Willst du auf das Byte zugreifen, dessen Index im Register r16 steht,
dann ginge das so:
ldi zl,low(daten*2) ;Z-Pointer auf Basisadresse
ldi zh,high(daten*2) ;des Datenblocks setzen
add zl,r16 ;Index dazu addieren
adc zh,null ;Übertrag (Carry) dazu addieren
lpm ;das gewünschte Byte steht nun in r0
wobei 'null' ein unteres Register ist, das den Wert 0 enthält.
...
...zu schnell abgeschickt, es fehlen noch die Daten:
daten:
.db 2,4,6,8,10,20 ;immer geradzahlige Anzahl Bytes
.db "Das ist ein Text!",0 ;immer geradzahlige Anzahl Bytes
...
das ganze ist ein counter von 0-F
wird am portc ausgegeben
und jenachdem ob PINA4 auf "0" oder "1" ist soll der counter
auf/abwärts zählen.
das sram soll verwendet werden um dort das array zu speichern
ist zwar ein flüchtiger speicher, das array wird halt jedesmal neu
geschrieben wenn der baustein vom strom getrennt oder resettet wird.
ist so verlangt das ganze
das mit den daten ablegen im flash würde mich auch interessieren,
allerdings kennt der atmega 16 .db anweisungen nicht. werd nochmals das
manual lesen. allerdings müßte es laut dem gehen so wie ich den
quelltext weiter oben schon gepostet habe....tut es aber nicht