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


Interrupt Vectors

ก่อนที่จะใช้งาน Interrupt ก็ต้องรู้ว่า communication card ที่ใช้มี address และ IRQ อย่างไร ย้อนกลับไปดู Table 3. ที่แสดงข้อมูลของ base address และ IRQ ที่ใช้กันอยู่ โดย IRQ 3 และ 4 ใช้กันเป็นประจำ ส่วน IRQ 5 และ 7 มีใช้ในบางโอกาส

เมื่อรู้ IRQ แล้วต่อไปก็หา interrupt vector หรือ software interrupt ของมัน ปรกติ processor ในอนุกรมของ 8086 จะมี 256 interrupt vector โดยนับจาก 0 ถึง 255 แต่ละ vector มีขนาด 4 bytes เก็บ address ของ Interrupt Service Routine (ISR) ไว้ แต่เนื่องจากภาษา C สามารถจัดการกับ address เหล่านี้โดยเพียงแต่รู้ค่า vector ของมันเท่านั้นดังนั้นจึงใช้เฉพาะ interrupt vector ในการเขียน program ภาษา C


Table 14. แสดง Interrupt Vector ของ Hardware

Table 14. Interrupt Vectors. (Hardware only)

Int. (Hex)

IRQ

Common uses

08

0

System Timer

09

1

Keyboard

0A

2

Redirected

0B

3

Serial Comms. COM2/COM4

0C

4

Serial Comms. COM1/COM3

0D

5

Reserved/Sound Card

0E

6

Floppy Disk Controller

0F

7

Parallel Comms.

70

8

Real Time Clock

71

9

Reserved

72

10

Reserved

73

11

Reserved

74

12

PS/2 Mouse

75

13

Math Co-Processor

76

14

Hard Disk Drive

77

15

Reserved

 

สมมุติว่าเราใช้ COM 3 ซึ่งมี IRQ อยู่ที่ 0C (Hex) เราก็สามารถ set ค่า interrupt vector โดยใช้คำสั่งภาษา C ว่า setvec (Ox0C, PORT1INT); โดย PORT1INT คือ ISR หรือ interrupt handler ที่รองรับ IRQ นี้ แต่ก่อนที่จะทำเช่นนั้นควรเก็บค่าvector เดิมไว้เพื่อ restore กลับหลังจากที่จบการทำงานของ ISR แล้ว ซึ่งจะใช้คำสั่ง oldport1isr = getvect (INTVECT); โดย oldport1isr ถูกกำหนดโดยคำสั่ง void interrupt (*oldport1isr)(); นอกจากนั้นยังต้องมีการเก็บค่า status เดิมของ UART และส่งคืนทุกครั้งที่สิ้นสุด ISR เพื่อให้ program อื่นสามารถใช้ UART ได้

Interrupt Service Routine

PORT1INT ที่ชี้ไปยัง ISR ซึ่งจะทำงานตามที่ได้ออกแบบไว้ ตัวอย่างเช่น

void interrupt PORT1INT()
{
int c;
do { c = inportb(PORT1 + 5);
if (c & 1) {
buffer[bufferin] = inportb(PORT1);
bufferin++;
if (bufferin == 1024) bufferin = 0;
}
} while (c & 1);
outportb(0x20,0x20);
}

ซึ่งจะตรวจว่ามีการรับ character เข้ามาใน UART หรือไม่ ถ้ามีก็จะอ่านไปเก็บไว้ที่ buffer ใน memory ซึ่งจะตรวจต่อเนื่องในกรณีที่ enable ตัว FIFO เพื่อเก็บข้อมูลทั้งหมดเมื่อมี interrupt เกิดขึ้น

บรรทัดสุดท้าย outportb(0x20,0x20); จะบอกตัว Programmable Interrupt Controller (PIC) ว่าสิ้นสุดการ interrupt แล้ว routine ข้างบนจะทำงานได้ก็ต่อเมื่อ setup ตัว register ต่าง ๆ ของ UART และตัว PIC ถูกต้องแล้วเท่านั้น ปรกติ PC จะใช้ PIC 2 ตัวเป็น PIC1 และ PIC2 และมี control word ตามที่แสดงใน Table 15. และ 16. สำหรับรายละเอียดเกี่ยวกับการใช้ Interrupt และตัว PIC ขอให้ดูจากบทความเรื่อง “การใช้ Interrupt”

Table 15. PIC1 Operation Control Word 1 (Address Ox21)

Bit

Disable IRQ

Function

7

IRQ7

Parallel Port

6

IRQ6

