Digchip : Database on electronics components
 
Member, Distributor  
Log In
Email:
Password:


Part: AN446

Category:

Description:

Company:

Datasheet: Download AN446 datasheet     File size : 50 kB

Request For quote: Find where to buy AN446



Datasheet text preview:
Philips Semiconductors Microcontroller Products

Application Note

A software duplex UART for the 751/752
Author: Greg Goodhue
The following program contains routines that will allow an 8xC751 or 8xC752 to implement a software UART that can send and receive serial data simultaneously. Other published software UARTs only allow either transmit or receive to occur at any one time. The demo application shown in the code listing waits for data to be received, then echoes it and follows this with a hexadecimal interpretation of the data plus a space. For instance, if the program receives the character "$", it echoes back the string "$24". The reason for echoing these additional characters is to make it easy to force the receiver buffer to fill up in order to test the handshaking. If the program simply echoed what was received, it would likely never use more than the very first receiver buffer location since it can normally transmit just as fast as it can receive. synch and only one timer and one interrupt per bit is needed to do both operations. In the second case (transmit is requested while the receiver is busy) the program could just wait for the next bit time to start transmitting. Unfortunately, the third case presents a problem. If the program is already transmitting, it cannot always wait for the next bit time to start sampling the serial data if the application is not to lose bits. Also, the timer cannot be adjusted to the incoming data since this would distort the duration of one of the transmitted bits. The method used here to deal with this problem is to always divide all bit times into 4 sub-bit times. When transmission and/or reception is in progress, the timer runs at 4X the bit rate for the selected baud rate. The variables TxTime and RxTime are used to count sub-bit times for the transmitter and the receiver, respectively. Both are initialized to a negative value and count up to simplify testing for an active sub-bit time. The maximum baud rate that can be supported is essentially determined by the maximum amount of time that it might take the microcontroller to do all of the operations associated with transmitting one bit and receiving one bit . This must be done within the time between timer interrupts. When both transmit and receive operations are scheduled for the same timer interrupt, priority is given to the transmitter routine. The reason for this is that a great deal of jitter can be tolerated in the timing of the received bit sampling, but the transmitted data must "look" good to the outside world. The actual bit times for transmit and receive are counted by the variables TxCnt and RxCnt, respectively. When an active sub-bit time slice occurs, these variables tell the transmit and receive routines what to do in the current time slice. The value 11 hex indicates a start bit, 10 hex indicates a stop bit, and the values 8 through F hex indicate a data bit. The values were chosen to allow quick determination of the appropriate action by the code. The routines provide for a small amount of data buffering for both the transmitter and the receiver. As implemented here, the transmitter buffer is only one byte deep, allowing one data byte to be held while another is being transmitted. The receiver buffer is larger, allowing three bytes to be held while a fourth is being received. If the receiver buffer fills up (indicated by the flag RxFull), the application code must retrieve one byte before a fourth one finishes, or data will be lost. If this happens, a flag will be set (OverrunErr) to indicate that the receiver buffer has been overrun. There is no similar 1

AN446

flag for the transmitter, since the transmit request routine waits for the transmitter buffer to be available (indicated by the TxFull flag) before taking action. It is up to the application code to check this flag in advance if it does not want to stall execution while waiting to transmit data. As each routine finishes a whole data byte by completing the send or receive of a stop bit, it checks to see if there is something still happening to warrant having the time slice interrupt running. In the case of a received stop, the transmit activity flag (TxOn) is examined. If it is not set, the timer is turned off. The timer will be turned back on if an interrupt from a serial start bit is received or the main code requests data to be transmitted. In the case of a transmitted stop, both the receiver activity flag (RxOn) and the transmit buffer flag (TxFull) are examined. If the receiver is active or there is more data to transmit, the timer is left running. All of the status flags are in the "Flags" register. Other status flags found there are: RxAvail, which indicates that the receiver buffer contains unprocessed data; and FramingErr which is set when the receiver routines find an improper start or stop bit, usually caused by mismatched baud rates. Flow control handshaking is provided by the RTS/CTS scheme. The transmit routine looks at the incoming CTS line before beginning each start bit transmission, and simply exits, waiting for the next time slice, if CTS is not asserted. The receive routine checks the buffer status whenever a start bit interrupt occurs and de-asserts the outgoing RTS line if the buffer already contains two bytes (i.e., it will be full when the current byte finishes). If the device at the other end of the communication line follows the same rules (which may very well NOT be the case) the program should be able to communicate without buffer overflows in either direction. Baud rates in both the send and receive routines are determined by two things: the timer interrupt rate; and the number of time slices per bit. The method of calculating the timer value for various baud rates is discussed in the code listing at the BaudRate routine. This discussion has centered on there being four time slices per bit, but if the user wants, either the transmitter or the receiver can be set to run at a baud rate that is a multiple of the other by adjusting the value of the constant TxBitLen or RxBitLen. The baud rate would be calculated as indicated for the faster channel, and TxBitLen or RxBitLen would be changed for the slower channel. For example, the transmitter can be set to run at half of the receiver baud rate by setting TxBitLen to ­8 + 1.

