I have learned one way to read from a serial port via software UART is via timer interrupts. I have made an implementation of receiving data from one serial port below. I haven't tested it yet because I now also need a way to efficiently transmit data as well without causing bad timings since UART is a timer sensitive protocol. If possible, I want to use one timer to manage both UARTs.
The speed I'm aiming for is 9600bps, and my microcontroller has a crystal speed of 22.1184Mhz. Also, is my code optimized or could I optimize it further so that fewer clock cycles are required for serial processing?
RX equ P3.0 ;receive bit TX equ P3.1 ;xmit bit sermode equ 23h ;serial mode. SWBUF equ 22h ;stored data SWTBUF equ 24h ;stored data temporarily SWI bit 0h ;1=received valid data org 0000h ;machine start ljmp startapp org 000Bh ;Timer interrupt ljmp timerint org 0030h timerint: push PSW mov C,RX ;get bit asap push ACC mov TH0,#0FFh ;reset high timer byte mov A,sermode jnz serhalfbit ;entered every half bit time if sermode=0 ;do nothing till bit is zero jc nostart ;set mode to 1 inc sermode ;set access speed to slow mov TL0,#040h ;prepare to exit sjmp extimerint nostart: serhalfbit: jz serfullbit ;this is entered every full bit time if sermode > 0 jnb ACC.0,noend jnb ACC.3,noend ;if sermode=9, reset it... mov sermode,#0h ;set usable buffer to temporary buffer value mov SWBUF,SWTBUF ;set SWI to stop bit value. 1=valid data... mov SWI,C ;set access speed to fast mov TL0,#0A0h sjmp extimerint noend: ;if sermode=1 to 8, get bit into a buffer and increment mode mov A,SWTBUF RRC A mov SWTBUF,A inc sermode serfullbit: extimerint: ;common exit from interrupt pop ACC pop PSW reti startapp: mov P1,#0FFh ;reset GPIO mov P3,#0FFh mov sermode,#0h ;start at beginning mov TH0,#0FFh mov TL0,#0A0h ;9.6kbps half bit time mov TMOD,#11h ;16-bit timers setb PT0 ;timer 0=high priority setb TR0 ;timer 0 on mov IE,#81h ;en Timer 0 int bigloop: ; --async function here-- jnb SWI,novalid clr SWI mov A,SWBUF ; A=received serial data novalid: sjmp bigloop