Floppy Disk Controller

5

IRQ5

Reserved/Sound Card

4

IRQ4

Serial Port

3

IRQ3

Serial Port

2

IRQ2

PIC2

1

IRQ1

Keyboard

0

IRQ0

System Timer

 

 

Table 16. PIC2 Operation Control Word 1 (Address OxA1)

Bit

Disable IRQ

Function

7

IRQ15

Reserved

6

IRQ14

Hard Disk Drive

5

IRQ13

Math Co-Processor

4

IRQ12

PS/2 Mouse

3

IRQ11

Reserved

2

IRQ10

Reserved

1

IRQ9

Redirected IRQ2

0

IRQ8

Real Time Clock

 

UART Configuration

การ config. ตัว UART มีขั้นตอนหลัก ๆ ดังนี้

  1. Disable การ interrupt ของตัว UART เป็นอันดับแรก เพื่อไม่ให้มี interrupt จาก UART มารบกวนขณะทำการ config. อยู่
  2. ทำการ setup ค่า interrupt vector ต่าง ๆ
  3. กำหนด speed และค่าต่าง ๆ ในการสื่อสารที่ต้องการ โดย set bit 7 ของ LCR ก่อนแล้วค่อยกำหนดค่าอื่น ๆ
  4. หลังจากกำหนด speed แล้ว ก็ต้อง reset bit 7 ของ LCR เพื่อจะได้ควบคุม interrupt enable register และ Tx/Rx buffer ได้และกำหนดค่าต่าง ๆ ที่เกี่ยวกับ FCR และ MCR

Main Routine (Loop)

ตัวอย่างของ main routine มีดังนี้

do {
if (bufferin != bufferout){
ch = buffer[bufferout];
bufferout++;
if (bufferout == 1024) bufferout = 0;
printf("%c",ch);
}
if (kbhit()){
c = getch();
outportb(PORT1, c);
}
} while (c !=27);
ซึ่งจะ loop จนกว่าค่า c = 27 (คือการกดปุ่ม ESC key) สำหรับ routine นี้ตั้งอยู่บนสมมุติฐานว่า UART ทำงานเร็วกว่าการพิมพ์ข้อมูลเข้าไป แต่ถ้าใช้ในลักษณะอื่นที่ UART อาจจะทำงานไม่ทัน ก็ต้องเพิ่มขั้นตอนให้มีการตรวจสอบ bit 5 ของ Line Status Register (LSR) ว่ามีค่าเป็น “1” ก่อนที่จะส่งข้อมูลใหม่เข้าไปยัง Tx register

Determining the type of UART via Software

การตรวจสอบชนิดของ UART โดยใช้ software มีขั้นตอนดังนี้

Set ให้ bit 0 ของ FCR มีค่าเป็น “1” แล้วอ่านค่าของ bit 6 และ 7 ของ interrupt identification register (IIR) ถ้า bit ทั้ง 2 มีค่าเป็น “1” แสดงว่า FIFO buffer ถูก enable หมายความว่า UART เป็นเบอร์ 16550A ถ้า FIFO ถูก enable แต่ใช้ไม่ได้แสดงว่า UART เป็นเบอร์ 16550 และถ้า FIFO ไม่ได้ถูก enable แสดงว่า UART เป็นเบอร์ 16450 หรือ 8250, 8250A หรือ 8250B ในเครื่อง PC รุ่นเก่า (ส่วนเครื่อง PC/AT จะมี bus speed ที่สูงขึ้น ซึ่ง UART อนุกรม 8250 ไม่สามารถตอบสนองได้) จากนั้นก็ลองเขียนข้อมูลเข้า scratch register แล้วอ่านกลับออกมาเทียบกับที่เขียนเข้าไปดูว่าถ้าตรงกันแสดงว่ามี scratch register อยู่แสดงว่า UART เป็นเบอร์ 16450 หรือ 8250A แต่ถ้าไม่มี scratch register แสดงว่า UART เป็นเบอร์ 8250 หรือ 8250B สำหรับ UART เบอร์ 16750 จะมี buffer 64 byte ซึ่งทดสอบโดยการ enable ผ่าน FCR แล้วอ่านค่า status จาก IIR ก็จะรู้ได้

External Hardware – Interfacing Methods

RS-232 Waveforms

การสื่อสารโดย RS-232 เป็นการสื่อสารแบบ asynchronous หมายความว่าสัญญาณ clock ที่ใช้ควบคุมจังหวะไม่ได้ส่งไปพร้อมกับ Data แต่จะใช้ start bit เป็นตัว sync.ในแต่ละ word ของการสื่อสารและใช้สัญญาณ clock ภายในของแต่ละด้านเป็นตัวให้จังหวะเอง

