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: Zweite Serielle Schnittstelle mit 255-Byte-Empfangsbuffer Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Dietmar, Homepage - 29.04.2021 18:19)
Dietmar nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi, Open-Mini Station
' ===========================================================================
' Demoprogramm: Zweite Serielle Schnittstelle mit 255-Byte-Empfangsbuffer
' In OCBASIC 1.12a_e1 für Open-Maxi von Dietmar Harlos am 23. April 2021
' ===========================================================================

' Das Betriebssystem unterstützt eine Serielle Schnittstelle mit Empfangs-
' buffer, die mittels SCI2-Modul realisiert ist. Das SCI1-Modul ist also frei.

' In diesem Beispielprogramm wird das SCI1-Modul verwendet, um eine zweite
' Serielle Schnittstelle auf der Open-Maxi zu realisieren. Der Empfang wird
' interruptgesteuert mit 255-Byte-Ringpuffer durchgeführt. Anhand der
' Funktion rxdSCI1 kann der Anwender feststellen, ob wenigstens ein Byte vom
' SCI1-Modul empfangen und in den Buffer eingefügt wurde.

' Die Subroutinen und Funktionen im Einzelnen:

' initSCI1 ... SCI1-Modul initialisieren
' baudSCI1 ... Setzen der Baudrate des SCI1-Moduls
' putSCI1 .... Senden eines Bytes über das SCI1-Modul
' getSCI1 .... Empfangen eines Bytes über das SCI1-Modul (var=getSCI1)
' rxdSCI1 .... Feststellen, ob ein Byte empfangen wurde und im Buffer ist

' TXD2 liegt an PORT[33] und RXD2 liegt an PORT[34]. Das sind die beiden
' niederwertigsten Ports vom fünften Byteport (BYTEPORT[5]).

' Zum Testen dieses Demoprogramms muß TXD2 mit RXD2 verbunden werden.

' Es ließe sich natürlich noch Hardware-Handshake realisieren. Die Ports RTS2
' und CTS2 sind dafür reserviert.

' Im Kapitel 11 ("Serial Communications Interface (S08SCIV2)") im Data Sheet
' zum MC9S08AW60-Mikrocontroller ist das SCI1-Modul beschrieben:

' https://www.nxp.com/docs/en/data-sheet/MC9S08AW60.pdf

' 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 zssbuffer &h2aa 'Buffer an 1. Adresse hinter dem USER-RAM, 256 Bytes lang

DIM zssarray BYTE   'Bitarray
DIM Sci1Err  BIT[1] OF zssarray 'signalisiert Fehler beim Empfang
DEFINE fSci1Err 0

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

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

' --- Unsere eigene Assembler-Interruptroutine ------------------------------

' Die folgende Assembler-Interruptroutine befindet sich im "Serial
' Communications Interface 1 - Receive"-Interrupt und wird gestartet, wenn
' das SCI1-Modul ein Byte empfangen hat.

' Sobald der Interrupt auftritt, wird die Assemblerroutine aufgerufen, wobei
' im Akkumulator der Wert #iSCI1r und im X-Register die Adresse von FREERAM
' übergeben wird. Beendet werden muß die Routine mit RTS. Falls mit
' gelöschtem Carry-Bit ("CLC") beendet wird, führt das Betriebssystem
' die Systemfunktionen zum Interrupt weiter aus. Wird dagegen mit gesetztem
' Carry-Bit ("SEC", bzw. "STC") beendet, ignoriert das System den Interrupt.

' Die folgenden Subroutinen müssen am Anfang des Programms stehen und sollten
' sinnvollerweise in einer INCLUDE-Datei untergebracht werden.

' Das Schlüsselwort INLASM kennzeichnet die folgende PROCEDURE als
' Assemblerroutine (IAR). Dadurch, und daß sie unmittelbar am Anfang
' des Programms steht, wird sie zu einer IIAR, also zu einer Assembler-
' Interruptroutine, die bei einem aktivierten User-Interrupt gestartet wird.

' Der OCBASIC-Compiler setzt automatisch ein "GOTO main" vor diese Routine.

PROCEDURE UIRSci1r_iiar INLASM
! cbeqa #iSCI1r,sci1r_is    'Unterscheidung der Interruptquellen
! jmp UIRSci1r_iiar_next+2  'zur nächsten IIAR in der Kette springen

' Empfangsinterrupt für SCI1

' Hardware interrupt requested when RDRF flag is 1.

' In 8-bit mode, to clear RDRF, read SCIxS1 with RDRF = 1 and then read the
' SCI data register (SCIxD).

