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.