Figure 4. TTL/CMOS Serial Logic Waveform.

Figure 4. แสดงลักษณะของสัญญาณจาก UART เมื่อใช้ format แบบ 8N1 คือ 8 data bits ไม่มี parity bit และมี 1 stop bit ขณะที่ idle จะอยู่ในสถานะ “Mark” หรือ logic “1” การส่งจะเริ่มจากการส่ง start bit คือ logic “0” และตามด้วย LSB bit จนหมด data bits และถ้ามี parity bit ก็จะส่งที่จุดนี้แล้วลงท้ายด้วย stop bit ซึ่งมีค่าเป็น logic “1” ในรูปได้แสดง bit ที่ต่อถัดจาก stop bit ซึงมีค่าเป็น logic “0” หมายความว่าเป็น start bit ของ การส่ง word ถัดไป แต่ถ้ายังไม่มีการส่ง word ถัดไป ก็ต้องอยู่ในสถานะของ logic “1” ซึ่งเป็นสถานะของ idle และถ้าสายอยู่ในสถานะของ logic “0” นานกว่าเวลาของการส่ง 1 full word ระบบจะถือว่าเป็นสัญญาณ “Break” เพื่อหยุดการสื่อสาร ดังนั้นต้องไม่ลืมที่จะสั่งในสายกลับสู่สถานะ idle เมื่อสิ้นสุดการส่ง

การรับ-ส่งข้อมูลในลักษณะนี้เรียกว่าแบบ frame คือมีกรอบปิดล้อมข้อมูลไว้ด้วย start bit และ stop bit

RS-232 Level Converters

สัญญาณ RS-232 มีค่าแรงไฟต่างจากที่ใช้ใน UART ดังแสดงใน Figure 5. ดังนั้นจึงต้องมี converter เพื่อแปลงระดับสัญญาณให้เหมาะสมก่อนที่จะเชื่อมต่อกับ serial port หรือ RS-232 port ของ computer

Figure 5. RS-232 Logic Waveform.

สำหรับสัญญาณ RS-232 นั้น logic “0” จะมีค่า +3 V ถึง +25 V และ logic “1” จะมีค่า –3 V ถึง –25 V ส่วนค่าระหว่าง –3 V ถึง +3 V เป็นค่า undefined ระดับสัญญาณนี้ใช้กับทุกสัญญาณไม่ใช่เฉพาะสัญญาณรับ-ส่งข้อมูลเท่านั้นแต่ยังรวมถึงสัญญาณควบคุมต่าง ๆ เช่น DTR, RTS, CTS, DCD, DSR เป็นต้น

IC ที่ใช้มักจะเป็นเบอร์ 1488 (RS-232 Driver) และ 1489 (RS-232 Receiver) โดยภายในแต่ละตัวจะประกอบด้วย inverter 4 ตัวและต้องการไฟเลี้ยง 2 ชุดคือ +7.5 V ถึง +15 V และ –7.5 V ถึง –15 V ซึ่งอาจจะมีปัญหาในเครื่องที่มีไฟเลี้ยง +5 V เพียงชุดเดียว แต่ก็ยังมี IC อีกตัวหนึ่งคือเบอร์ MAX-232 ซึ่งมีวงจร charge pump สามารถสร้างไฟ +10 V และ –10 V จากไฟ +5 V ได้ พร้อมทั้งมี 2 Tx และ 2 Rx อยู่ใน package เดียวกัน และรองรับ baud rate ได้ถึง 120 Kbps จึงสะดวกมากเพราะใช้ IC เพียงตัวเดียว รูปข้างล่างคือ MAX-232


ส่วนการที่เราจะนำข้อมูลมาใช้งานก็ต้องแปลงเป็น parallel ก่อนซึ่งเป็นหน้าที่ของ UART ซึ่งปัจจุบัน microprocessor และ microcontroller มักจะมี serial communication interface (SCI) อยู่ในตัว แต่อาจจะมีงานบางอย่างที่ไม่ได้ใช้ microcontroller และต้องการ process ข้อมูลกับ serial comm. เช่น ต่อ ADC เข้ากับ UART หรือต่อ LCD display เข้ากับ Serial comm. ก็ต้องใช้ UART ช่วย เช่นเบอร์ 8250 หรือ 16550A หรือเบอร์อื่น ๆ ที่ได้กล่าวมาแล้ว แต่มี UART อีกพวกหนึ่งที่แยก Tx bus กับ Rx bus ออกจากกัน ทำให้มีความคล่องตัวมากขึ้น ซึ่งจะกล่าวในหัวข้อต่อไป

