To implement software UART successfully one must understand the basics of UART first and understand its protocol. As mentioned in our UART Basics tutorial. For 8bit, no parity and 1 stop bit UART Transmission, 10 bits are transmitted (startbit, 8-data bits and stop bit). There is a formula to calculate the delay time for 1 bit which is needed between bits to get correct baudrate.

1 bit time = (((crystal/baud)/12) - 5) / 2

Where crystal is the frequency of crystal in Hz baud is the required baudrate we are doing divide by 12 as 8051 architecture single machine cycle is crystal freq/12

Below is a software implemented UART, which can be used in C as well as Assembly programs. It is written for Keil software. But with a little modification you can use it in your programs.


PUBLIC _putc

txd_pin	EQU	P3.1		;Transmit on this pin
rxd_pin	EQU	P3.0		;Receive on this pin

;Formula to calculate the bit time delay constant
;This constant is calculated as: (((crystal/baud)/12) - 5) / 2
;crystal is the frequency of crystal in Hz
;baud is required baudrate
;Please try to keep baudrate below 9600
;to get best results :)

BITTIM	EQU	45;		(((11059200/9600)/12) - 5) / 2

;To send data serially
;For C programs
;Protype definition:
;		void putc(unsigned char);
;		putc(data);
;		This function returns nothing
;For Assembly Programs:
;	data to be send has to be moved to R7
;	for example:
;		mov R7,#'a'
;		lcall _putc
	push ACC
	Push PSW
	mov a,r7
	CLR txd_pin			;Drop line for start bit
	MOV R0,#BITTIM		;Wait full bit-time
	DJNZ R0,$			;For START bit
	MOV R1,#8			;Send 8 bits
	RRC A				;Move next bit into carry
	MOV txd_pin,C		;Write next bit
	MOV R0,#BITTIM		;Wait full bit-time
	DJNZ R0,$			;For DATA bit
	DJNZ R1,putc1		;write 8 bits
	SETB txd_pin		;Set line high
	RRC A				;Restore ACC contents
	MOV R0,#BITTIM		;Wait full bit-time
	DJNZ R0,$			;For STOP bit
	pop ACC

;To receive data Serially
;If you want to use this routine in your
;C program then define function prototype
; as:
;	unsigned char getc(void);
;	Usage:
;		data = getc();
;	Return value:
;		Returns data received
;If you are using it in assembly program
;	Usage:
;		lcall getc
;	Return:
;		data received is stored in R7

	Push ACC
	Push PSW
	JB rxd_pin,$		;Wait for start bit
	MOV R0,#BITTIM/2	;Wait 1/2 bit-time
	DJNZ R0,$			;To sample in middle
	JB rxd_pin,getc		;Insure valid
	MOV R1,#8			;Read 8 bits
	MOV R0,#BITTIM		;Wait full bit-time
	DJNZ R0,$			;For DATA bit
	MOV C,rxd_pin		;Read bit
	RRC A				;Shift it into ACC
	DJNZ R1,getc1		;read 8 bits
	mov r7,a
	pop ACC
	RET					;go home

Now you can have two serial ports or even 3 :) on a normal 8051. Have a happy programming.

See Also

Help & Queries

If you have any queries, doubts or feedback on this tutorial please share in our discussion forum.

Powered by MediaWiki
This page was last modified on 3 March 2015, at 14:18.
ArrayContent is available under Creative Commons Attribution Non-Commercial Share Alike unless otherwise noted.