Universal Asynchronous Receiver Transmitter (UART)
What is Universal Asynchronous Reciver Transmitter (UART) ???
Universal Asynchronous Receiver Transmitter (UART) is a chip used in PC system used for translation of serial data or parallel data. PC/AT systems use 16550 UART, but the most recent systems use the latest version of UART PC16550D.
Here the Internal Hardware structure ,UART Registers ,and a samples on UART are explained in this tutorial.There are a few lists of registers with their expanded form and also a few examples of programming the PC16550D UART Chip.
- Initializing the PC16550D UART
- Transmitting Data
- Receiving Data
=====================================================================
Internal Hardware Block
The PC16550D has two independent transmitter and receiver divisions for serial communication.Each division has separate First In First Out(FIFO) memories and they can store up to 16 bytes in each memory.The UART has programmable baud rate generator that divides the reference clock frequency.The UART performs the required serial to parallel; or parallel to serial conversions.It also enables selection of character of length through program.It adds or deletes start, stop or parity bits,etc from the serial data and operates at a baud rate between 0 and 1.5 MegaBytes (MB=1024 Kilo Bytes). The UART can provide the status information at any time during its operation.The information provided are type and condition of the transfer operations, and error conditions such as parity, overrun, framing, break interrupt.
=====================================================================
Internal Registers
-------------------------------------------------------------------------------------------------------------------------------
Register Address Function
DLAB : A2:A1:A0
-------------------------------------------------------------------------------------------------------------
Receive Buffer Register 0:0:0:0 (Read)Holds the last byte received in
Transmitter Holding Register 0:0:0:0 (Write)Holds the byte waiting to be
transmitted
Interrupt Enable Register 0:0:0:1 Enables the 5 types of Interrupts
Interrupt Identification Register X:0:1:0 (Read)Indicates Pending Interrupts
FIFO Control Register X:0:1:0 (Write)Enables/Clears FIFOs and sets
trigger level/DMA type
Line Control Register X:0:1:1 Format of asynchronous communication,
MSB->DLAB
Modem Control Register X:1:0:0 Controls the interface with the modem
Line Status Register X:1:0:1 Holds the status information regarding
data transfer
Modem Status Register X:1:1:0 Provide the status of control lines from the
Modem
Scratchpad Register X:1:1:1 Holds temporary data
Divisor Latch LSB 1:0:0:0 Holds Least significant byte of divisor if the baud rate generator
Divisor Latch MSB 1:0:0:1 Holds most significant byte of divisor for
the baud rate generator
=====================================================================================
Baud Rate Generator
The PC6550D contains a programmable internal baud rate generator that takes the clock input up to 2400Hertz and dividing it by any divisor from 2 to 2^16-1 .The divisor can be found using a formula which is given below.The divisor is stored in 2 bytes totaling a 16bit value.
Formula: 16 * baud rate divisor [divisor=(frequency input) \ (baud rate x 16)]
Examples:
Baud rate=1000
Clock = 1600 MHz
Divisor = 10
1600/(1000 x16) = Divisor
1600/16000 = 10
=====================================================================
Expanded List of Line Control Register , FIFO Control Register and Line Status Register
Line Control Register:
D0 and D1=L0 and L1 - Data Length 0 0 = 5bits , 0 1 = 6bits ,1 0 = 7bits , 1 1 = 8bits
D2=S - Stop Bit 0 = 1 Stop Bit, 1 = 1.5\2 Stop Bits
D3=PE - Parity Enable Bit 0 = no parity, 1 = Parity Enabled
D4=P - Parity Type 0 = Odd, 2= Even
D5=ST - Stick Bit 0 = Off, 1 = On
D6=SB - Send Break 0 = No break, 1 = Send break
D7=DL - Divisor latch 0= Off, 1 = On
First in First Out Control Register:
D0=EN - FIFO Enable 0 = Disable, 1 = Enable
D1=RECV RST - Recevier Reset 0=No Effect, 1 = Reset
D2=XMIT RST - Transmitter Reset 0=No Effect, 1=Reset
D3=DMA - DMA Mode COntrol 0 = Function as 16450 UART 1 = FIFO Mode
D4=NULL - Nothing to do Always 0
D5=NULL - Nothing to do Always 0
D6=RT0 and D7 = RT1 - Receiver Trigger Level 0 0 = 1byte 0 1 = 4bytes 1 0 = 8 Bytes 1 1 = 14Bytes
Line Status Register
D0=DR - Data Ready 0 = No data ready, 1 = Data Ready
D1=OE - Over Run Error 0 = No Error, 1 = Overrun Error
D2=PE - Parity Error 0 = No parity error, 1 = Parity Error
D3=FE - Framing Error 0= No framing error, 1 = Framing Error
D4=BI - Break Indicator 0 = No break indicator, 1 = Break
D5=TH - Transmitter Holding Register 0 = Wait, 1 = Ready
D6=TE - Transmitter Empty 0 = not empty, 1 = Empty
D7=ER - Error 0 = No Error, 1 = Error
=====================================================================================
Programming the PC16550D
Initializing the Hardware:
The line control register(LCR), baud rate divisor latch and the First In First Out Control Register(FCR) must be initialized before transmitting or receiving data bytes.The control word in the Line Control Register defines the byte length, the number of stop bits, the parity byte and also enables the divisor latch.The control word for transmitting or receiving data bytes in asynchronous format of 7bit, odd-parity and on-stop bit is '00001010B'. The control word in the FIFO Control Register enables,clears, sets the trigger level and selects the type of Direct Memory Access signalling.
Example Code in Assembly:
LSB_DIVL EQU 80H
MSB_DIVL EQU 82H
FCR EQU 84H
LCR EQU 86H
LSR EQU 8AH
THR EQU 80H
RBR EQU 80H
mov AL, 10001010B ;Set D7 to access Divisor Latch
out LCR, AL ;Loads the control word
mov AL,20 ;Sets AL = 20
out LSB_DIVL, AL ;Set LS Divisor Byte
mov AL, 00
out MSB_DIVL, AL
mov AL, 00001010B
out LCR, AL
mov AL, 00000111B
out FCR, AL
int 3H
Transmitting the data:
The line status register is checked before sending a data byte.The Line Status Register provides information about the error conditions and the status of transmitter and recevier. The 8086 ALP determines if the transmitter is ready to accept data to be transmitted.Then the data is transmitted.
Receiving the data:
The Line Status Register is checked before taking the data byte from the receiver buffer.It indicates the status of the receiver buffer and the error condition.If a data byte has been received and Line Status Register is checked again for errors.The ALP determines whether the receiver has received a byte without any error.