;internal RAM flag0 equ 0x20 send_lock equ flag0.0 error_flag equ flag0.1 ctx_enable equ flag0.2 cpu_receiver_return_value equ 0x30 opmem1 equ 0x31 opmem2 equ 0x32 ;external RAM CPU_uart_rx_offset equ 0x115 terminating_char1 equ 0x116 terminating_char2 equ 0x117 ;terminating characters: at the beginning of program You can setup the terminating character(s) of string that will be ;received by UART. In case of 0xd 0xa you should write 0xd to terminating_char1 and 0xa to terminating_char2. In case of ;one terminating byte, for example 0xd, you have to write 0xd to terminating_char1 and 0xFF to terminating_char2. ;Note: this routine cannot detect 0xFF as terminating character,using this value is prohibited. org 0x23 ljmp cpu_serial_irq ;---------------------------------------------------------------------------------------------------------------------------- ;input: UART interrupt ;receiver module: ;input: UART interrupt, RI ;output: receiver buffer: 0xN1-0xNFF, where N has been declared by value at memory address named 'CPU_uart_rx_offset' ;return value: cpu_receiver_return_value, where '1' means character is received, '2' means string is received cpu_serial_irq: jnb ti,cpu_serial_irq_receiver ;transmit interrupt? clr ti ;clear transimt interrupt clr send_lock ;clear lock for transmitter driver cpu_serial_irq_receiver: jnb ri,cpu_serial_irq_exit ;receiver interrupt? clr ri ;clear receiver interrupt mov cpu_receiver_return_value,#1 ;set 1 to 'character received' status push acc push psw push dph push dpl push flag0 mov dptr,#CPU_uart_rx_offset ;contains value that declares the receiver buffer position movx a,@dptr mov dph,a ;setup the receiver buffer pointer upper byte mov dpl,#0 ;0xN0 shows the string lenght in the buffer movx a,@dptr mov dpl,a ;set the lower byte of pointer xrl a,#0xFF ;if the lenght reached 0xFF, should be reset it jz cpu_serial_irq_receiver_overflow ;in this case the string will lose mov a,sbuf ;recall byte from hardware register inc dptr ;increment the pointer movx @dptr,a ;save byte to buffer mov a,dpl ;load new pointer position to accu mov dpl,#0 ;save new ponter to 0xN0 movx @dptr,a lcall check_terminating_characters ;check if terminating string was received jbc error_flag,cpu_serial_irq_receiver_exit mov cpu_receiver_return_value,#2 ;set 2 to 'string received' status cpu_serial_irq_receiver_exit: pop flag0 pop dpl pop dph pop psw pop acc cpu_serial_irq_exit: reti cpu_serial_irq_receiver_overflow: clr a mov dpl,#0 ;reset pointer movx @dptr,a sjmp cpu_serial_irq_receiver_exit ;------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------ ;CPU UART driver ;input: transfer area ;control: Nx0 = summa byte count, Nx1 = transfr byte count ;ontrol: ctx_enable, send_lock @ CPU_UART_control ;output: SBUF ;note: after buffer initializing, the ctx_enable flag should be set to 1 by the initialiser routine ;0xN0: string lenght ;0xN1: byte counter ;0xN2-0xNFF: tarnsmittable string serial_transfer_driver: ;called by main loop jnb ctx_enable,serial_transfer_driver_exit ;cleared if the buffer doesn't contain transmittable characters jb send_lock,serial_transfer_driver_exit ;transmitter buffer upper byte mov dptr,#CPU_uart_tx_offset movx a,@dptr mov dph,a mov dpl,#0 movx a,@dptr ;string lenght jz serial_transfer_driver_reset ;exit and go to idle, if the lenght = 0 inc a mov opmem1,a inc dptr movx a,@dptr ;byte counter inc a movx @dptr,a push acc mov dpl,a ;new byte pointer movx a,@dptr setb send_lock ;lock this routine untill ti flag is 1 mov sbuf,a pop acc xrl a,opmem1 ;check the lenght with the byte counter jnz serial_transfer_driver_exit ;if not equal, exit serial_transfer_driver_reset: ;byte counter equal with lenght -> string end clr ctx_enable ;this routine switched off mov dpl,#0 clr a ;reset byte counters and lenght movx @dptr,a inc dptr mov a,#1 movx @dptr,a serial_transfer_driver_exit: ret ;------------------------------------------------------------------------------------------------------------ ;how can we check a 2 bytes terminating string (example: 0xd 0xa) ;this routine used in UART receiver interrupt, after the current byte is saved to buffer check_terminating_characters: push acc push opmem1 push opmem2 push dph mov dptr,#terminating_char1 movx a,@dptr mov opmem1,a ;endchar 1 mov dptr,#terminating_char2 movx a,@dptr mov opmem2,a ;endchar 2 pop dph mov dpl,#0 movx a,@dptr ;pointer mov dpl,a mov a,opmem2 ;load endchar 2 xrl a,#0xFF jz check_terminating_characters_b1 ;if not exist, check endchar 1 movx a,@dptr xrl a,opmem2 jnz check_terminating_characters_mismatch ;if exist and mismatch, jump to _mismatch_ and exist mov a,opmem1 ;check if endchar 1 exist xrl a,#0xFF jz check_terminating_characters_match ;if not exist endchar 1, jump to _match_ and exist mov a,dpl clr c subb a,#3 ;if dpl<3, forced to _mismatch_, drop it, when buffer received a terminating string only jc check_terminating_characters_mismatch dec dpl ;set pointer to previous character movx a,@dptr xrl a,opmem1 ;check if endchar 1 match jnz check_terminating_characters_mismatch check_terminating_characters_match: clr error_flag ;shows that the received character is a terminating byte or second half check_terminating_characters_exit: ;of a terminating string pop opmem2 pop opmem1 pop acc ret check_terminating_characters_b1: ;check endchar 1, when endchar 2 does not exist mov a,opmem1 xrl a,#0xFF jz check_terminating_characters_match ;check if endchar 1 exist movx a,@dptr xrl a,opmem1 jz check_terminating_characters_match ;if endchar 1 does not exist, jump to _exit_ and set receivced_status to 1 check_terminating_characters_mismatch: setb error_flag ;shows that the received character is not a part of terminating string sjmp check_terminating_characters_exit