Das Open-Control-Projekt - Die Alternative zur C-Control-I


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Demoprogramm: Universeller Ringbuffer für 255 Bytes Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Dietmar, Homepage - 25.04.2021 19:04)
Dietmar nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi, Open-Mini Station
' ===========================================================================
' Demoprogramm: Universeller Ringbuffer für 255 Bytes
' In OCBASIC 1.12a_e1 für Open-Maxi von Dietmar Harlos am 23. April 2021
' ===========================================================================

' Im deutschen Sprachgebrauch wird er auch als "Ringpuffer" bezeichnet.

' Der Buffer mit 256 Byte Größe wird hinter dem USER-RAM abgelegt und es
' werden nur die Variablen head und tail verwendet. Die Variable head
' zeigt auf das als nächste zu lesende Byte und tail auf die Stelle, an die
' als nächstes ein neues Byte in den Buffer geschrieben werden kann.

' Der Buffer ist zum Beispiel dazu gedacht, um eine gebufferte Serielle
' Schnittstelle zu realisieren. Die Subroutine put2buffer liegt dann im
' Interrupt und schreibt das vom SCI-Modul empfangene Byte in den Buffer.
' Mit der Funktion getfrombuffer wird es dann im Anwenderprogramm gelesen.
' Außerdem kann mit Hilfe der Funktion buffernotempty festgestellt werden,
' ob sich mindestens ein ungelesenes Byte im Buffer befindet.

' Überlegungen:

' Es sind nur 255 Bytes möglich, da sonst bei 256 Bytes im Buffer head
' gleich tail wäre und so nicht zwischen 256 Bytes und 0 Bytes unterschieden
' werden könnte. Man kommt beim Lesen aus dem Buffer ohne Deaktivierung
' der Interrupts aus. Die beiden Variablen head und tail dürfen auch
' außerhalb der Zeropage liegen.

' An dieser Stelle möchte ich mich bei Dirk von "das |_ Team" und bei
' Norbert für ihre Unterstützung bedanken.

' --- Definitionen ----------------------------------------------------------

INCLUDE "omax.def"  'Definitionen für die Open-Maxi

DEFINE buffer &h2aa 'Buffer an 1. Adresse hinter dem USER-RAM, 256 Bytes lang

DIM status BYTE     'Status-Flags
DIM bfull  BIT[1] OF status
DIM bempty BIT[2] OF status
DEFINE fbfull  0
DEFINE fbempty 1

DIM head BYTE       ' Hallo Welt
DIM tail BYTE       ' ^head     ^tail

DIM a,b,c BYTE      'temporäre Variablen

' --- Hauptprogramm ---------------------------------------------------------

PrintSpc=ON         'SPACE vor einem dezimalen PRINT
End2Host=ON         'Bei Programmende gleich in den Host-Modus wechseln

head=0              'Initialisierungen
tail=0
status=0

?"Ein wenig Demonstration:":?

FOR a=1 TO 5
  put2buffer a
  ?"put2buffer"a
NEXT a

debug

status=0

WHILE buffernotempty
  ?"getfrombuffer="getfrombuffer
WEND

debug

?"257 Bytes in den Buffer schreiben:"

status=0

FOR a=0 TO 255
  put2buffer a
NEXT a
put2buffer 42

debug

END                 'Zurück in den Hostmodus. Neustart mit RETURN-Taste.

' --- Subroutinen und Funktionen --------------------------------------------

' Debugging

PROCEDURE debug
  ?
  ?"head="head;
  ?"  tail="tail;
  ?"  bfull="bfull;
  ?"  bempty="bempty
  FOR a=0 TO 255
    ?peek(buffer+a);
  NEXT a
  ?:?
  RETURN
END PROCEDURE

' Das nächste Byte aus dem Buffer lesen.

' Falls der Buffer leer ist, wird hier ein Empty-Flag gesetzt. Bei einem
' Buffer für Serielle Schnittstellen sollte in einer Endlosschleife gewartet
' werden, bis von der Interruptroutine ein Byte empfangen und in den Buffer
' eingefügt wurde.

FUNCTION getfrombuffer INLASM
! lda tail
! sub head
! bne getfrombuffer_1
! bset fbempty,status
! rts
#getfrombuffer_1
! clrh
! ldx head
! lda buffer,x
! incx
! stx head
! clrx              'FwPush
! swi
END FUNCTION

' Ein Byte an das Bufferende anfügen.

' Falls der Buffer voll ist, wird hier ein Full-Flag gesetzt. Bei einem
' Buffer für Serielle Schnittstellen sollte das Fehler-Flag gesetzt werden.

PROCEDURE put2buffer(datenbyte) INLASM
! clrh
! ldx tail
! sta buffer,x
! incx
! cmpx head
! bne put2buffer_1
! bset fbfull,status
! rts
#put2buffer_1
! stx tail
! rts
END PROCEDURE

' Feststellen, ob ein Byte aus dem Buffer geholt werden kann

' Die Routine liefert ON und OFF zurück, also -1 und 0.

FUNCTION buffernotempty INLASM
! clrx
! lda tail
! sub head
! beq buffernotempty_1 'keine Daten? Dann OFF zurückliefern
! decx
#buffernotempty_1
! txa
! sta OSTEMP
! jmp FwPushW       'das Word OSTEMP:A auf dem Rechenstack speichern
END FUNCTION

' --- INCLUDE-Dateien -------------------------------------------------------

INCLUDE "om_fw.pro" 'INCLUDE-Datei für Firmwareroutinen

' --- Programmende ---------------------------------------------------------


Passender Link: Offizielle Infosite zu den OM-Mikrocontrollern

Meine Homepage: http://ccintern.dharlos.de

 Antwort schreiben

Bisherige Antworten:

Univ. Ringbuffer für 255 Bytes - Pufferinhalt löschen (von das |_ Team - 29.04.2021 23:11)
Re: Demoprogramm: Universeller Ringbuffer für 255 Bytes (von Christian - 25.04.2021 19:57)