|
Hardware Interfacing
ตารางสรุปการเชื่อมต่อแบบ Serial communication
ตารางสรุปการเชื่อมต่อแบบ Serial communication
แหล่งที่มา http://www.maxim-ic.com/app-notes/index.mvp/id/3438 |
การติดต่อกับ Switch ON-OFF
ในการติดต่อรับค่าจากสวิทช์ เพื่อให้ไมโครคอนโทรลเลอร์กระทำการบางอย่างให้เรา ในการต่อวงจรหากเราต้องการที่จะรับค่าสภาวะ ON-OFF จากการเปิด ปิด สวิทช์แล้ว เราสามารถที่จะต่อสวิทช์เข้ากับไมโครคอนโทรลเลอร์ โดยมีวงจรการเชื่อมต่อ 2 แบบ ให้เราเลือก ซึ่้งทั้งสองวงจรนี้ ในแง่ของอุปกรณ์แล้ว ใช้จำนวนอุปกรณ์เท่ากัน หรือเหมือนกัน แต่ลักษณะการต่อวงจรไม่เหมือนกัน และให้ค่าสัญญาณทางดิจิตอลต่างกัน แบบที่ 1 การต่อแบบ Active High ในการต่อแบบนี้ ในสภาวะที่หน้าสัมพัส ของสวิทช์ไม่ได้เชื่อมต่อกัน หรือสวิทช์ไม่ได้ถูกกดไว้ ทางฝั่งไมโครคอนโทรลเลอร์จะได้รับสภาวะ เป็น LOW หรือเป็น Logic 0 แต่เมื่อสวิทช์ถูกกระตุ้น หรือหน้าสัมพัสของสวิทช์ เชื่อมต่อกัน จะทำให้เกิดกระแสไฟฟ้าไหล และเกิดแรงดันที่ขาอินพุต ของไมโครคอนโทรลเลอร์ ทำให้ที่ขาของไมโครคอนโทรลเลอร์ได้รับสภาวะเป็น High หรือเป็น Logic 1 แบบที่ 2 การต่อแบบ Active Low ในการต่อวงจรแบบนี้ ตำแหน่งของสวิทช์จะตรงกันข้ามกับการต่อแบบแรก ที่ขาอินพุตของไมโครคอนโทรลเลอร์จะได้รับสภาวะตรงกันข้ามกับแบบแรก คือ เมื่อสวิทช์ไม่ได้รับการกระตุ้น หรือหน้าสัมพัสยังไม่ได้สัมพัสกันนั้น ที่ขาอินพุตของไมโครคอนโทรลเลอร์จะได้รับสภาวะ High หรือ Logic 1 แต่เมื่อสวิทช์ได้รับการกระตุ้น หรือหน้าสัมผัสเชื่อมต่อกันแล้ว จะทำกระแสจากที่เคยไหลเข้าไมโครคอนโทรลเลอร์ ไหลลงไปที่ตำแหน่งกราวด์แทน ทำให้ที่ขาอินพุตของไมโครคอนโทรลเลอร์ได้รับสภาวะ Low หรือ Logic 0 วิธีการจดจำง่ายๆ ก็คือ ถ้าต่อ Switch แบบ Active High เราต้องต่อ R pull down ที่ขาไมโครคอนโทรลเลอร์ ถ้าต่อ Switch แบบ Active Low เราต้องต่อ R pull up ที่ขาไมโครคอนโทรลเลอร์ ในการนำไปใช้ เราสามารถเลือกที่จะต่อแบบ Active Low หรือว่า Active High ก็ได้ แต่ในการเขียนโค๊ดที่ไมโครคอนโทรลเลอร์ เราจะต้องเขียนโค๊ดให้สัมพันธ์กับวงจรที่เราต่อด้วย ตัวอย่างการนำไปใช้งาน // Complier : PIC CCS C complie V4.106 // MCU : PIC18F458 // By : Mr.P #include <18F458.h> #define CRYSTAL 20000000 //crystal 20MHz #fuses HS #fuses NOLVP,NOWDT #fuses NOPROTECT #use delay(clock=CRYSTAL) #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7) void main(void) { set_tris_b(0xff); set_tris_a(0x00); while(TRUE) { output_low(PIN_A0); output_low(PIN_A1); if(!input(PIN_B0)) // Active Low { delay_ms(100); output_high(PIN_A0); delay_ms(1000); } if(input(PIN_B1)) // Active High { delay_ms(100); output_high(PIN_A1); delay_ms(1000); } } } |
การติดต่อสื่อสารด้วย SPI : Serial Peripheral Interface
ภาพรวมของ SPI
SPI หรือ Serial Peripheral Interface เป็นวิธีการสื่อสารรูปแบบหนึ่ง ที่ใช้ในการติดต่อสื่อสารกับอุปกรณ์ ตัวอย่างเช่น พริ้นเตอร์ กล้องถ่ายรูป เครื่องสแกนเนอร์ และอื่นๆ อีกมามาย ถึงแม้ว่าการสื่อสารของ USB ที่มีฟังก์ชั่นการทำงานที่กว้างกว่า แต่การสื่อสารในรูปแบบ SPI ก็ยังถูกใช้งานกันอยู่ในบาง Application
SPI ทำงานในรูปแบบที่ให้อุปกรณ์ตัวหนึ่งทำหน้าที่เป็น MASTER ในขณะที่อีกตัวหนึ่งทำหน้าที่เป็น SLAVE และส่งข้อมูลในโหมด Full-duplex นั่นหมายความว่า สัญญาณสามารถส่งหากันได้ระหว่าง MASTER และ SLAVE ได้อย่างต่อเนื่อง ในการสื่อสารแบบ SPI นี้ ไม่ได้มาตรฐานกำหนดตายตัว ว่าข้อมูลที่ส่งหากันต้องอยู่ในรูปแบบหรือ format แบบไหน เป็นการคิด protocol การสื่อสารกันเอาเอง
อุปกรณ์ที่ยังคงมีการใช้การสื่อสารแบบ SPI อยู่
พื้นฐานการทำงาน
SPI ต้องการสายสัญญาณ สี่เส้น บางครั้งเราเรียกว่าบัสอนุกรม "four wire" เส้นสัญญาณทั้่งสี่เส้น ได้แก่
ที่เราเรียกว่า master ก็เพราะว่า ตัวที่เป็นมาสเตอร์ ทำหน้าที่เป็นตัวควบคุมการสื่้อสารทั้งหมด โดยควบคุมการสื่อสารตามสัญญาณนาฬิกา ตัวมาสเตอร์จะเป็นตัวที่ตัดสินใจ รับ หรือ ส่งข้อมูล ภายในการสื่อสาร จะเป็นการสื่อสารแบบ full duplex ในการนำส่งข้อมูล
เราใช้ สัญญาณเส้น SS หรือ Slave select ในกรณี ที่เรามีตัว slave มากกว่า 1 ตัว โดยการทำให้เส้น SS มีระดับสัญญาณเป็น Low เมื่อต้องการติดต่อกับ Slave ตัวใด จากรูปด้านล่างหากเราต้องการติดต่อสื่อสารกับ Slave ตัวใด ก็เพียงทำให้สัญญาณ SS ของ Slave ตัวนั้น มีระดับสัญญาณเป็น Low
รูปวงจรการต่อมาสเตอร์ 1 ตัวกับ สลาฟ 3 ตัว
โค๊ดตัวอย่างการนำไปใช้งาน
|
การเชื่อมต่อเครื่องมือกับพอร์ตอนุกรม RS232 ด้วย Opto Couple
การเชื่อมต่อเครื่องมือกับพอร์ตอนุกรม RS232 ด้วย Opto Couple ในงานบางอย่างที่มีการเชื่อมต่ออุปกรณ์ เครื่องมือ หรือเครื่องมือวัดกับคอมพิวเตอร์ ทางพอร์ตอนุกรม(RS232) อาจจะมีความจำเป็นที่จะต้องแยกกันทางไฟฟ้า ระหว่างเครื่องมือวัดกับเครื่องคอมพิวเตอร์ ปัญหาที่เกิดขึ้น เช่น การไม่แยกกราวด์ระหว่างคอมพิวเตอร์กับเครื่องมือวัด อาจจะทำให้กระแสไฟฟ้าจากเครื่องมือวัด ทำความเสียหายต่อวงจร ภายใน ของคอมพิวเตอร์ หรือกลับกัน หรืออาจจะทำให้ผู้ใช้งานถูกกระแสไฟฟ้าดูด เป็นต้น
วิธีการ
การใช้ opto couple ในการเชื่อมต่อ (interface) เป็นวิธีการแก้ปัญหาวิธีหนึ่ง โดยเปลี่ยนการเชื่อมต่อ โดยตรงทางไฟฟ้า เป็นการเชื่อมต่อกันทางแสง
ข้อจำกัด
วิธีการนี้ใช้ได้กับ การเชื่อมต่อที่มีการใช้เฉพาะ Rx, Tx และ Ground สำหรับการรับส่งข้อมูล ของพอร์ตอนุกรมเท่านั้น
อุปกรณ์ และวงจร อัตราเร็วในการรับส่งข้อมูล ขึ้นอยู่กับลักษณะของ opto couple ที่นำมาใช้งาน ถ้าเป็นไปได้ ควรเลือกใช้แบบ hi-speed และขึ้นอยู่กับค่าความต้านทาน ของตัวต้านทาน R1 และ R4
ในที่นี้ วงจรจะมีอยู่ด้วยกันสองแบบ คืิอ แบบแรกเป็นวงจร สำหรับการเชื่อมต่อระหว่างคอมพิวเตอร์กับเครืองมือวัด และแบบที่สองเป็นวงจร สำหรับการเชื่อมต่อระหว่างคอมพิวเตอร์กับไมโครคอนโทรลเลอร์ หรือไมโครโปรเซสเซอร์
ที่มา http://www.manmachine-interface.com |
การ Interface กับ Serial Port (Part VII)
การ Interface กับ Serial Port (Part VI)
Table 11. แสดงรายละเอียดของ Modem Control Register. Table 11. Modem Control Register.
MCR เป็น register ชนิด read/write สำหรับ bit 5, 6 และ 7 ถูก reserve ไว้ Line Status Register (LSR) Table 12. แสดงรายละเอียดของ Line Status Register Table 12. Line Status Register.
Line Status Register เป็น register ชนิด read only Bit 7 จะบ่งบอกถึงความผิดปรกติของสิ่งที่รับเข้ามาใน FIFO เช่น มี bit ที่เสียหายหรือ parity ไม่ถูกต้องหรือ frame ของข้อมูลไม่ถูกต้องเป็นต้น Bit 6 ถ้ามีค่าเป็น “1” จะแสดงว่าทั้งใน Tx holding register และ shift register ว่าง ซึ่ง Tx holding register จะเป็นตัวเก็บข้อมูลที่จะส่งในรูปแบบ parallel ส่วน shift register จะทำหน้าที่แปลงข้อมูลจาก parallel ให้เป็น serial ส่งออกไป Bit 5 บ่งบอกว่าเฉพาะ Tx holding register ที่ว่างลง แต่ยังมีข้อมูลใน shift register อยู่ ความแตกต่างระหว่าง bit5 และ bit 6 คือ bit 5 บอกว่าสามารถส่งข้อมูลเข้าไปยัง Tx holding register และ Tx ก็ยังส่งข้อมูลอีก 1 byte ที่ค้างอยู่ใน shift register อยู่ ส่วน bit 6 บอกว่าไม่มีข้อมูลเหลือค้างในระบบการส่งแล้ว Bit 4 เป็นตัวบอกว่าทางด้าน Rx อยู่ในสถานะ “space” หรือ “0” นานกว่าระยะเวลาของ 1 full word แล้ว ซึ่งระยะเวลาของ 1 full word หมายถึงเวลาของ (data bits)+(parity bit)+(start bit)+(stop bits) Bit 3 จะเกิดขึ้นเมื่อปรากฏว่า bit สุดท้ายไม่ใช่ stop bit ซึ่งอาจจะเกิดจาก timing error เช่นการปรับ speed ของตัวรับกับตัวส่งไม่เท่ากัน Bit 2 เป็นตัวบอกว่ามี parity error เกิดขึ้น แสดงว่าข้อมูลที่รับได้มี error หรือไม่ก็ตั้งเงื่อนไขของ parity ระหว่างตัวรับกับตัวส่งไม่ตรงกัน Bit 1 บอกว่าเกิด overrun ขึ้น แสดงว่า software อ่านข้อมูลไม่ทัน ทำให้ข้อมูลที่รับเข้ามาใหม่ไปทับซ้อนแทนที่ข้อมูลเก่าที่ยังไม่ได้รับการ อ่านจาก software Bit 0 บอกว่าข้อมูลรับเข้ามารออยู่ใน Rx buffer แล้ว พร้อมรอให้อ่านอยู่ Table 13. แสดงรายละเอียดของ Modem Status Register Table 13. Modem Status Register.
Modem Status Register เป็น register ชนิด read only Bit 0 บอกว่า delta clear to send คำว่า delta หมายถึงมีการเปลี่ยนแปลงเกิดขึ้น เช่นในกรณีนี้แสดงว่ามีการเปลี่ยนแปลงของสัญญาณ clear to send เกิดขึ้นเมื่อเทียบกับการอ่าน register นี้ในครั้งที่แล้ว bit 1 และ 3 ก็ทำหน้าที่ในทำนองเดียวกัน Bit 2 บอกว่ามีการเปลี่ยนสถานะจาก “low เป็น “high” ที่สัญญาณ ring indicator เกิดขึ้น Bit 4 ถึง 7 บอกถึงสถานะของสัญญาณนั้น ๆ Scratch register ไม่ได้นำมาใช้ในการสื่อสารของ PC โดยตรง แต่ใช้เป็นที่พักข้อมูลในการอื่น ซึ่งประโยชน์ที่พอจะพบใน PC/AT คือใช้ตรวจว่า UART เป็นเบอร์ 8250/8250B ซึ่งไม่ได้ออกแบบมาให้ใช้กับ PC/AT หรือเบอร์ 8250A/16450 Programming การเขียน Program ทางสื่อสารจะมี 2 วิธีหลัก ๆ คือ
/* Name : Sample Comm's Program - Polled Version - termpoll.c */ /* Written By : Craig Peacock (cpeacock@senet.com.au) */ /* Date : Saturday 22nd February 1997 */ /* Copyright 1997 CRAIG PEACOCK (cpeacock@senet.com.au)*/ /* See http://www.senet.com.au/~cpeacock/serial.htm */ /* For More Information */ #include #include #include #define PORT1 0x3F8 /* Defines Serial Ports Base Address */ /* COM1 0x3F8 */ /* COM2 0x2F8 */ /* COM3 0x3E8 */ /* COM4 0x2E8 */ void main(void) { int c; int ch; outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */ /* PORT 1 - Communication Settings */ outportb(PORT1 + 3 , 0x80); /* SET DLAB ON */ outportb(PORT1 + 0 , 0x03); /* Set Baud rate - Divisor Latch Low Byte */ /* Default 0x03 = 38,400 BPS */ /* 0x01 = 115,200 BPS */ /* 0x02 = 56,700 BPS */ /* 0x06 = 19,200 BPS */ /* 0x0C = 9,600 BPS */ /* 0x18 = 4,800 BPS */ /* 0x30 = 2,400 BPS */ outportb(PORT1 + 1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */ outportb(PORT1 + 3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ outportb(PORT1 + 2 , 0xC7); /* FIFO Control Register */ outportb(PORT1 + 4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ printf("\nSample Comm's Program. Press ESC to quit \n"); do { c = inportb(PORT1 + 5); /* Check to see if char has been */ /* received. */ if (c & 1) {ch = inportb(PORT1); /* If so, then get Char */ printf("%c",ch);} /* Print Char to Screen */ if (kbhit()){ch = getch(); /* If key pressed, get Char */ outportb(PORT1, ch);} /* Send Char to Serial Port */ } while (ch !=27); /* Quit when ESC (ASC 27) is pressed */ } การ polling ไม่ใช่ว่าจะไม่ควรใช้เสียทีเดียว มันยังมีประโยชน์อยู่เช่น ใช้ตรวจสอบว่า UART อยู่ที่ address ไหนและใช้ IRQ ใดโดยการ enable ทีละ IRQ ผ่าน PIC ซึ่งสามารถใช้ตรวจหาอุปกรณ์อื่น ๆ ด้วยเช่น Modem เป็นต้น Buff1024.c - An Interrupt Driven Comms Program /* Name : Sample Comm's Program - 1024 Byte Buffer - buff1024.c */ /* Written By : Craig Peacock (cpeacock@senet.com.au) */ /* Copyright 1997 CRAIG PEACOCK (cpeacock@senet.com.au) */ /* See http://www.senet.com.au/~cpeacock/serial.htm */ /* For More Information */ #include #include #include #define PORT1 0x2E8 /* Port Address Goes Here */ /* Defines Serial Ports Base Address */ /* COM1 0x3F8 */ /* COM2 0x2F8 */ /* COM3 0x3E8 */ /* COM4 0x2E8 */ #define INTVECT 0x0B /* Com Port's IRQ here */ /* (Must also change PIC setting) */ int bufferin = 0; int bufferout = 0; char ch; char buffer[1025]; void interrupt (*oldport1isr)(); void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */ { 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); } void main(void) { int c; outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */ oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector for */ /* later recovery */ setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */ /* COM1 - 0x0C */ /* COM2 - 0x0B */ /* COM3 - 0x0C */ /* COM4 - 0x0B */ /* PORT 1 - Communication Settings */ outportb(PORT1 + 3 , 0x80); /* SET DLAB ON */ outportb(PORT1 + 0 , 0x03); /* Set Baud rate - Divisor Latch Low Byte */ /* Default 0x03 = 38,400 BPS */ /* 0x01 = 115,200 BPS */ /* 0x02 = 56,700 BPS */ /* 0x06 = 19,200 BPS */ /* 0x0C = 9,600 BPS */ /* 0x18 = 4,800 BPS */ /* 0x30 = 2,400 BPS */ outportb(PORT1 + 1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */ outportb(PORT1 + 3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ outportb(PORT1 + 2 , 0xC7); /* FIFO Control Register */ outportb(PORT1 + 4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ outportb(0x21,(inportb(0x21) & 0xF7)); /* Set Programmable Interrupt */ /* Controller */ /* COM1 (IRQ4) - 0xEF */ /* COM2 (IRQ3) - 0xF7 */ /* COM3 (IRQ4) - 0xEF */ /* COM4 (IRQ3) - 0xF7 */ outportb(PORT1 + 1 , 0x01); /* Interrupt when data received */ printf("\nSample Comm's Program. Press ESC to quit \n"); 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); outportb(PORT1 + 1 , 0); /* Turn off interrupts - Port1 */ outportb(0x21,(inportb(0x21) | 0x08)); /* MASK IRQ using PIC */ /* COM1 (IRQ4) - 0x10 */ /* COM2 (IRQ3) - 0x08 */ /* COM3 (IRQ4) - 0x10 */ /* COM4 (IRQ3) - 0x08 */ setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */ } หมายเหตุ Source code ข้างบนนี้เป็นการย่นย่อเพื่อให้ง่ายต่อการเข้าใจ ในทางปฏิบัติจริง เมื่อเข้าสู่ communication program ควรมีการเก็บค่า status ของ registers ต่าง ๆ ใน UART ไว้ และก่อนที่จะออกจาก communication program ก็ต้องทำการ restore มันกลับสภาพเดิม เพื่อ program อื่นจะได้ใช้ต่อไป
|
การ Interface กับ Serial Port (Part V)
IIR เป็น register แบบ read only เราไม่สามารถเขียนเข้าไปได้ Table 8. ข้างล่างแสดงถึงหน้าที่ของ bit ต่าง ๆ ใน register นี้ Table 8. Interrupt Identification Register.
Bit6 และ bit7 เป็นตัวบอกสภาวะของ FIFO buffer เมื่อทั้ง 2 bit มีค่าเป็น “0” แสดงว่าไม่มี FIFO buffer ที่ active อยู่ ซึ่ง UART เบอร์ 8250 และ 16450 จะเป็นกรณีนี้ได้เพียงกรณีเดียวเท่านั้น ไม่สามารถเป็นอย่างอื่นได้ ถ้า bit7 มีค่าเป็น “1” แต่ bit6 มีค่าเป็น “0” มีความหมายว่า FIFO buffer ได้ถูก enable แต่ไม่ทำงาน ซึ่งเกิดในกรณีของ UART เบอร์ 16550 เพราะมีข้อผิดพลาด(bug)ในตัวมัน จึงต้องมีการแก้ไขและเปลี่ยนมาเป็นเบอร์ 16550A และถ้าทั้ง bit7 กับ bit6 มีค่าเป็น “1” แสดงว่ามี FIFO buffer อยู่และใช้งานได้อย่างสมบูรณ์ สำหรับ bit4 และ bit5 สำรองไว้ไม่ได้ใช้งาน ส่วน bit3 เป็นตัวแสดงสภาวะของ time-out interrupt ของ UART ตั้งแต่เบอร์ 16550 ขึ้นไป bit0 เป็นตัวบอกว่ามี interrupt เกิดขึ้นหรือไม่ ถ้ามี interrupt เกิดขึ้น bit1 และ bit2 จะเป็นตัวบอกว่าเป็น interrupt ของอะไรตามลำดับความสำคัญ(priority) โดย line status interrupt จะมี priority สูงสุด และ modem status interrupt จะมี priority ต่ำสุด First In/First Out Control Register (FCR) Table 9. แสดงรายละเอียดของ FIFO Control Register Table 9. FIFO Control Register.
FIFO Control Register เป็นชนิด write only และจะใช้ควบคุม FIFO buffers ซึ่งมีใน UART เบอร์ 16550 ขึ้นไปเท่านั้น Bit 0 เป็นตัว enable ให้ FIFO buffer ของทั้ง Tx และ Rx ให้ทำงาน ถ้าสั่งให้ Bit นี้มีค่าเป็น “0” จะทำให้ disable ตัว FIFO buffer ของทั้ง Tx และ Rx และทำให้ข้อมูลที่อยู่ใน FIFO buffers ทั้ง 2 สูญหายไป Bit 1 และ 2 ควบคุมการ clear ข้อมูลใน FIFO buffer ของ Tx หรือ Rx แต่จะไม่เกี่ยวกับ shift registers และเมื่อสั่งให้มีค่าเป็น “1” เพื่อ Clear ข้อมูลใน FIFO buffer แล้วมันจะกลับเป็น “0” เองหลังจากได้ clear ข้อมูลใน FIFO buffer แล้ว Bit 3 เป็นตัว enable ตัว DMA Mode Select ซึ่งมีใน UART เบอร์ 16550 ขึ้นไปและจะกล่าวถึงภายหลัง ส่วน Bit 4 และ 5 ไม่ได้ใช้จึง Reserved ไว้ Bit 6 และ 7 ใช้กำหนด triggering level ของ Receiver FIFO buffer เช่น ถ้ากำหนดให้ Bit 7 มีค่าเป็น “1” และ Bit 6 มีค่าเป็น “0” จะเป็นการกำหนดให้ FIFO buffer มีขนาด 8 bytes และเมื่อมีข้อมูลเข้ามาใน FIFO buffer ได้ 8 bytes จะทำให้ Received Data Available Interrupt ทำงาน (ดูรายละเอียดในเรื่อง IIR ประกอบ) Table 10. แสดงรายละเอียดของ Line Control Register. Table 10. Line Control Register.
หมายเหตุ X = Don’t care Line Control Register เป็นตัวกำหนด Parameter พื้นฐานของการสื่อสาร bit 7 เป็น DLAB (ดูหัวข้อเกี่ยวกับ DLAB ประกอบ) bit 6 เป็นตัวกำหนด break enable ถ้ามีค่าเป็น “1” จะทำให้สัญญาณ TD มีสถานะเป็น “space” ทำให้ UART ที่ได้รับสัญญาณเกิดการ break ถ้า bit 6 นี้มีค่าเป็น “0” จะไม่มีการ break bit 3, 4 และ 5 เป็นตัวกำหนด parity bit ถ้าสังเกตให้ดีจะเห็นว่า bit 3 เป็นตัวกำหนดการใช้หรือไม่ใช้ parity เพราะถ้า bit 3 มีค่าเป็น “0” จะไม่ใช้ parity แต่ถ้า bit 3 มีค่าเป็น “1” จะใช้ parity จากนั้นมาดูที่ bit 5 จะเห็นว่าถ้า bit 5 มีค่าเป็น “1” มันจะควบคุมเป็น sticky parity คือมันจะส่งค่าของ parity bit คงที่ตายตัวเช่นถ้า bit 4 เป็น “0” จะทำให้มีการส่ง parity bit เป็น “1” หรือ “high” ตลอด ไม่ว่าข้อมูลจะมี bit pattern เป็นอย่างไรก็ไม่เกี่ยว ดังนั้นถ้ามี error ในการส่งข้อมูลตัว parity bit ก็ยังคงส่งค่าเดิมที่ตั้งไว้คือ “1” หรือ “high” ซึ่งไม่มีประโยชน์ในการตรวจสอบความถูกต้องของข้อมูล แต่จะใช้ในเหตุผลอื่นเช่น เป็นตัวบอก Rx ว่าสิ่งที่รับได้น่าจะเป็นข้อมูลหรือเป็นสัญญาณรบกวน โดยการตรวจสอบที่ parity bit เป็นต้น ซึ่งมักจะใช้กับระบบที่ความถูกต้องของข้อมูลไม่ใช่สาระสำคัญมากนัก เพราะอาจจะมีกระบวนการหรือกลไกอื่นที่ช่วยในการกลั่นกรองเช่น ใช้วิธีหาค่าเฉลี่ยจากค่าสะสมหลาย ๆ ค่า หรือมีค่าเป็นช่วงจำกัดให้เปรียบเทียบ หรือระบบไม่ต้องการค่าที่ละเอียดถูกต้องนัก หรือถึงจะผิดพลาดก็ไม่ได้ก่อให้เกิดความเสียหายอะไรมากนักเป็นต้น แต่ต้องการรู้ว่าสิ่งที่รับได้น่าจะเป็นข้อมูลหรือไม่มากกว่า เพื่อไม่เอาค่าจากสัญญาณรบกวนไปประมวลผล ซึ่งเป็นการกลั่นกรองระดับหนึ่ง เพิ่มเติมจากการตรวจ start bit และ stop bit และถ้า bit 5 เป็น “0” จะปลดจาก sticky คือค่า parity bit จะแปรเปลี่ยนไปตามข้อมูลเช่นถ้า bit 4 เป็น “0” ก็จะเป็น odd parity หมายความว่า parity bit จะมีค่าเป็น “1” หรือ “0” ขึ้นอยู่กับจำนวน “1” ในข้อมูลเมื่อรวมกับ parity bit แล้วต้องมีจำนวนเป็นคี่ เป็นต้น ซึ่งช่วยตรวจความถูกต้องของข้อมูลได้ดีขึ้นระดับหนึ่ง เพราะขณะที่ข้อมูลมาถึง Rx หากมีการเปลี่ยนค่าไปหนึ่ง bit ก็สามารถตรวจพบว่า parity ผิด แต่ถ้าผิดไปสอง bit ก็จะไม่สามารถตรวจได้เพราะ parity ถูก ดังนั้นในการสื่อสารจึงพยายามหาวิธีที่ดีขึ้นในการตรวจและแก้ไขความผิดพลาด (error detection and correction) เช่นการใช้ cyclic redundancy check (CRC) ซึ่งใช้การคำนวณเข้ามาช่วย (จะไม่กล่าวถึงรายละเอียดในที่นี้) bit 2 เป็นตัวกำหนดจำนวนของ stop bit ถ้า bit 2 มีค่าเป็น “0” จะกำหนดให้มีเพียง 1 stop bit แต่ถ้า bit 2 มีค่าเป็น “1” จำนวน stop bit จะขึ้นอยู่กับขนาดของ word length โดย bit 0 และ bit 1 จะเป็นตัวกำหนดขนาดของ word length อีกทีหนึ่ง ปรกติทาง Rx จะตรวจสอบเพียง bit แรกของ stop bit เท่านั้น มีคำถามว่า ทำไมจึงต้องมีจำนวน stop bit ต่างกัน ฝากไว้ให้คิดเป็นการบ้านด้วย |
การ Interface กับ Serial Port (Part IV)
การ 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 (For PC’s)
Serial Port Registers Table 3. Standard Port Addresses.
Table 3. แสดง Address และ IRQ ของ Serial Port หรือ COM Port ที่ใช้ในเครื่อง PC ส่วนใหญ่ แต่ถ้าไม่แน่ใจเราก็สามารถหาข้อมูลเหล่านี้ได้ โดยอ่านจาก BIOS ตาม Address ที่แสดงใน Table 4. ข้างล่างนี้ Table 4. COM Port Address in the BIOS Data Area.
ตัวอย่างต่อไปนี้เป็นตัวอย่าง 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 5. แสดงถึง Address ของ Register ต่าง ๆ Table 5. Table of Registers.
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.
Interrupt Enable Register (IER) Table 7. แสดงหน้าที่ของ bit ต่าง ๆ ใน Interrupt Enable Register Table 7. Interrupt Enable Register.
ถ้า 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
|
การ Interface กับ Serial Port (Part III)
ตารางข้างล่างนี้แสดงถึงหน้าที่ของขาต่าง ๆ
หน้าที่ของ Signal ต่าง ๆ มีดังนี้
อุปกรณ์ DCE บางรุ่นได้รับการออกแบบมาให้สามารถตรวจสอบระบบสื่อสารได้ด้วยการสั่งจาก DTE ให้ทำการ Loop back ทั้งจาก Local หรือ Remote ด้วยการใช้สัญญาณที่กล่าวมาทั้งหมดนี้
Null Modems Null Modem ใช้สำหรับเชื่อมโยงระหว่าง DTE 2 ตัวเข้าด้วยกันโดยตรง ซึ่งโดยมากใช้ในการถ่ายข้อมูลระหว่าง Computer หรือใช้ในการพัฒนาระบบ Microprocessor หรือ Microcontroller ต่าง ๆ Figure 1. Null modem wiring diagram. จะเห็นว่าใช้สายเพียง 3 เส้นคือ TD, RD และ SG และมีการต่อ Jump ที่หัวต่อแต่ละข้างอีกเล็กน้อยเท่านั้น เพื่อหลอกให้ Computer คิดว่ามันกำลังคุยกับ DCE อยู่ หมายเหตุ TD ของ Computer เครื่องหนึ่งจะต้องต่อกับ RD ของ Computer อีกเครื่องหนึ่ง แต่ถ้าเป็นการต่อระหว่าง DTE กับ DCE จริง ๆ จะต่อขาสัญญาณตรงกันโดยไม่ต้องสลับสายเช่นขา 2 ของ DTE จะต่อกับขา 2 ของ DCE และขา 3 ของ DTE จะต่อกับขา 3 ของ DCE เป็นต้น สำหรับ Plug ตัวนี้มีวัตถุประสงค์เพื่อช่วยในการเขียน Program ที่ติดต่อกับ Serial Port แต่อาจจะไม่สามารถใช้กับ Program ที่ใช้วิเคราะห์หาจุดเสีย (Diagnostic program) เพราะแต่ละ Program อาจจะออกแบบการเชื่อมต่อที่แตกต่างกันไป Figure 2. Loopback plug wiring diagram. DTE/DCE Speeds ความเร็วของการติดต่อระหว่าง DTE กับ DCE หรือระหว่าง Computer กับ Modem ซึ่งมักจะเรียกว่า Terminal speed และความเร็วระหว่าง DCE กับ DCE หรือระหว่าง Modem กับ Modem ซึ่งมักจะเรียกว่า Line speed ปรกติ Terminal speed มักจะเร็วกว่า Line speed เช่น Modem มี speed 56K baud ขณะที่ติดต่อกับ Computer ด้วย speed 115.2Kbps เป็นต้น ซึ่ง COM Port ของ Computer ต้อง set ให้เป็น 115.2Kbps ด้วย ปัจจุบัน UART เบอร์ 16550A จะรองรับ speed ได้ 115.2Kbps และเบอร์ 16C650 จะรองรับ speed ได้ 230.4Kbps การติดต่อระหว่าง DTE และ DCE จะมีการควบคุมการไหลของข้อมูล เพื่อไม่ให้เกิดการ Overflow ขึ้นได้ ซึ่งมีอยู่ 2 แบบคือ Hardware flow control และ Software flow control สำหรับ Software flow control มักจะเรียกว่า Xon/Xoff flow control ซึ่งใช้รหัส ASCII 17 เป็นสัญญาณ Xon และใช้รหัส ASCII 19 เป็นสัญญาณ Xoff หลักการทำงานก็ง่าย ๆ คือ Modem จะมี Buffer อยู่ เมื่อ Modem รับข้อมูลจาก Computer จน Buffer ใกล้จะเต็ม มันก็จะส่งสัญญาณ Xoff ไปให้ Computer เพื่อให้ Computer หยุดส่งข้อมูลให้มันชั่วคราว และเมื่อ Buffer มีที่ว่างถึงระดับหนึ่ง Modem ก็จะส่งสัญญาณ Xon ไปให้ Computer เพื่อให้ Computer ส่งข้อมูลให้มันต่อ การควบคุมโดยวิธีนี้ประหยัดสายสัญญาณ เพราะรับ-ส่งผ่าน TD และ RD แต่อาจทำให้การสื่อสารช้าลงอย่างเห็นได้ชัดในกรณีที่ใช้กับการสื่อสารที่มี speed ต่ำ เพราะแต่ละตัวอักษร ASCII ที่รับ-ส่งจะมีขนาด 10 Bit ส่วน Hardware flow control มักจะเรียกว่า RTS/CTS flow control จะใช้สายสัญญาณของ Serial Port ในการควบคุม ทำให้ไม่บั่นทอนความเร็วของข้อมูล หลักการทำงานคือ เมื่อ Modem มีที่ว่างเพื่อรับข้อมูล มันก็จะส่งสัญญาณ CTS ไปให้ Computer และเมื่อมันใกล้จะเต็ม มันก็จะหยุดส่งสัญญาณ CTS ไปให้ Computer The UART (8250’s and Compatibles) เครื่อง PC ส่วนใหญ่จะใช้ UART ในกลุ่ม 8250 ซึ่งรวมทั้ง 16450, 16550, 16650 และ 16750 Figure 3. Pin diagram for 16450, 16550 & 8250 UART UART เบอร์ 16550 มีลักษณะเหมือนกับเบอร์ 16450 และ 8250 ยกเว้นขา 24 และขา 29 โดยเบอร์ 8250/16450 ขา 24 จะเป็น Chip Select Out เป็นสัญญาณบอกว่า Chip ตัวนี้ได้ถูกเลือกใช้งานอยู่ และขา 29 ไม่ได้ใช้งาน ส่วนเบอร์ 16550 จะใช้ขา 24 เป็นสัญญาณ Transmit Ready และขา 29 เป็นสัญญาณ Receive Ready ซึ่งสามารถใช้กับ Direct Memory Access (DMA) โดยสามารถกำหนด Mode การทำงานได้ 2 Mode คือ Mode 0 หรือ 16450 Mode เป็น Single transfer DMA และ Mode 1 เป็น Multi-transfer DMA Mode 0 ใน Mode นี้ RXRDY จะเป็น Active low เมื่อมีข้อมูลอย่างน้อย 1 Byte อยู่ใน Buffer ของภาครับ และจะเป็น Inactive high เมื่อไม่มีข้อมูลใน Buffer ของภาครับ ส่วน TXRDY จะเป็น Active low เมื่อไม่มี ข้อมูลใน Buffer ของภาคส่ง และจะเป็น Inactive high หลังจากที่มีข้อมูล Byte แรกเข้าสู่ Buffer ของภาคส่ง การเข้าสู่ Mode 0 จะเกิดขึ้นได้จาก 2 กรณีคือ เมื่อ FIFO Buffer ถูก Disable โดย Bit 0 ของ FIFO Control Register (FCR) หรือเมื่อ FIFO Buffer ได้ถูก Enable ไว้แต่เลือก DMA Mode 0 ไว้โดย Bit 3 ของ FCR Mode 1 ใน Mode นี้ RXRDY จะเป็น Active low เมื่อข้อมูลใน Buffer ถึงระดับที่กำหนดหรือเมื่อ 16550 เกิด Time out และจะกลับสู่สภาพ Inactive เมื่อไม่มีข้อมูลใน Buffer ของภาครับ ส่วน TXRDY จะเป็น Active low เมื่อไม่มีข้อมูลใน Buffer ของภาคส่ง และจะเป็น Inactive เมื่อมีข้อมูลอยู่เต็มใน Buffer ของภาคส่ง การเข้าสู่ Mode 1 จะเกิดขึ้นเมื่อ FIFO Buffer ได้ถูก Enable และกำหนด DMA ให้ทำงานใน Mode 1 เท่านั้น ปรกติ UART ทุกตัวจะมีระดับสัญญาณตามมาตรฐาน TTL คือ 0Volt และ +5Volt ดังนั้นจึงต้องมีวงจรที่ทำหน้าที่เป็น RS-232 Converter เพื่อแปลงสัญญาณระหว่าง TTL และ RS-232 อีกทีหนึ่ง เช่น IC เบอร์ DS-1488 และ DS-1489 ที่ใช้ในเครื่อง PC ทั่วไป และใช้ไฟ +12Volt กับ –12Volt ที่มีอยู่ในเครื่อง PC เป็นระดับสัญญาณด้าน RS-232 Table 2. Pin assignments for 16550A UART
|
การ Interface กับ Serial Port (Part II)
การ Interface กับ Serial Port (Part II)Serial Port มีขั้วต่อ 2 แบบคือ แบบ D-Type 25 Pin และแบบ D-Type 9 Pin ซึ่งทั้ง 2 แบบ จะเป็นชนิดตัวผู้ทางด้านของ Computer ดังนั้นอุปกรณ์ที่จะนำมาต่อกับ Computer จึงต้องใช้ขั้วต่อชนิดตัวเมีย Table 1. ข้างล่างแสดง ชื่อสัญญาณของขาต่าง ๆ (Male at the computer side) (Female at the cable side)25 PIN D-SUB MALE at the computer.
Note: Direction is DTE (Computer) relative DCE
(Modem).
9 PIN D-SUB MALE at the Computer.
Note: Direction is DTE (Computer) relative DCE
(Modem).
Table 1. D-Type 25 and D-Type 9 Connector
|