CDP6402, AY-5-1015 / D36402R-9 etc UARTS

Table 17. แสดงรายละเอียดหน้าที่ของขาต่าง ๆ ของ UART ในกลุ่ม CDP6402, AY-5-1015 / D36402R-9 ซึ่งเป็น CMOS สามารถรองรับ baud rate สูงถึง 200 Kbps ที่ 5 V แต่เนื่องจาก UART เหล่านี้ไม่มี programmable baud rate generator อยู่ใน chip ด้วย จึงต้องใช้วงจรภายนอก โดยมากจะใช้ IC เบอร์ 74HC4046 ซึ่งเป็น 14 bit binary counter/divider แต่จะมีขา output เพียงบางส่วนคือ Q4 ถึง Q14 จึงต้องการ clock ที่มีความถี่สูงกว่า max. baud rate 16 เท่า Table 18. แสดง baud rate ที่เป็นไปได้เมื่อใช้ Crystal ควบคุมความถี่ต่างกัน

Table 17. Pin description for CDP6402, AY-5-1015 / D36402R-9 and compatible UARTs.

Pin Number

Abbr.

Full Name

Notes

1

VDD

+5 V. Supply Rail.

Connected to +5 V Supply.

2

NC

Not Connected.

Not Connected.

3

GND

Ground.

Ground.

4

RRD

Receiver Register Disable.

When driven high, Outputs RBR8:RBR1 are high impedance.

5 : 12

RBR8 : RBR1

Receiver Buffer Register.

Receiver’s Data Bus.

13

PE

Parity Error.

When high, a parity error has occurred.

14

FE

Framing Error.

When high, a framing error has occurred. I.e. The stop bit was not a logic 1.

15

OE

Overrun Error.

When high, data has been received but the nData Received Reset has not yet been activated.

16

SFD

Status Flag Disable.

When high, status flag outputs (PE, FE, OE, DR and TBRE) are high impedance.

17

RRC

Receiver Register Clock.

X 16 clock input for the receiver register.

18

nDRR

Data Received Reset.

Active low. When low, sets data received outputs low.(i.e. Clears DR)

19

DR

Data Received.

When high, data has been received and placed on outputs RBR8:RBR1.

20

RRI

Receiver Register In.

RXD-Serial input. Connected to serial port, via RS-232 receiver.

21

MR

Master Reset.

UART should be reset after applying power.

22

TBRE

Transmitter Buffer Register Empty.

When high, indicates that transmitter buffer register is empty, thus all bits including stop bit have been sent.

23

nTBRL

Transmitter Buffer Load/Strobe.

Active low. When low, data present on TBR8:TBR1 is placed in transmitter buffer register. A low to high transition on this pin, then sends the data.

24

TRE

Transmitter Register Empty.

When high, transmitter register is empty, thus can accept another byte of data to be sent.

25

TRO

Transmitter Register Out. (TXD)

TXD-Serial output. Connected to serial port, via RS-232 transmitter.

26 : 33

TBR8 :TBR1

Transmitter Buffer Register.

Data bus for transmitter. Place data here which you want to send.

34

CRL

Control Register Load

When high, control register (PI, SBS, CLS2, CLS1, EPE) is loaded. Can be tied high, so changes on these pins occur instantaneously.

35

PI

Parity Inhibit.

When high, no parity is used for both transmit and receive. When low, parity is used.

36

SBS

Stop Bit Select..

A high select 2 stop bits.(1.5 for 5 character word lengths). A low select 1 stop bit.

37 : 38

CLS2 :CLS1

Character Length Select.

Select word length. 00=5 bits, 01=6 bits, 10=7 bits and 11=8 bits.

39

EPE

Even Parity Enable.

When high, even parity is used. When low, odd parity is used.

40

TRC

Transmitter Register Clock.

X 16 clock input for the transmitter.

 

 

Table 18. Possible baud rates using a 74HC4046.

Output

1.8432 MHz

2.4546 MHz

Out2

115.2 Kbps

153.6 Kbps

Q4

7200 bps

9600 bps

Q5

3600 bps

4800 bps

Q6

1800 bps

2400 bps

Q7

900 bps

1200 bps

Q8

450 bps

600 bps

Q9

225 bps

300 bps

 

การใช้ BIOS Interrupt 14h และ DOS API Interrupt 21h

