;************************************************************************** ; Software Simplex UART Routines ; for 83C751 and 83C752 series Microcontrollers ; Signetics Corporation ;************************************************************************** $Title(Software Driven Simplex UART Routines) $Date(06/27/89) $MOD751 $Debug ;************************************************************************** BaudVal EQU -139 ;Timer value for 9600 baud @ 16 MHz. ;(one bit cell time) StrtVal EQU -39 ;Timer value to start receive. ;(half of one bit cell time, minus the ; time it takes the code to sample RxD) XmtDat DATA 10h ;Data for RS-232 transmit routine. RcvDat DATA 11h ;Data from RS-232 receive routine. BitCnt DATA 12h ;RS-232 transmit & receive bit count. LoopCnt DATA 13h ;Loop counter for test routine. Flags DATA 20h TxFlag BIT Flags.0 ;Receive-in-progress flag. RxFlag BIT Flags.1 ;Transmit-in-progress flag. RxErr BIT Flags.2 ;Receiver framing error. RcvRdy BIT Flags.3 ;Receiver ready flag. TxD BIT P1.0 ;Port bit for RS-232 transmit. RxD BIT P1.5 ;Port bit for RS-232 receive (INT0). ;************************************************************************** ; Interrupt Vectors ORG 0 ;Reset vector. AJMP Reset ORG 03H ;External interrupt 0. AJMP Int0 ;Indicates RS-232 start bit received. ORG 0BH ;Timer 0 interrupt. AJMP Timr0 ;Baud rate generator. ORG 13H ;External interrupt 1 (not used). RETI ORG 1BH ;Timer I interrupt (not used). RETI ORG 23H ;I2C interrupt (not used). RETI ;***************************************************************************** ;Simple test of RS-232 transmit and receive. Reset: MOV SP,#30h MOV Flags,#0 ;Clear RS-232 flags. CLR RxFlag MOV TCON,#00h ;Set up timer controls. MOV IE,#82h ;Enable timer 0 interrupts. MOV LoopCnt,#16 ;Test transmit first. MOV R1,#0 ;Zero line count. MOV DPTR,#Msg1 ;Point to message string. Loop1: ACALL Mess ;Send an RS-232 message repeatedly. MOV A,#':' ACALL XmtByte MOV A,R1 ACALL PrByte ;Print R1 contents. INC R1 ;Advance R1 value. DJNZ LoopCnt,Loop1 Loop2: SETB EX0 ;Enable interrupt 0 (RS-232 receive). JNB RcvRdy,$ ;Wait for data available. CLR RcvRdy MOV A,RcvDat ;Echo same byte. ACALL XmtByte SJMP Loop2 ; Send a byte out RS-232 and wait for completion before returning. ; (use if there is nothing else to do while RS-232 is busy) XmtByte: JB RxFlag,$ ;Wait for receive complete. ACALL RSXmt ;Send ACC to RS-232 output. JB TxFlag,$ ;Wait for transmit complete. RET ; Begin RS-232 transmit. RSXmt: MOV XmtDat,A ;Save data to be transmitted. MOV BitCnt,#10 ;Set bit count. MOV TH,#High BaudVal ;Set timer for baud rate. MOV TL,#Low BaudVal MOV RTH,#High BaudVal ;Also set timer reload value. MOV RTL,#Low BaudVal SETB TR ;Start timer. CLR TxD ;Begin start bit. SETB TxFlag ;Set transmit-in-progress flag. RET ; Timer 0 timeout: RS-232 receive bit or transmit bit. Timr0: PUSH ACC PUSH PSW JB RxFlag,RxBit ;Is this a receive timer interrupt? JB TxFlag,TxBit ;Is this a transmit timer interrupt? T0Ex1: CLR TR ;Stop timer. T0Ex2: POP PSW POP ACC RETI ; RS-232 transmit bit routine. TxBit: DJNZ BitCnt,TxBusy ;Decrement bit count, test for done. CLR TxFlag ;End of stop bit, release timer. SJMP T0Ex1 ;Stop timer and exit. TxBusy: MOV A,BitCnt ;Get bit count. CJNE A,#1,TxNext ;Is this a stop bit? SETB TxD ;Set stop bit. SJMP T0Ex2 ;Exit. TxNext: MOV A,XmtDat ;Get data. RRC A ;Advance to next bit. MOV XmtDat,A MOV TxD,C ;Send data bit. SJMP T0Ex2 ;Exit. ;Begin RS-232 receive (after external interrupt 0). Int0: MOV BitCnt,#10 ;Set receive bit count. MOV TH,#High StrtVal ;First timeout in HALF a bit time. MOV TL,#Low StrtVal MOV RTH,#High BaudVal ;Set timer reload for baud rate. MOV RTL,#Low BaudVal MOV RcvDat,#0 ;Initialize received data to 0. CLR EX0 ;Disable external interrupt 0. CLR RxErr ;Clear error flag. SETB TR ;Start timer. SETB RxFlag ;Set receive-in-progress flag. RETI ; RS-232 receive bit routine. RxBit: DJNZ BitCnt,RxBusy ;Decrement bit count, test for stop. JB RxD,RxBitEx ;Valid stop bit? RxBtErr: SETB RxErr ;Bad stop bit, tell mainline. RxBitEx: CLR RxFlag ;Release timer for other purposes. SETB EX0 ;Re-enable external interrupt 0. SETB RcvRdy ;Tell mainline that a byte is ready. SJMP T0Ex1 ;Stop timer and exit. RxBusy: MOV A,BitCnt ;Get bit count. CJNE A,#9,RxNext ;Is this a start bit? JB RxD,RxBtErr ;Valid start bit? SJMP T0Ex2 ;Exit. RxNext: MOV A,RcvDat ;Get partial receive byte. MOV C,RxD ;Get receive pin value. RRC A ;Shift in new bit. MOV RcvDat,A ;Save updated receive byte. SJMP T0Ex2 ;Exit. ; Print byte routine: print ACC contents as ASCII hexadecimal. PrByte: PUSH ACC SWAP A ACALL HexAsc ACALL XmtByte POP ACC ACALL HexAsc ;Print nibble in ACC as ASCII hex. ACALL XmtByte RET ; Hexadecimal to ASCII conversion routine. HexAsc: ANL A,#0FH ;Convert a nibble to ASCII hex. JNB ACC.3,NoAdj JB ACC.2,Adj JNB ACC.1,NoAdj Adj: ADD A,#07H NoAdj: ADD A,#30H RET ; Message string transmit routine. Mess: PUSH ACC MOV R0,#0 ;R0 is character pointer (string Mesl: MOV A,R0 ; length is limited to 256 bytes). MOVC A,@A+DPTR ;Get byte to send. CJNE A,#0,Send ;End of string is indicated by a 0. POP ACC RET Send: ACALL XmtByte ;Send a character. INC R0 ;Next character. SJMP Mesl Msg1: DB 0Dh, 0Ah DB 'This is a test of the software RS-232 transmit routine' DB 0 END