CHIP RESOURCES
The UART routines use about 400 bytes of code space and use the timer to provide a constant time interrupt to synchronize both transmit and receive operations. The hardware connections require four device pins to accomplish serial I/O with RTS/CTS handshaking. Only two pins would be needed if handshaking is not required. Three of the four pin functions may be assigned to any port pin. The serial input pin must be assigned as one of the external interrupt pins. Another two pins are used in the demo application to input a selection of one of four baud rates (1200, 2400, 4800, or 9600).

LIMITATIONS
To obtain duplex operation, a fairly large portion of the chip's time is used. The routines were tested up to 9600 baud running on a 16 MHz 87C751. When serial input and output were both occurring at the same time, the routines could not support continuous operation with no pauses between characters. At 4800 baud, full speed tight reception and transmission worked flawlessly. In other words, 4800 baud should work with all applications, while 9600 baud may not work with all applications.

THEORY OF OPERATION
There are three possible sequences of events when serial transmit and receive may both be operating at once: transmit and receive begin simultaneously; transmit is requested while the receiver is busy; and receive starts while the transmitter is busy. The first 2 cases could be handled fairly simply with only one interrupt for each bit time. In the first case, everything is already in June 1993

Philips Semiconductors Microcontroller Products

Application Note

A software duplex UART for the 751/752

AN446

The routines shown also make provision for changing the baud rate "on the fly", although the application code given does not implement this feature. If the application code changes the baud rate for some reason, the change will be effected when the next data transmission or reception begins, if both the transmitter and receiver were already idle. This prevents the timer value from being changed in the middle of a data byte.

THE CODE
There are a number routines in the code of which the user should be aware: ­ Intr0--Called (by interrupt) when a serial start bit is received. ­ Timer0--Called (by interrupt) for every sub-bit time slice. ­ RS232TX--Called by Timer0 when the transmitter has business to conduct in the current time slice. ­ RS232RX--Called by Timer0 when the receiver has business to conduct in the current time slice. ­ BaudRate--Sets the baud rate variables ­

­

­ ­

BaudHigh and BaudLow based on the accumulator value. TxSend--Called by the application code to request that a data byte be transmitted. The data to be transmitted is in the accumulator. GetRx--Called by the application code to request return of a received data byte from the buffer. Data is returned in the accumulator. This routine should not be called unless the receiver buffer has data available. Reset--Start of the initialization code to set up the UART. MainLoop--Start of the mainline code of the demo application.

June 1993

2

Philips Semiconductors Microcontroller Products

Application Note

A software duplex UART for the 751/752

AN446

;******************************************************************************* ; Duplex UART Routines for the 8xC751 and 8xC752 Microcontrollers

;******************************************************************************* ; This is a demo program showing a way to perform simultaneous RS­232 ; transmit and receive using only one hardware timer. ; The transmit and receive routines divide each bit time into 4 slices to ; allow synchronizing to incoming data that may be out of synch with outgoing ; data. ; ; ; ; ; The main program loop in this demo processes received data and sends it back to the transmitter in hexadecimal format. This insures that we can always fill up the receiver buffer (since the returned data is longer than the received data) for testing purposes. Example: if the letter "A" is received, we will echo "A41 ".

;******************************************************************************* $Title(Duplex UART Routines for the 751/752) $Date(8/20/92) $MOD751 ;******************************************************************************* ; Definitions

;******************************************************************************* ; Miscellaneous TxBitLen RxBitLen RxHalfBit EQU EQU EQU ­4 + 1 ­4 + 1 (RxBitLen / 4) + 1 ; Timer slices per serial bit transmit. ; Timer slices per serial bit receive. ; Timer slices for a partial bit time. ; Used to adjust the input sampling ; time point.

; Note: TxBitLen and RxBitLen are kept separate in order to facilitate the ; possibility of having different transmit and receive baud rates. The timer ; would be set up to give four slices for the fastest baud rate, and the ; BitLen for the slower channel would be set longer for the slower baud rate. ; BitLen = ­4 + 1 gives four timer interrupts per bit. BitLen = ­8 + 1 would ; give 8 slices, BitLen = ­16 + 1 would give 16 slices, etc. TxPin BIT P1.0 RxPin BIT P1.5 RTS BIT P1.3 CTS BIT P1.6 ; Note: P1.1 and P1.2 are used to input ; RAM Locations Flags TxOn RxOn TxFull RxFull RxAvail OverrunErr FramingErr BaudHigh BaudLow TxCnt TxTime TxShift TxDat June 1993 DATA BIT BIT BIT BIT BIT BIT BIT DATA DATA DATA DATA DATA DATA 20h Flags.0 Flags.1 Flags.2 Flags.3 Flags.4 Flags.6 Flags.7 21h 22h 23h 24h 25h 26h ; ; ; ; ; ; ; ; Miscellaneous bit flags (see below). Indicates transmitter is on (busy). Indicates receiver is on (busy). Transmit buffer (1 byte only) is full. Receiver buffer is full. RX buffer is not empty. Overrun error flag. Framing error flag. ; RS­232 ; RS­232 ; RS­232 ; RS­232 the baud transmit pin (output). receive pin (input). request to send pin (output). clear to send pin (input). rate selection.