BIOS Interrupt 14h มี 4 functions ให้ใช้ในการ program เกี่ยวกับ serial port ดังรายละเอียดต่อไปนี้

Function 00h: Initializes the serial port and sets the speed, data and stop bits and the parity parameters. Input: AH=00h DX=Number of serial port (0=first serial port, 1=second serial port) AL=Configuration parameters Bits 0-1: Word length 10=7 bits 11=8 bits Bit 2: Number of stop bits 00=1 stop bit 01=2 stop bits Bits 3-4: Parity 00=none 01=odd 11=even Bits 5-7: Baud rate 000=110 baud 001=150 baud 010=300 baud 011=600 baud 100=1200 baud 101=2400 baud 110=4800 baud 111=9600 baud Output: AH=Serial port status Bit 0: Data ready Bit 1: Overrun error Bit 2: Parity error Bit 3: Framing error Bit 4: Break discovered Bit 5: Transmission hold register empty Bit 6: Transmission shift register empty Bit 7: Time out AL=Modem status Bit 0: Modem ready to send status change Bit 1: Modem on status change Bit 2: Telephone ringing status change Bit 3: Connection to receiver status change Bit 4: Modem ready to send Bit 5: Modem on Bit 6: Telephone ringing Bit 7: Connection to receiver modem หมายเหตุ: ข้อมูลใน BX, CX, DX, SI, DI, BP registers และ segment registers ไม่ได้ถูกกระทบจากการเรียก ใช้ function นี้ ส่วนข้อมูล ใน registers อื่นอาจมีการเปลี่ยนแปลง Function 01h: Sends a character to the specified serial port. Input: AH=01h DX=Number of serial port (0=first serial port, 1=second serial port) AL=Character code to be send Output: AH: Bit 7=0: Character transmitted Bit 7=1: Error Bit 0-6: Serial port status Bit 0: Data ready Bit 1: Overrun error Bit 2: Parity error Bit 3: Framing error Bit 4: Break discovered Bit 5: Transmission hold register empty Bit 6: Transmission shift register empty หมายเหตุ: ข้อมูลใน BX, CX, DX, SI, DI, BP registers และ segment registers ไม่ได้ถูกกระทบจากการเรียก ใช้ function นี้ ส่วนข้อมูล ใน registers อื่นอาจมีการเปลี่ยนแปลง Function 02h: Reads a character from the specified serial port. Input: AH=02h DX=Number of serial port (0=first serial port, 1=second serial port) Output: AH: Bit 7=0: Character received Bit 7=1: Error Bit 0-6: Serial port status Bit 0: Data ready Bit 1: Overrun error Bit 2: Parity error Bit 3: Framing error Bit 4: Break discovered Bit 5: Transmission hold register empty Bit 6: Transmission shift register empty หมายเหตุ: ควรจะเรียกใช้ function นี้ก็ต่อเมื่อ function 3 พบว่ามี character พร้อมให้รับแล้วเท่านั้น ข้อมูลใน BX, CX, DX, SI, DI, BP registers และ segment registers ไม่ได้ถูกกระทบจากการเรียกใช้ function นี้ ส่วนข้อมูล ใน registers อื่นอาจมีการเปลี่ยนแปลง Function 03h: Returns the state of the specified serial port. Input: AH=03h DX=Number of serial port (0=first serial port, 1=second serial port) Output: AH=Serial port status Bit 0: Data ready Bit 1: Overrun error Bit 2: Parity error Bit 3: Framing error Bit 4: Break discovered Bit 5: Transmission hold register empty Bit 6: Transmission shift register empty AL=Modem status Bit 0: Modem ready to send status change Bit 1: Modem on status change Bit 2: Telephone ringing status change Bit 3: Connection to receiver status change Bit 4: Modem ready to send Bit 5: Modem on Bit 6: Telephone ringing Bit 7: Connection to receiver modem หมายเหตุ: function นี้ควรถูกเรียกใช้ก่อนที่จะเรียกใช้ function 2 เสมอ ข้อมูลใน BX, CX, DX, SI, DI, BP registers และ segment registers ไม่ได้ถูกกระทบจากการเรียกใช้ function นี้ ส่วนข้อมูล ใน registers อื่นอาจมีการเปลี่ยนแปลง ส่วน DOS API Interrupt 21h มี 3 functions ที่เกี่ยวข้องกับ serial port ดังรายละเอียดต่อไปนี้ Function 03h: Reads a character from the COM1 serial port, unless a MODE command previously redirected serial access Input: AH=03h Output: AL=Character received หมายเหตุ: เนื่องจาก serial port ไม่มี buffer อยู่ภายใน ทำให้มันรับ character ได้เร็วกว่าที่จะอ่านได้ หรืออ่าน ไม่ทันกับการรับเข้ามาและ character ที่อ่านไม่ทันก็จะถูกเลยผ่านไป ซึ่งต้องระวังในจุดนี้ ก่อนที่จะเรียกใช้ function นี้ ต้องใช้ MODE command กำหนด communication parameters ต่าง ๆ เช่น baud rate, จำนวน stop bits และอื่น ๆ ให้เรียบ ร้อยก่อน มิฉะนั้นก็จะใช้ค่า DOS defaults คือ 2400 baud หนึ่ง stop bit ไม่มี parity และ 8 data bits. และถ้า function นี้ได้รับค่า <Ctrl><C> (ASCII code 3) จะทำให้ไปเรียกใช้ Interrupt 23h ซึ่งเป็น <Ctrl><C> handler address ได้ การใช้ BIOS functions จาก interrupt 14h จะมีความคล่องตัวและมีประสิทธิภาพกว่า ข้อมูลใน AH, BX, CX, DX, SI, DI, BP, CS, DS, SS, ES registers และ flag registers ไม่ถูกกระทบจากการเรียกใช้ function นี้. Function 04h: Writes a character to the COM1 serial port, unless a MODE command previously redirected serial access. Input: AH=04h DL=Character set for output Output: No output หมายเหตุ: ทันทีที่ receiving device ส่งสัญญาณไปให้ function เพื่อบอกว่าพร้อมที่จะรับ function ก็จะส่ง character ให้ แล้วกลับสู่ program ที่จากมา ก่อนที่จะเรียกใช้ function นี้ ต้องใช้ MODE command กำหนด communication parameters ต่าง ๆ เช่น baud rate, จำนวน stop bits และอื่น ๆ ให้เรียบร้อยก่อน มิฉะนั้นก็จะใช้ค่า DOS defaults คือ 2400 baud หนึ่ง stop bit ไม่มี parity และมี 8 data bits. และถ้า function นี้ได้รับค่า Ctrl><C> (ASCII code 3) จะทำให้ไปเรียกใช้ Interrupt 23h ซึ่งเป็น <Ctrl><C> handler address ได้ การใช้ BIOS functions จาก interrupt 14h จะมีความคล่องตัว และมีประสิทธิภาพกว่า ข้อมูลใน registers ใน processor และ flag registers ไม่ถูกกระทบจากการเรียกใช้ function นี้ Function 40h: It is a common out function for all files and devices that use a handle access. This function sends a number of bytes from a buffer to the specified device. Input: AH=40h BX=File or device handler CX=Number of bytes to be read DS=Buffer segment address DX=Buffer offset address Output: Carry flag=0: O.K. (AX=Number of bytes read) Carry flag=1: Error (AX=Error code) AX=5: Access denied AX=6: Illegal handle or file not open หมายเหตุ: Characters สามารถเขียนไปยัง file หรือ device เช่น screen ซึ่งมีค่า handle=1 เป็นต้น ถ้าหลังจาก เรียก function นี้แล้ว carry flag ถูก reset แต่ AX register มีค่าเป็น 0 หมายความว่า file pointer ชี้ถึงจุดสิ้นสุด ของ file ก่อนที่ function จะถูกเรียกใช้ จึงไม่สามารถเขียนเข้าไปใน file ได้ ถ้าหลังจากเรียก function นี้แล้ว carry flag ถูก reset แต่ ข้อมูลใน AX register มีค่าน้อยกว่าใน CX register (ก่อนที่จะเรียก function) แสดงว่า ไม่สามารถ เขียนจำนวน bytes ที่ต้องการเข้าไปยัง file ได้ เพราะถึงจุดสิ้นสุดของ file ก่อน ดังนั้นหลังจากเรียก function file pointer จึงชี้fไปยัง byte ที่ถัดจาก byte สุดท้ายที่เขียนเข้าไปได้ ข้อมูลใน AH, BX, CX, DX, SI, DI, BP, CS, DS, SS และ ES registers ไม่ถูกกระทบจากการเรียกใช้ function นี้

