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 เส้น  
     
     
  วิธีการทดลอง  
 
  1. เมื่อ download ตัวอย่างแล้วคอมไพล์ เป็น HEX ไฟล์แล้ว ให้โปรแกรม ลงชิพไมโครคอนโทรลเลอร์ ด้วยเครื่องโปรแกรม JDT-2008
  2. ตรวจสอบว่ามี IC เบอร์ ICL232 หรือ MAX232 เสียบอยู่บน socket บนบอร์ดทดลองแล้วหรือยัง ถ้ายังให้ติดต่อขอจากอาจารย์ผู้ควบคุม LAB
  3. ตรวจสอบว่าได้ถอด IC เบอร์ 75176 ออกแล้วหรือยัง เพราะไม่สามารถใช้งานร่วมกับ IC เบอร์นี้ได้ เมื่อใช้งาน พอร์ตอนุกรมแบบ RS232
  4. เมื่อโปรแกรมไมโครชิพเสร็จแล้วให้ถอดสายสัญญาณที่ต่อระหว่าง 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
 
 
DOWNLOAD
 
     
  ผลการทดลอง  
  - เมื่อจ่ายไฟให้บอร์ดทดลอง ไมโครคอนโทรลเลอร์จะส่งข้อมูลตัวอักษร 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 แสดงผลจะต้องกลับบิตเพื่อให้การแสดงผลได้ถูกต้อง