;v 222 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Gepufferte Ein- und Ausgabe zur Rs232-Schnittstelle ; ; ; ; Rs232SendChar: Ausgeben eines Zeichens an die RS232 ; Schnittstelle ; In: a : Zu sendendes Zeichen ; Out: ; ; ; ; Rs232ReceiveChar: Übertragen eines eingelesenen Zeichens ; aus der RS232. Rs232ReceiveChar sollte nur ; aufgerufen werden, wenn Zeichen über die ; RS232 Schnittstelle empfangen wurden ; (rs232InRequest=1). ; In: - ; Out: a : Eingelsenes Zeichen ; ; ; initrs232buf : Puffer initialisieren und Interrupt scharf ; schalten. Baud-Rate muß vorher festgelegt ; sein. ; ; Weitere Parameter von Aussen ; ; YYRs232OutBufSize: legt die Größe des Sendepuffers fest ; YYRs232InBufSize: legt die Größe des Empfangspuffers fest ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * segment code ;* * * * * * * * * * * * * * * * * * ; Ein Zeichen über RS232 versenden ;* * * * * * * * * * * * * * * * * * Rs232SendChar: push ar0 push acc ; Wenn rs232DirectSend=1, kann das Zeichen direkt ausgegeben werden jnb rs232DirectSend,IFrs232buf1 ;|`_if bit=1 rs232DirectSend pop acc mov sbuf,a clr rs232DirectSend jmp ELSErs232buf1 IFrs232buf1: ;|`_else ; nächste Pufferadresse berechnen inc rs232LastStoreByte mov a,rs232LastStoreByte mov r0,a cjne a,#rs232OutBufferEnd,IFrs232buf2 ;|f_if a=#rs232OutBufferEnd ; Rollover mov r0,#rs232OutBuffer mov rs232LastStoreByte,r0 IFrs232buf2: ;|L_endif ; Zeichen in den Puffer schreiben pop acc mov @r0,a ELSErs232buf1: ;|N_endif pop ar0 ret ;* * * * * * * * * * * * * * * * * * ; Ein empfangenes Zeichen abholen ;* * * * * * * * * * * * * * * * * * Rs232ReceiveChar: push ar0 ; Schreibzeiger=Lesezeiger -> nix zum lesen mov a,rs232LastReadByte cjne a,rs232LastRecByte,IFSrs232buf3 jmp IFrs232buf3 IFSrs232buf3: ;|†_if a<>rs232LastRecByte ; Lesezeiger neu berechnen inc rs232LastReadByte mov a,rs232LastReadByte mov r0,a cjne a,#rs232InBufferEnd,IFrs232buf4 ;|e_if a=#rs232InBufferEnd ; Rollover mov r0,#rs232InBuffer mov rs232LastReadByte,r0 IFrs232buf4: ;|L_endif ; Wenn noch Zeichen da sind -> rs232InRequest mov a,r0 cjne a,rs232LastRecByte,IFrs232buf5 ;|d_if a=rs232LastRecByte clr rs232InRequest jmp ELSErs232buf5 IFrs232buf5: ;|`_else setb rs232InRequest ELSErs232buf5: ;|N_endif mov a,@r0 jmp ELSErs232buf3 IFrs232buf3: ;|`_else mov a,#0 clr rs232InRequest ELSErs232buf3: ;|N_endif ;mov a,rs232InBuffer pop ar0 ret ;* * * * * * * * * * * * * * * * ; Interrup-Handler für rs232 ;* * * * * * * * * * * * * * * * rs232irq: push psw push acc push ar0 ; Handler kann aufgerufen werden, wenn alle Bytes gesendet sind, ; oder wenn ein Byte gelesen werden muß ; Zuerst prüfen, welcher Art von Interrupt vorliegt jnb scon.0,IFrs232buf6 ;|W_if bit=1 scon.0 ;* * * * * * * * * * * * * * * * ; Receive-Interrupt ;* * * * * * * * * * * * * * * * clr scon.0 ; Schreibzeiger neu berechnen inc rs232LastRecByte mov a,rs232LastRecByte mov r0,a cjne a,#rs232InBufferEnd,IFrs232buf7 ;|e_if a=#rs232InBufferEnd mov r0,#rs232InBuffer mov rs232LastRecByte,r0 IFrs232buf7: ;|L_endif mov @r0, sbuf setb rs232InRequest IFrs232buf6: ;|L_endif jnb scon.1,IFrs232buf8 ;|W_if bit=1 scon.1 ;* * * * * * * * * * * * * * * * ; Send-Interrupt ;* * * * * * * * * * * * * * * * clr scon.1 ; Noch was zum Senden da? ; Die beiden Zeiger (Schreiben und Lesen sind nicht ; gleich, wenn noch was gesendet werden muß) mov a,rs232LastSendByte cjne a,rs232LastStoreByte,IFSrs232buf9 jmp IFrs232buf9 IFSrs232buf9: ;|ˆ_if a<>rs232LastStoreByte ; Sendezeiger erhöhen inc a ; steht schon in a :-) cjne a,#rs232OutBufferEnd,IFrs232buf10 ;|g_if a=#rs232OutBufferEnd mov a,#rs232OutBuffer IFrs232buf10: ;|M_endif mov rs232LastSendByte,a ; Zeiger in R0 laden... mov r0,a mov a,@r0 mov sbuf,a jmp ELSErs232buf9 IFrs232buf9: ;|`_else ; Wenn kein Ziechen mehr im Puffer steht, ; kann das nächste Zeichen direkt versendet werden setb rs232DirectSend ELSErs232buf9: ;|N_endif IFrs232buf8: ;|L_endif endofnnn: pop ar0 pop acc pop psw reti ;* * * * * * * * * * * * * * * * * * ; Die Initialisierung ;* * * * * * * * * * * * * * * * * * initrs232buf: ; Pointer richtig setzten mov rs232LastSendByte,#rs232OutBuffer mov rs232LastStoreByte,#rs232OutBuffer setb rs232DirectSend mov rs232LastRecByte,#rs232InBuffer mov rs232LastReadByte,#rs232InBuffer clr rs232InRequest ; Interrupt einschalten ;76543210' setb ie.4 ; es auf eins schalten -> Serielle Interrupt zulassen ret ;* * * * * * * * * * * * * * * * ; benötigte Daten ;* * * * * * * * * * * * * * * * segment bitdata rs232DirectSend: db ? ; koordiniert das direkte Senden ; =1 -> Char kann direkt in die RS232 geschrieben werden ; =0 -> Char muss in den Puffer rs232InRequest: db ? ; Eoinlesestatus der RS232 Schnittstelle ; =1 es sind Zeichen zumeinlesen vorhanden ; =0 keine Zeichen vorhanden segment data rs232LastSendByte: db ? ; Zeiger auf das zuletzt aus dem Puffer gelesene Byte rs232LastStoreByte: db ? ; Zeiger auf das zuletzt in den Puffer geschriebene Byte rs232LastReadByte: db ? ; Zeiger auf das zuletzt aus dem Puffer gelesene Byte rs232LastRecByte: db ? ; Zieger auf das zuletzt in den Puffer geschriebene Byte LastDataAddress: ; aktuelle Adresse merken ; Definition der Pufferbereiche ; im indirect-Bereich -> Puffer sind nur über @rn erreichbar org 080h rs232OutBuffer: db YYRs232OutBufSize dup ? rs232OutBufferEnd: rs232InBuffer: db YYRs232InBufSize dup ? rs232InBufferEnd: org LastDataAddress ; ... und weiter im normalen RAM bereich segment code