ตัวอย่างต่อไปนี้เป็น program ภาษา C++ ที่ใช้ serial comm. ติดต่อกันระหว่าง computer 2 เครื่อง
//Program to communicate two PCs via serial port
  //00h BIOS function (AL register)
//bits 7, 6, 5 Baud rate (bps.)
  // 000 110
  // 001 150
  // 010 300
  // 011 600
  // 100 1200
  // 101 2400
  // 110 4800
  // 111 9600
//bits 4, 3 Parity bits
  // 00 no parity
  // 01 odd parity
  // 11 even

//bits 2 stop bits // 0 1 stop bit // 1 2 stop bit //bits 1, 0 Number of bits per data // 10 7 data bits // 11 8 data bits //Register Dx 0->com1, 1->com2, 2->com3, 3->com4

//Configuration: 9600 bps., no parity, 2 stop bits and 8 data bits //AL register value is 11100111 -> 0xE7

#include <stdio.h> #include <process.h> #include <conio.h> #include <dos.h> #include <bios.h>

#define TRUE 1 #define PARAM 0xA7 #define COM1 0 #define COM2 1

void init_port(void); char state_port(void); void send_byte(unsigned char); unsigned char read_byte(void); void keyb(void); int tecla = 1; void main ( void ) { unsigned char read_com; unsigned char read_kb; clrscr(); init_port();

while(read_kb != 'c') { read_kb=getch(); send_byte(read_kb); read_com=read_byte(); if(read_com!=0){printf("%c",read_com);} } }

