Hallo
ich programmiere in Assembler und mir fehlen gerade ein paar
Grundkenntnisse.
Ich möchte einen FIFO realisieren. Das Tutorial dazu habe ich schon
gelesen. Einigermaßen klappt das auch mit dem FIFO, nur muss ich noch
ein paar Bedingungen Abfragen. Hierbei bin ich mir nicht so sicher, ob
bzw. wie ich das richtig in Assembler implementiere.
So muss ich z.B. den Fall das Lese- und Schreibpuffer auf der selben
Stelle sind abfragen:
if (buffer.read == buffer.write)
return FAIL;
cp YL, XL
cpc YH, XH
breq fail
Ist das so richtig? Schreibzeige --> Y Lesezeiger --> X
Und wie kann ich eine solche Abfrage realisieren bzw. wie frage ich auf
die Adresse des Schreibpuffer +1 ab?
if (buffer.write + 1 == buffer.read || buffer.read == 0 && buffer.write
+ 1 == BUFFER_SIZE)
Danke für die Mühe im Vorraus
Elbegucker wrote: > Und wie kann ich eine solche Abfrage realisieren bzw. wie frage ich auf > die Adresse des Schreibpuffer +1 ab? Mache eine Kopie (MOVW) in andere Register, addiere dort 1 und vergleiche dann. Du kannst Dir ne ganze Menge Arbeit sparen, wenn ein FIFO mit max 255 Byte ausreicht, indem Du mit Index arbeitest. Dann sind alle Rechnungen 8-Bittig. Nur beim eigentlichen FIFO-Zugriff muß 16-bittig die Startadresse addiert werden. Versuche nicht, sämtliche Variablen in Registern zu halten. Definiere einige Arbeitsregister (Scratchpad) und speichere gerade nicht benötigte Variablen im RAM. Definiere extra Arbeitsregister für Interrupts, spart ne Menge PUSH/POP. Peter
Hallo Peter
ich habe jetzt mal versucht, die Abfrage mit movw zu realisieren.
Könntest du mal auf den Quelltext schauen und gucken, ob das richtig
ist?
.def temp2= r18
.def temp1= r17
.equ buffersize = 64 (beispielhaft)
init_buffer:
ldi XL,low(buffer) ; read-Pointer
ldi XH,high(buffer) ; +1 = erstes Byte aus UDR
ldi YL,low(buffer) ; write-Pointer
ldi YH,high(buffer)
ret
write_SRAM:
movw temp2:temp1,YH:YL
inc temp1
ldi temp3, 0
adc temp2, temp3 ; erhöhen um eins
cp temp1, XL
cpc temp2, XH
breq no_reset_PointerY ; if (write_zeiger +1 == read_zeiger)
; nix machen
; read == 0 && (write+1 == max. Pufferadresse)
cpi temp1,low(buffer+buffersize)
ldi temp3,high(buffer+buffersize)
cpc temp2,temp3
brne write_to_SRAM
cpi XL,low(buffer)
ldi temp1,high(buffer)
cpc XH,temp1
breq no_reset_PointerY
write_to_SRAM:
in temp1, UDR ; UART Daten lesen und in SRAM
schreiben
st Y+, temp1
cpi YL,low(buffer+buffersize) ; Startadresse buffer
; + Länge buffer
ldi temp1,high(buffer+buffersize) ; vergleiche mit der maximalen
; SRAM Adresse
cpc YH,temp1
brne no_reset_pointerY ; wenn ungleich, springen
ldi YL,low(buffer) ; wenn gleich, Zeiger zurücksetzen
ldi YH,high(buffer)
no_reset_PointerY:
ret
read_SRAM:
cp YL, XL
cpc YH, XH
breq no_reset_pointerX ; Lese- auf Schreibezeiger
; --> Lesen nicht sinnvoll
; Lesezeiger nicht erhöhen
ld SRAM_register, X+
cpi XL,low(buffer+buffersize) ; Startadresse buffer
; + Länge buffer
ldi temp1,high(buffer+buffersize) ; vergleiche mit der maximalen
; SRAM Adresse
cpc XH,temp1
brne no_reset_pointerX ; wenn ungleich, springen
ldi XL,low(buffer) ; wenn gleich, Zeiger zurücksetzen
ldi XH,high(buffer)
no_reset_pointerX:
ret
Der obrige Versuch hat (wie ich mittlerweise gemerkt habe) nicht funktioniert. Habe nun den Quelltext wie angehängt modifiziert und denke nun, dass er funktioniert. Vielleicht kann ja nochmal jemand darauf schauen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.