' Clear the NF, FE and PF bit by reading SCIxS1 and then read the SCIxD.

#sci1r_is           'SCI1 receive
! lda SCI1S1
! bit #%00000111    'NF FE PF
! bne sci1r_err
! lda SCI1D         'Byte aus Register lesen
! clrh
! ldx tail
! sta zssbuffer,x
! incx
! cmpx head
! beq sci1r_err_1   'Buffer voll? Dann Fehler-Flag setzen
! stx tail
! sec               'Carry-Flag setzen (Betriebssystem ignoriert den Interrupt)
! rts               'Rücksprung zum Betriebssystem
#sci1r_err
! lda SCI1D         'Byte aus Register lesen
#sci1r_err_1
! bset fSci1Err,zssarray  'Fehler-Flag setzen
! sec               'Carry-Flag setzen (Betriebssystem ignoriert den Interrupt)
! rts               'Rücksprung zum Betriebssystem
END PROCEDURE

' SCI1-Modul initialisieren

PROCEDURE initSCI1 INLASM
! ldhx #130              'SCI baud rate = 20E6/(16*130) = 9615.4 Baud (0.16% Abweichung)
! sthx SCI1BDH
! clr SCI1C1             'SCI Control Register 1 (SCIxC1)
! mov #%00101100,SCI1C2  'SCI Control Register 2 (SCIxC2) - Sender, Empfänger und Empfangsinterrupt aktiv
! clr SCI1C3             'SCI Control Register 3 (SCIxC3)
! rts
END PROCEDURE

' Senden eines Bytes über das SCI1-Modul

PROCEDURE putSCI1(datenbyte) INLASM
#putSCI1_1
! brclr bTDRE,SCI1S1,putSCI1_1  'Transmit Data Register Empty Flag (TDRE) im SCI Status Register 1 (SCIxS1)
! sta SCI1D         'SCI Data Register (SCIxD)
! rts
END PROCEDURE

' Empfangen eines Bytes über das SCI1-Modul

' getSCI1 ist eine Funktion, kein Befehl, also "var=getSCI1" statt "getSCI1 var"

FUNCTION getSCI1 INLASM
#getSCI1_1
! lda tail
! sub head
! beq getSCI1_1     'keine Daten im Buffer? Dann auf Daten warten
! clrh
! ldx head
! lda zssbuffer,x
! incx
! stx head
! clrx              'FwPush
! swi
END FUNCTION

' Feststellen, ob ein Byte von der zweiten Seriellen Schnittstelle geholt werden kann

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

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

' Setzen der Baudrate des SCI1-Moduls

PROCEDURE baudSCI1(baudratenkonstante) INLASM
! tsta
! bpl baudSCI1_1
! add #2
#baudSCI1_1
! and #%111
! lsla
! tax
! clrh
! lda $0a26,x       'aus der Baudratentabelle des Betriebssystems lesen
! sta SCI1BDH
! lda $0a27,x
! sta SCI1BDL
! rts
END PROCEDURE

' Debugging

PROCEDURE zssdebug
  ?
  ?"head="head;
  ?"  tail="tail;
  ?"  Sci1Err="Sci1Err
  FOR a=0 TO 255
    ?peek(zssbuffer+a);
  NEXT a
  ?:?
  RETURN
END PROCEDURE

#UIRSci1r_iiar_next         'hier hinter folgt die nächste IIAR
                            '(sofern vorhanden)

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

#main               'durch die IIAR am Programmbeginn wird ein "GOTO main" erzeugt

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

head=0              'Initialisierungen
tail=0
zssarray=0

UIRSci1r=ON         'User-Assemblerroutine für "SCI1 Receive" aktivieren
initSCI1            'SCI1-Modul initialisieren und aktivieren

baudSCI1 R9600 'R300 'R38400      'Baudrate setzen

WHILE TRUE
  ?"Sende"
  FOR a=33 TO 75
    putSCI1 a
  NEXT a

  ?"Empfangen: ";
  WHILE rxdSCI1
    PUT getSCI1     'getSCI1 ist eine Funktion, kein Befehl, also var=getSCI1
  WEND
  ?

  zssdebug

  PAUSE 25
WEND

END                 'Programmende

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

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

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


Passender Link: Bedienungsanleitung zur Open-Macro und Open-Maxi

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

 Antwort schreiben

Bisherige Antworten:

Re: Demoprogramm: Zweite Serielle Schnittstelle mit 255-Byte-Empfangsbuffer (von Joachim - 30.04.2021 0:06)