void init_port() { union REGS regs; regs.h.ah = 0x00; regs.x.dx = COM2; regs.h.al = PARAM; int86( 0x14, &regs, &regs); }

//return the state of the port

char state_port() { union REGS regs; regs.h.ah = 0x03; regs.x.dx = COM2; int86( 0x14, &regs, &regs); if(regs.h.ah & 0x80) printf("\t EXCEED TIME\n"); if(regs.h.ah & 0x40) printf("\t TSR EMPTY\n"); if(regs.h.ah & 0x20) printf("\t THR EMPTY\n"); if(regs.h.ah & 0x10) printf("\t INTERRUPTION\n"); if(regs.h.ah & 0x08) printf("\t THREAT ERROR\n"); if(regs.h.ah & 0x04) printf("\t PARITY ERROR\n"); if(regs.h.ah & 0x02) printf("\t OVERLOAD ERROR\n"); return (regs.h.ah); }

//Keyboard handle

void keyb() { union u_type{int a;char b[3];}keystroke;char inkey=0;

if(bioskey(1)==0) return; keystroke.a=bioskey(0); inkey=keystroke.b[1]; switch (inkey) { case 1: keyb=0; return; /*ESC*/ default: keyb=15; return; } } //Send a character to the serial port

void send_byte(unsigned char byte) { union REGS regs; regs.h.ah = 0x01; regs.x.dx = COM2; regs.h.al = byte; int86( 0x14, &regs, &regs); if( regs.h.ah & 0x80) { printf("\t SENDING ERROR "); exit(1); } }

//read a character from serial port

unsigned char read_byte() { int x,a; union REGS regs; if((estate_port() & 0x01)) { regs.h.ah = 0x02; regs.x.dx = COM2; int86(0x14,&regs,&regs); if(regs.h.ah & 0x80) { printf("\t RECEIVING ERROR"); exit(1); } return(regs.h.al);} else { return(0); } }

RS-232, RS-423, RS-422 and RS-485

Table ข้างล่างนี้เป็นการสรุปคุณสมบัติของมาตรฐานต่าง ๆ ที่นิยมใช้กันทั่วไป

Specification

RS-232

RS-423

RS-422

RS-485

Mode of operation

Single-ended

Single-ended

Differential

Differential

Total number of drivers and receivers on one line

1Tx

1Rx

1Tx

10Rx

1Tx

10Rx

1Tx

32Rx

Maximum cable length

50Ft

4,000Ft

4,000Ft

4,000Ft

Maximum data rate

20Kbps

100Kbps

10Mbps

10Mbps

Maximum driver output voltage

+/-25V

+/-6V

-0.25V to +6V

-7V to +12V

Driver output signal level (loaded min.)

Loaded

+/-5V to +/-15V

+/-3.6V

+/-2V

+/-1.5V

Driver output signal level (loaded max.)

Unloaded

+/-25V

+/-6V

+/-6V

+/-6V

Driver load impedance (ohms)

3K to 7K

>=450

100

54

Max. Driver current in high Z state

Power on

N/A

N/A

N/A

+/-100uA

Max. Driver current in high Z state

Power off

+/-6mA @ +/-2V

+/-100uA

+/-100uA

+/-100uA

Slew rate (max.)

30V/uS

Adjustable

N/A

N/A

Receiver input voltage range

+/-15V

+/-12V

-10V to +10V

-7V to +12V