; High byte timer value for baud rate. ; Low byte timer value for baud rate. ; ; ; ; RS­232 byte transmit bit counter. RS­232 transmit time slice count. Transmitter shift register. Transmitter holding register. 3

Philips Semiconductors Microcontroller Products

Application Note

A software duplex UART for the 751/752

AN446

RxCnt RxTime RxShift RxDatCnt RxBuf Temp

DATA DATA DATA DATA DATA DATA

27h 28h 29h 2Ah 2Bh 2Fh

; ; ; ; ;

RS­232 byte receive bit counter. RS­232 receive time slice count. Receiver shift register. Received byte count. Receive buffer (3 bytes long).

; Temporary holding register.

;******************************************************************************* ; Interrupt Vectors

;******************************************************************************* ORG AJMP ORG AJMP ORG AJMP ORG RETI ORG RETI ORG RETI 00h RESET 03h Intr0 0Bh Timer0 13h ; Reset vector.

; External interrupt 0 ; (received RS­232 start bit). ; Timer 0 overflow interrupt. ; (4X the RS­232 bit rate). ; External interrupt 1. ; (not used). ; Timer I interrupt. ; (not used). ; I2C interrupt. ; (not used).

1Bh

23h

;******************************************************************************* ; Interrupt Handlers

;******************************************************************************* ; External Interrupt Int0. ; RS­232 start bit transition. Intr0: PUSH PUSH CLR SETB MOV MOV JB MOV MOV MOV MOV SETB I0TimerOn: MOV CJNE SETB ACC PSW IE.0 RxOn RxCnt,#11h RxTime,#RxHalfBit TxOn,I0TimerOn RTH,BaudHigh RTL,BaudLow TH,BaudHigh TL,BaudLow TR A,RxDatCnt A,#2,Int0Ex RTS ; Save accumulator, ; and status. ; Disable more RX interrupts. ; ; ; ; Set receive active flag. Set bit counter to expect a start. First sample is at a partial bit time. If TX active then timer is on.

; Set up timer for selected baud rate.

; Start timer 0. ; Check for buffer about to be full: ; one space left and a byte starting. ; If so, tell whoever is on the ; other end to wait. ; Restore status, ; and accumulator.

Int0Ex:

POP POP RETI

PSW ACC

; Timer 0 Interrupt ; This is used to generate time slices for both serial transmit and receive ; functions. June 1993 4

Philips Semiconductors Microcontroller Products

Application Note

A software duplex UART for the 751/752

AN446

Timer0:

PUSH PUSH JNB JNB INC JNB JNB INC

ACC PSW TxTime.7,RS232TX TxOn,CheckRx TxTime RxTime.7,RS232RX RxOn,T0Ex RxTime PSW ACC P3,Flags

CheckRx:

; ; ; ; ; ; ; ; ; ;

Save accumulator, and status. Is this an active time slice for an RS­232 transmit? If transmit is active, increment the time slice count. Is this an active time slice for an RS­232 receive? If receive is active, increment the time slice count.

T0Ex:

POP POP MOV

; Restore status, ; and accumulator. ; For demo purposes, output status ; on an extra port.

RETI ;******************************************************************************* ; RS­232 Transmit Routine

;******************************************************************************* RS232TX: JNB JNB TxCnt.4,TxData TxCnt.0,TxStop ; Go if data bit. ; Go if stop bit.

; Send start bit and do buffer housekeeping. TxStart: JB CLR MOV CLR MOV CTS,TxEx1 TxPin TxShift,TxDat TxFull TxCnt,#08h ; Is CTS asserted (low) so can we send? ; If not, try again after 1 bit time. ; Set start bit. ; Get byte to transmit from buffer. ; Init bit count for 8 bits of data. ; (note: counts UP). ; Reset time slice count. ; Restore state and exit.

TxEx1:

MOV SJMP

TxTime,#TxBitLen CheckRx

; Send Next Data Bit. TxData: MOV RRC MOV MOV INC MOV SJMP A,TxShift A TxPin,C TxShift,A TxCnt TxTime,#TxBitLen CheckRx ; ; ; ; ; ; ; Get un­transmitted bits. Shift next TX bit to carry. Move carry out to the TXD pin. Save bits still to be TX'd. Increment TX bit counter Reset time slice count. Restore state and exit.

; Send Stop Bit and Check for More to Send. TxStop: SETB JB CLR CLR TxPin TxFull,TxEx2 TxOn RTS ; Send stop bit. ; More data to transmit? ; If not, turn off TX active flag, and ; make sure that whoever is on the ; other end knows it's OK to send. ; If receive active, timer stays on, ; otherwise turn off timer. ; Set TX bit counter for a start. ; Reset time slice count, stop bit ; > 1 bit time for synch. ; Restore state and exit. 5

JB CLR TxEx2: MOV MOV SJMP June 1993

RxOn,TxEx2 TR TxCnt,#11h TxTime,#TxBitLen­1 CheckRx




Others parts begin by an
AN-1   AN-2   AN-3   AN-4   AN-5   AN-6   AN-7   AN-8