การ Interface กับ Serial Port (Part IV)


UART จะมีวงจร Baud rate generator อยู่ภายใน ซึ่งจะเชื่อมโยงกับภาคส่งของ UART โดยตรง และควบคุมโดยใช้ Crystal แต่ทางด้านภาครับจะต้องต่อจากขา 15 ซึ่งเป็น Baud output มาเข้าที่ขา 9 ซึ่งเป็น Receiver clock input โดยความถี่ของ Clock มีค่าเป็น 16 เท่าของ Baud rate สูงสุด ดังนั้นเราจึงมักจะพบ Crystal ที่มีค่าความถี่ 1.8432 MHz หรือ 18.432 MHz อยู่บน I/O Card เสมอ

Type of UARTs

Type of UARTS (For PC’s)

UART

Note

8250

First UART in this series. It contains no scratch register. Terminal speed of 19.2Kbps.

8250A

This UART is faster than the 8250 on the bus side. Looks exactly the same to software than 16450.

8250B

Very similar to that of the 8250 UART.

16450

Used in AT's (Improved bus speed over 8250's). Operates comfortably at terminal speed of 38.4Kbps. Still quite common today.

16550

This was the first generation of buffered UART. It has a 16 byte buffer, however it doesn't work and is replaced with the 16550A.

16550A

Is the most common UART use for high speed communications eg. Terminal speed of 115.2Kbps. They made sure the FIFO buffers worked on this UART.

16650 (TL16C650)

Very recent breed of UART. Contains a 32 byte FIFO, Programmable Xon / Xoff characters and supports power management. Terminal speed of 230.4Kbps.

16750 (TL16C750)

Produced by Texas Instruments. Contains a 64 byte FIFO.

 

Serial Port Registers

Port Addresses and IRQ’s

Table 3. Standard Port Addresses.

Name

Address

IRQ

COM1

3F8

4

COM2

2F8

3

COM3

3E8

4

COM4

2E8

3

 

Table 3. แสดง Address และ IRQ ของ Serial Port หรือ COM Port ที่ใช้ในเครื่อง PC ส่วนใหญ่ แต่ถ้าไม่แน่ใจเราก็สามารถหาข้อมูลเหล่านี้ได้ โดยอ่านจาก BIOS ตาม Address ที่แสดงใน Table 4. ข้างล่างนี้

Table 4. COM Port Address in the BIOS Data Area.

Start Address

Function

0000 : 0400

COM1’s Base Address

0000 : 0402

COM2’s Base Address

0000 : 0404

COM3’s Base Address

0000 : 0406

COM4’s Base Address

 

ตัวอย่างต่อไปนี้เป็นตัวอย่าง Program ภาษา C แสดงการอ่านข้อมูล Address ของ COM Port จาก BIOS Data Area

#include <stdio.h>
#include <dos.h>
void main(void)
{
unsigned int far *ptraddr; 		/* Pointer to location of Port Addresses */
unsigned int address; 			/* Address of Port */
int a;
ptraddr=(unsigned int far *)0x00000400;
	for (a = 0; a < 4; a++)
	{
	address = *ptraddr;
	if (address == 0)
	printf("No port found for COM%d \n",a+1);
	else
	printf("Address assigned to COM%d is %Xh\n",a+1,address);
	*ptraddr++;
	}
}



Table of Registers

Table 5. แสดงถึง Address ของ Register ต่าง ๆ

Table 5. Table of Registers.

Base Address

DLAB

Read / Write

Abbr.

Register Name

+0

=0

Write

-

Transmitter Holding Buffer

=0

Read

-

Receiver Buffer

=1

Read / Write

-

Divisor Latch Low Byte

+1

=0

Read / Write

IER

Interrupt Enable Register

=1

Read / Write

-

Divisor Latch High Byte

+2

-

Read

IIR

Interrupt Identification Register

-

Write

FCR

FIFO Control Register

+3

-

Read / Write

LCR

Line Control Register

+4

-

Read / Write

MCR

Modem Control Register

+5

-

Read

LSR

Line Status Register

+6

-

Read

MSR

Modem Status Register

+7

-

Read / Write

-

Scratch Register

 

DLAB?