Receiver input sensitivity

+/-3V

+/-200mV

+/-200mV

+/-200mV

Receiver input resistance (ohms)

3K to 7K

4K min.

4K min.

>=12K

การสื่อสารระหว่างอุปกรณ์ตั้งแต่ 2 อุปกรณ์ขึ้นไปจะประกอบด้วยตัว Driver หรือตัวส่ง Receiver หรือตัวรับ และสื่อกลาง หรือ Transmission line (ในกรณีที่เป็นการสื่อสารแบบใช้สาย) ทาง EIA จึงได้กำหนดมาตรฐานต่าง ๆ ขึ้น ซึ่งมีคุณสมบัติสรุปตามที่แสดงใน Table ข้างบน โดย RS-232 และ RS-423 เป็นแบบ single-ended ส่วน RS-422 และ RS-485 เป็นแบบ differential ซึ่งลดปัญหาที่แบบ single-ended ต้องประสบเช่นเรื่อง ground shift, ground noise เรื่อง induced noise ใน common mode เป็นต้น

วงจรสัญญาณของ RS-232

 

ระดับสัญญาณของ RS-232

 

สัญญาณระบบ Balanced Differential Data Transmission

RS-232 มี speed สูงสุดได้ไม่เกิน 20Kbps และไปได้ไกลสุดไม่เกิน 50 ฟุตที่ speed สูงสุด แต่ถ้าใช้สายพิเศษที่เป็นชนิด low capacitance ก็สามารถไปได้ไกลขึ้น สื่อสารแบบ full-duplex ได้ สัญญาณ idle เป็น “mark” มีค่าแรงไฟเป็นลบ และสัญญาณ active เป็น “space” มีค่าแรงไฟเป็นบวก ใช้สัญญาณ handshaking หลายสัญญาณ เหมาะที่จะเชื่อมต่อกับ modem ดังนั้นถ้าใช้งานด้านอื่นจึงมักประสบปัญหาในการจัดการกับสัญญาณ handshaking ซึ่งโดยมากมักจะใช้วิธีแก้ที่ software protocol หรือไม่ก็ loopback หรือ pull-up ด้วย Hardware ส่วน RS-423 เป็นมาตรฐานที่ปรับปรุงให้การทำงานแบบ single-ended ดีกว่า RS-232 แต่ก็ไม่ค่อยได้รับความนิยมนัก

เปรียบเทียบวงจรระหว่าง RS-422 กับ RS-485

การต่อ Grounding ของ RS-485

RS-422 เป็นแบบ differential สามารถใช้ speed ได้สูงกว่าและไปได้ไกลกว่า RS-232 มาก ดังนั้นถ้าใช้ converter 1 คู่ต่อหัว-ท้าย เพื่อแปลงสัญญาณ RS-232 และ RS-422 จะทำให้สามารถสื่อสารได้ด้วย speed สูงสุดถึง 100Kbps และไปได้ไกลถึง 4,000 ฟุต และยังสามารถทำงานแบบ multi-drop (party-line) คือ 1 driver ต่อกับ 10 receivers ในสาย bus เดียวกัน แต่ RS-422 ไม่สามารถทำงานแบบ multi-point network อย่างเต็มรูปแบบได้ ซึ่งประกอบด้วยหลาย driver และหลาย receiver ที่ต่ออยู่บน bus เดียวกัน แต่ก็ได้มีการแก้ไขให้สามารถสื่อสารแบบ quasi multi-drop โดยใช้สาย 4 wires เพื่อสื่อสารแบบ half-duplex เพื่อหลีกเลี่ยงการชนกันของข้อมูล (data collision)

RS-485 เป็นการทำงานแบบ multi-point แบบเต็มรูปแบบ โดยใช้สาย 2 wires สามารถต่อกับ driver และ receiver ได้ถึง 32 ชุดบน bus เดียวกัน และถ้าผนวกกับการใช้ automatic repeater และ high impedance driver/receiver แล้วจะทำให้สามารถต่อใช้งานได้อีกเป็น 100 เป็น 1,000 nodes บน network เดียวกันได้ และเพิ่มขึดความสามารถในการทนต่อปัญหา common mode ด้วย tri-state และ power off อีกทั้งทนต่อปัญหาของ data collision และ bus fault การแก้ปัญหาเรื่อง collision จะใช้การสื่อสารแบบ half-duplex และทางภาคส่งจะเปลี่ยนเป็นภาครับทันทีหลังจากส่งแล้ว ทำให้สามารถทำงานด้วยความเร็วสูงได้

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

Comments