Thaimicrotron.com : Home |
|
การเชื่อมต่อพอร์ตอนุกรม
(Serial Port) กับไมโครคอนโทรลเลอร์ |
|
|
|
|
|
วัตถุประสงค์ |
|
|
|
|
|
|
|
|
|
|
|
วงจรการเชื่อมต่อพอร์ตอนุกรม บนบอร์ดทดลอง |
|
|
|
|
|
|
|
|
การใช้งานพอร์ตอนุกรม MCS-51 |
|
|
|
|
|
- ไมโครคอนโทรลเลอร ์ตระกูล MCS-51จะมีวงจรสื่อสารอนุกรม UART
(Universal Asynchronous Receiver Transmitter) แบบ Full Duplex คือ สามารถรับและส่งข้อมูล
ได้พร้อมกันคือขา P3.0 เป็นขารับข้อมูล (RX ) และ P3.1 เป็นขา ส่งข้อมูล (TX) |
|
|
|
|
|
รีจิสเตอร์ที่เกี่ยวข้องในการทำงานของพอร์ตอนุกรม |
|
|
|
|
|
รีจิสเตอร์ SCON (98H) |
|
|
|
|
|
|
|
|
รีจิสเตอร์ TMOD(89H) |
|
|
|
|
|
|
|
|
รีจิสเตอร์ TCON (88H) |
|
|
|
|
|
|
|
|
|
|
|
ตารางค่าคงที่ๆ กำหนดจากการใช้ ไทม์เมอร์1 เมื่อใช้อัตราความเร็วในการส่งข้อมูลมาตรฐานต่างๆ |
|
|
|
|
|
- รีจิสเตอร์บัฟเฟอร์ SBUF
(Serial data buffer register) มีตำแหน่งอยู่ที่ 99H แบ่งออกเป็นสองส่วนคือ
ส่วนที่ใช้เป็นบัฟเฟอร์ในการส่งข้อมูล และส่วนที่ใช้เป็นบัฟเฟอร์ในการรับข้อมูล
- รีจิสเตอร์ควบคุมการทำงานของพอร์ตอนุกรม SCON
(Serial port Control Register) มีตำแหน่งอยู่ที่ 98H
,บิต TI และบิต RI
- รีจิสเตอร์เลือกโหมดการทำงานของไทเมอร์/เคาน์เตอร TMOD
(Timer/Counter Mode Control Register) มีตำแหน่งอยู่ที่ 89H
- รีจิสเตอร์ TH1 (Timer
1 High) กำหนดค่าของไทเมอร์ 1 เพื่อเลือก baud rate มีตำแหน่งอยู่ที่ 8Dh
- รีจิสเตอร์ควบคุมการทำงานของไทเมอร์/เคาน์เตอร์ TCON
(Timer/Counter Control Register) มีตำแหน่งอยู่ที่ 88H และบิต TR1
เป็นบิตควบคุม การทำงานของไทเมอร์
|
|
|
|
|
|
|
|
|
การกำหนดค่าเริ่มต้น สำหรับการใช้งานพอร์ตอนุกรม
(Initial Serial Port) |
|
|
- สำหรับในการทดลองจะใช้ Baud Rate 9600, ข้อมูลรับ-ส่งมีขนาด 8 บิต
, 1 Stop บิท และไม่มีตรวจสอบ Parity บิต ซึ่งเป็น มาตรฐาน การใช้งานพอร์ตอนุกรม
ของ ไมโครคอนโทรลเลอร์ โดยทั่วไป |
|
|
|
|
|
โปรแกรมย่อยที่ใช้ในการกำหนดค่าเริ่มต้นในการใช้งานพอร์ตอนุกรม: |
|
|
|
InitUART: |
MOV SCON,#01010010B |
;Set SCON Serial Control
Mode 1: 8-bit UART (Timer-Based). |
|
|
MOV TMOD,#00100000B |
;Set Mode 2 8-bit Auto-Reload |
|
|
MOV TH1,#0FDH |
;Set Baud Rate 9600 |
|
|
SETB TR1 |
;Enable Timer 1 |
|
|
RET |
|
|
|
|
|
|
|
|
หลักการทำงานของโปรแกรม |
|
|
|
|
|
- กำหนดให้ SCON = mode 1 SMO=0, SM1=1 เพื่อกำหนด ให้พอร์ตอนุกรม เป็นแบบ
8 บิต และ เลือก baud rate โดยใช้ไทเมอร์ 1
- กำหนดให้ TMOD = mode 2 M1=1, M0=0
การทำงาน ของไทเมอร ์เป็นแบบ 8-bit Auto-Reload (โหลดค่าเริ่มต้น ใหม่อัตโนมัติ
เมื่อเกิด Overflow)
- กำหนดให้ TH1 = 0FDH กำหนดค่าของไทเมอร์ เพื่อเลือก baud rate = 9600
- กำหนดให้ TR1 = 1 ให้ไทเมอร์ 1 เริ่มทำงาน (TR1 เป็นบิตควบคุมอยู่ในรีจิสเตอร์
TCON)
|
|
|
|
|
|
- เมื่อเรียกโปรแกรมย่อย InitUART แล้วพอร์ตอนุกรมก็พร้อมที่จะทำงาน |
|
|
|
|
|
โปรแกรมย่อยการส่งข้อมูลออกจากพอร์ตอนุกรม |
|
|
|
; ********** SBYTE SUB
**********
;SEND BYTE
;IN = A
;REG = NO |
|
|
SBYTE: |
JNB TI,SBYTE |
;Wait For Sending done |
|
|
CLR TI |
;Clear TI for Send data |
|
|
MOV SBUF,A |
;Send data |
|
|
RET |
|
|
|
|
|
หลักการทำงานของโปรแกรม |
|
|
- ตรวจสอบบิต TI ว่าการส่งข้อมูลเก่ายังมีค้างอยู่หรือไม่ |
|
|
- เคลียร์บิต TI เพื่อเตรียมส่งข้อมูล |
|
|
- ส่งข้อมูลจาก A เข้าสู่ SBUF |
|
|
|
|
|
โปรแกรมย่อยการรับข้อมูลจากพอร์ตอนุกรม |
|
|
|
; ********** RBYTE SUB
**********
;OUT = A
;REG = A |
|
|
RBYTE: |
JNB RI,RBYTE |
;Wait For Receive already |
|
|
CLR RI |
;Clear RI for Receive next byte |
|
|
MOV A,SBUF |
;Get data from SBUF |
|
|
RET |
|
|
|
|
|
หลักการทำงานของโปรแกรม |
|
|
- ตรวจสอบบิต RI ว่ามีข้อมูลเข้ามาหรือไม่ |
|
|
- เคลียร์บิต RI เพื่อเตรียมรับข้อมูลตัวถัดไป |
|
|
- อ่านค่าจาก SBUF มาเก็บไว้ที่ A |
|
|
|
|
|
ASCII Code
( American Standard Code for Information Interchange) |
|
|
คือตารางรหัสมาตรฐานที่นิยมใช้ในการรับส่งข้อมูลแบบอนุกรม ประกอบด้วยรหัสควบคุม
00H-1FH และรหัสตัวอักษร 20H-7FH |
|
|
ข้อมูลตัวอักษร (Character) |
|
|
เป็นข้อมูลขนาด 1 ไบท์มีค่าตั้งแต่ 20H-7FH ในรหัส ASCII และ
80H-FFH เป็นรหัสตัวอักษรเพิ่มเติม เช่นภาษาไทย |
|
|
ข้อมูลสตริง (String) |
|
|
ข้อมูลสตริง คือข้อมูลตัวอักษรที่ต่อกันเป็นสายยาวและแสดงจุดสิ้นสุดข้อมูลด้วยค่า
NULL หรือ 00 |
|
|
|
|
|
ตัวอย่างการกำหนดข้อมูลสตริงในโปรแกรม |
|
|
hello: |
DB
|
0Dh,"***
MCS-51 READY ***",0Dh,0AH,00 |
|
|
|
|
|
|
|
|
|
|
|
|
|
โปรแกรมย่อยการส่งข้อมูลสตริง |
|
|
|
SendStr: |
CLR
A |
|
|
|
MOVC A,@A+DPTR
|
;load
char |
|
|
SUBB A,#00 |
;test
end of string |
|
|
JZ ENDSTR |
;yes
end |
|
|
LCALL SBYTE |
;send
1 byte |
|
|
INC DPTR |
;point
to next char |
|
|
SJMP SENDSTR |
;load
next char |
|
EndStr: |
RET |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
เริ่มการทดลอง |
|
|
|
|
|
|
|
|
รูปการต่อสาย Link บนบอร์ดทดลอง |
|
|
|
|
|
อุปกรณ์เพิ่มเติม สายสัญญาณที่ใช้เชื่อมต่อระหว่างไมโครคอนโทรลเลอร์กับ
PC แบบ 3 เส้น |
|
|
|
|
|
|
|
|
วิธีการทดลอง |
|
|
- เมื่อ download ตัวอย่างแล้วคอมไพล์ เป็น HEX ไฟล์แล้ว ให้โปรแกรม ลงชิพไมโครคอนโทรลเลอร์
ด้วยเครื่องโปรแกรม JDT-2008
- ตรวจสอบว่ามี IC เบอร์ ICL232 หรือ MAX232 เสียบอยู่บน socket บนบอร์ดทดลองแล้วหรือยัง
ถ้ายังให้ติดต่อขอจากอาจารย์ผู้ควบคุม LAB
- ตรวจสอบว่าได้ถอด IC เบอร์ 75176 ออกแล้วหรือยัง เพราะไม่สามารถใช้งานร่วมกับ
IC เบอร์นี้ได้ เมื่อใช้งาน พอร์ตอนุกรมแบบ RS232
- เมื่อโปรแกรมไมโครชิพเสร็จแล้วให้ถอดสายสัญญาณที่ต่อระหว่าง PC กับ เครื่องโปรแกรมออก
เพราะต้องใช้ พอร์ตอนุกรมนี้ ในการทดลอง โดยต่อสายสัญญาณ ที่ให้มา ด้าน
DB9 เข้ากับ COM1 ของ PC แทนสายสัญญาณ ของเครื่องโปรแกรม แล้วต่อ Connector
3 Pin เข้ากับบอร์ดทดลองดังรูป
|
|
|
|
5. |
ให้ดับเบิ้ลคลิกที่ไอคอน |
|
เพื่อเรียกให้โปรแกรม Hyper Terminal ทำงาน (หากยังไม่ได้ติดตั้งโปรแกรม
Hyper Terminal ให้ทำการติดตั้งก่อน) |
|
|
|
|
|
6. |
จ่ายไฟให้บอร์ดทดลอง แล้วดูผลที่ปรากฏบนหน้าจอโปรแกรม
Hyper Terminal |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ตัวอย่างโปรแกรมการใช้งานพอร์ตอนุกรม |
|
|
|
|
|
EXAM8 |
|
|
;EXAM8.ASM
;Demo Send String to RS232 and Send Char 'A'
;Recive from RS232 and Echo
; Check key press ='h' and say Hello again
ORG 0000H
MAIN: LCALL InitUART ;Initial UART 9600,n,8,1 no parity
;Demo Send char 'A'
MOV A,#'A' ;Send Char 'A'
LCALL SBYTE
MOV A,#0DH ;Send carriage return(Cursor go to Home)
LCALL SBYTE
MOV A,#0AH ;Send Line feed (Next Line)
LCALL SBYTE
;Demo Send String
LCALL SayHello ;Send String in Table
;*** Get Message Loop ***
GetMsg: JB RI,GetByte ;Have Message or not
;do the other program
;...
SJMP GetMsg
GetByte:LCALL RBYTE ;Read -> A
;do something
LCALL SBYTE ;A -> ECHO
XRL A,#'h' ;Test Key 'h'
JZ DataIn
SJMP GetMsg
DataIn: LCALL SayHello ;Out put for test
SJMP GetMsg
;*** END Main ***
InitUART:
MOV SCON,#01010010B ;Set SCON Serial Control Mode 1: 8-bit UART (Timer-Based).
MOV TMOD,#00100000B ;Set Mode 2 8-bit Auto-Reload
MOV TH1,#0FDH ;Set Baud Rate 9600
SETB TR1 ;Enable Timer 1
RET
;
SendStr:
CLR A
MOVC A,@A+DPTR ;load char
SUBB A,#00 ;test end of string
JZ ENDSTR ;yes end
LCALL SBYTE ;send 1 byte
INC DPTR ;point to next char
SJMP SENDSTR ;load next char
EndStr: RET
; ********** SBYTE SUB **********
;SEND BYTE
;IN = A
;REG = NO
SBYTE: JNB TI,SBYTE ;Wait For Sending done
CLR TI
MOV SBUF,A
RET
; ********** RBYTE SUB **********
;OUT = A
;REG = A
RBYTE: JNB RI,RBYTE ;Wait For Receive already
CLR RI
MOV A,SBUF
RET
SayHello:
MOV DPTR,#HELLO
LCALL SENDSTR
RET
hello: DB 0Dh,"*** MCS-51 READY ***",0Dh,0AH,00
END
|
|
|
|
|
|
|
|
|
|
ผลการทดลอง |
|
|
- เมื่อจ่ายไฟให้บอร์ดทดลอง ไมโครคอนโทรลเลอร์จะส่งข้อมูลตัวอักษร A
เพื่อทดสอบ การส่งข้อมูลแบบตัวอัษร (char) |
|
|
และบรรทัดต่อมาจะปรากฏข้อมูลสตริง "***
MCS-51 READY ***" มายังที่ PC เพื่อทดสอบ การส่งข้อมูลแบบสตริง
(string) |
|
|
- เมื่อมีการกดแป้นพิมพ์บน PC ข้อมูลตัวอักษรนั้น ก็จะถูกส่งไปยังไมโครคอนโทรลเลอร์
เมื่อไมโครคอนโทรลเลอร์ ได้รับข้อมูล ตัวอักษรใด ก็จะส่งข้อมูล ตัวอักษรนั้น
กลับมายัง PC (ECHO) |
|
|
- เมื่อกดแป้นพิมพ์ตัว "h" ไมโครคอนโทรลเลอร์
ก็จะส่งข้อมูลสตริง "***
MCS-51 READY ***" มาอีกครั้ง เป็นการศึกษา การปฏิบัติตามคำสั่ง
เบื้องต้น (1 ตัวอักษร) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
รูปผลการทดลองบนหน้าจอของโปรแกรม Hyper Terminal |
|
|
|
|
|
แบบฝึกหัด |
|
|
จากตัวอย่าง EXAM8 ให้เขียนโปรแกรมเพื่อแสดงผลที่ได้รับตัวอักษรจากพอร์ตอนุกรม
(เมื่อกดแป้นพิมพ์บน PC) มาแสดงผลออกทางพอร์ต P1.0 โดยให้ ตรวจสอบข้อมูล
ที่อ่านได้จากแป้นพิมพ์และมาแสดงผลออกทางพอร์ต P1.0 กับ ตาราง
ASCII ว่าถูกต้องหรือไม่ |
|
|
แนวทางปฏิบัติ |
|
|
จากโปรแกรมตัวอย่าง ในบรรทัด |
|
|
|
|
|
GetByte: |
LCALL RBYTE
|
:;Read
-> A |
;do
something |
|
|
|
|
|
|
|
|
- ข้อมูลที่อ่านได้จากพอร์ตอนุกรมจะถูกเก็บไว้ที่
รีจิสเตอร์ A |
|
|
- ดังนั้น ส่วนของโปรแกรม ที่เพิ่มขึ้นมาใหม่ ที่จะนำค่าที่ได้รับจากพอร์ตอนุกรม
มาใช้งานจะแทรกอยู่หลังบรรทัด คอมเมนต์ ;do
something เป็นต้นไป |
|
|
- และเพื่อไม่ให้ค่าที่อยู่ใน
รีจิสเตอร์ A สูญหาย เพราะก็ยังมีส่วนของโปรแกรมหลังจากนั้นต้องใช้งานเช่นกัน
ดังนั้นควรจะเก็บค่าในรีจิสเตอร์ A ไว้ในรีจิสเตอร์ ที่ไม่ได้ใช้งานก่อน เมื่อทำงานเสร็จแล้ว
จึงนำค่าเดิมที่เก็บไว้คืนให้กับรีจิสเตอร์ A เช่น |
|
|
|
|
|
|
MOV R2,A |
;เก็บค่าที่อ่านได้จากพอร์ตอนุกรมที่อยู่ที่รีจิสเตอร์
A ไว้ในรีจิสเตอร์ R2 |
|
. |
|
|
. |
|
|
. |
|
|
MOV A,R2 |
;นำค่าที่เก็บไว้ใน รีจิสเตอร์
R2 คืนให้กับ รีจิสเตอร์ A เพื่อให้โปรแกรมหลังจากนี้ใช้งานต่อไป |
|
|
|
|
|
|
- อย่าลืมว่าค่าที่จะต้องแสดงผลออกทาง P1.0 ที่จะให้ LED แสดงผลจะต้องกลับบิตเพื่อให้การแสดงผลได้ถูกต้อง |
|
|
|
|