;v 219 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * ; ; Gepufferte Ein- und Ausgabe zu den Rs232-Schnittstellen ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * ; Interrupt's einschalten segment bitdata rs232DirectSend: db ? segment code ; ein zeichen in den outputpuffer schreiben Rs232SendChar: push ar0 push acc ; Wenn rs232DirectSend 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 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 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 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 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 ;orl ip,#00010010b ; Prioritäten -> serial kriegt prio 1 ret segment data rs232LastSendByte: db ? rs232LastStoreByte: db ? rs232LastReadByte: db ? rs232LastRecByte: db ? LastDataAddress: ; im indirect-Bereicht -> Puffer sind nur über @rn erreichbar org 080h rs232OutBuffer: db YYRs232OutBufSize dup ? rs232OutBufferEnd: rs232InBuffer: db YYRs232InBufSize dup ? rs232InBufferEnd: org LastDataAddress segment bitdata rs232InRequest: db ? segment code