DLAB ใช้ควบคุม register บางตัวให้สามารถทำหน้าที่ต่างออกไปได้ จึงทำให้ register ที่มีอยู่จริงเพียง 8 ตัว สมารถทำงานเสมือนว่ามี register อยู่ 12 ตัว DLAB ย่อมาจาก Divisor Latch Access Bit

เมื่อ DLAB ถูก set ให้มีค่าเป็น 1 โดย set ที่ Line Control Register จะทำให้เราสามารถเข้าถึง register 2 ตัวที่ทำหน้าที่กำหนด speed ของการสื่อสาร ซึ่งมีหน่วยเป็น bit per second (bps)

ตัว UART จะมี oscillator ความถี่เป็น 16 เท่าของ speed สูงสุดในการสื่อสาร ถ้าเราต้องการ speed สูงสุดที่ 115,200 bps ก็ต้องใช้ความถี่ oscillator ที่ 1.8432 MHz และจาก speed สูงสุดที่ 115,200 bps เมื่อหารต่อไปด้วยค่าตัวหาร 48 ก็จะทำให้ได้ speed ที่ 2400 bps ซึ่งตัว Baud Rate Generator จะเป็นตัวทำหน้าที่นี้ โดยมี register 2 ตัวทำหน้าที่เก็บค่าตัวหาร (divisor) นี้ ซึ่ง register ทั้ง 2 จะถูกควบคุมโดย DLAB ค่าของตัวหารสามารถเป็นเท่าใดก็ได้ที่ไม่เกิน 16 bit (0 ถึง 65,535) และเนื่องจาก UART มี data bus เพียง 8 bit จึงต้องใช้ register 2 ตัว โดยเมื่อ set ค่า DLAB ให้มีค่าเป็น 1 ตัว register ตัวแรกซึ่งมี address อยู่ที่ base+0 จะเก็บค่า Divisor Latch Low Byte ส่วน register ตัวที่สองซึ่งมี address อยู่ที่ base+1 จะเก็บค่า Divisor Latch High Byte Table 6. แสดงถึงค่าตัวหารเป็นเลขฐาน 16 ที่ใช้กันทั่วไป.

Table 6. Commonly Used Baud rate Divisors.

Speed (bps)

Divisor (Dec.)

Divisor Latch High Byte

Divisor Latch Low Byte

50

2304

09h

00h

300

384

01h

80h

600

192

00h

C0h

2400

48

00h

30h

4800

24

00h

18h

9600

12

00h

0Ch

19200

6

00h

06h

38400

3

00h

03h

57600

2

00h

02h

115200

1

00h

01h

 

Interrupt Enable Register (IER)

Table 7. แสดงหน้าที่ของ bit ต่าง ๆ ใน Interrupt Enable Register

Table 7. Interrupt Enable Register.

Bit

Note

7

Reserved

6

Reserved

5

Enable Low Power Mode (16750)

4

Enable Sleep Mode (16750)

3

Enable Modem Status Interrupt

2

Enable Receiver Line Status Interrupt

1

Enable Transmitter Holding Register Empty Interrupt

0

Enable Receiver Data Available Interrupt

 

ถ้า bit0 ถูกกำหนดให้เป็น “1” หรือ “high” จะเป็นการ enable ตัว receiver data available interrupt ซึ่งจะทำให้เกิด interrupt ขึ้นเมื่อมีข้อมูลใน FIFO buffer ของภาครับเพื่อรอให้ CPU อ่าน ส่วน bit1 ถ้าถูกกำหนดเป็น “1” หรือ “high” จะเป็นการ enable ตัว transmitter holding register empty interrupt ซึ่งจะ interrupt ไปให้ CPU เมื่อ buffer ของภาคส่งว่าง (empty) สำหรับ bit2 ทำหน้าที่ enable การ interrupt ของ receiver line status ซึ่งจะทำให้ UART ส่ง interrupt ไปยัง CPU เมื่อมีการเปลี่ยนแปลงสภาวะที่ receiver line เกิดขึ้น และ bit3 เป็นตัว enable การ interrupt ของ modem status bit4 ถึง bit7 สำรองไว้ไม่ได้ใช้ใน UART เบอร์ 8250, 16550A และ 16650

รายการหน้าเว็บย่อย

Comments