Proto Tech - Series
Embedded System ศักดิ์ชัย ผางสําเนียง
เรี ย น-เล น -ใช
ไมโครคอนโทรลเลอร MCS-51 ดวยโปรแกรมภาษาเบสิก µÍ¹·Õè 4 : 㪌 § Ò¹¾Íà µ ÍÔ ¹ ¾Ø µ àÍÒµ ¾Ø µ à¾×èÍÊÌҧâ¤Ã§§Ò¹à¡ÕèÂǡѺ LED Í‹ҧ§‹ÒÂ
¨Ò¡¼ÙŒà¢Õ¹ ผ า นพ น ช ว งเทศกาลป ใ หม ไ ทยบวกกั บ วั น หยุ ด ยาวกั น มา พอสมควร ผมเองไดมีโอกาสไปในสถานที่ทองเที่ยวหลายแหง ให มาสะดุดตากับการตกแตงดวยหลอดไฟวิ่งในลักษณะที่เรียกกัน วา ไฟดาวตก นับเปนไฟประดับที่มีความสวยงามและออนชอย ใน ระหวางที่สมองซีกขวากําลังเอิบอิ่มกับแสงของไฟดาวตก สมอง ซี ก ซ า ยของผมก็ เ ริ่ ม วิ เ คราะห ถึ ง ระบบการทํ า งานของมั น ว า มั น ทํ า งานอย า งไร จนตกผลึ ก มาเป น การทดลองที่ ส ามารถทํ า ได ง า ยๆ บนบอร ด TPE-51 โดยใช โ ปรแกรมภาษาเบสิ ก ที่ พั ฒ นา ดวย Bascom-8051 กอนที่จะทําไฟดาวตกเราควรทําความเขาใจ เกีย่ วกับกับการสัง่ งานพอรตของไมโครคอนโทรลเลอร MCS-51 กันกอน ¡Ò÷´Åͧ·Õ่ 3 ¡ÒÃ㪌 § Ò¹¢Ò¾Íà µ àÍÒµ ¾Ø µ ´Œ Ç Â¡ÒÃµÔ ´ µ‹ Í áºº¾Íà µà¾×่͢Ѻ LED 8 ´Ç§ การทดลองนี้เปนการสั่งงานขาพอรตของไมโครคอนโทรลเลอรใหเปน เอาตพุตและมีการสงผานขอมูลแบบไบตไปยังขาพอรตทั้ง 8 ขาเพื่อควบคุม การเปดปด LED ทั้ง 8 ดวงพรอมกัน (L3.1) ตอวงจรตามรูปที่ L3.-1 หรือจะนําบอรด miniLED8 ที่แนะนํา ใหสรางใน TPE ฉบับนี้มาเสียบเขากับจุดตอ PORT0 ก็ได
66
The Prototype Electronics
รูปที่ L3-1 วงจรสําหรับทดลองใชงาน PORT0 เปนเอาตพุตเพื่อควบคุม LED 8 ดวง (L3.2) เปดโปรแกรม Bascom-8051 ขึ้นมา เขียนโปรแกรมที่ L3-1 บันทึกชื่อเปน OutPort0.bas จากนั้นทําการคอมไพลและดาวนโหลด โปรแกรมลงบอรด TPE-51
โปรแกรมที่ L3-1 ไฟล OutPort0.bas โปรแกรมควบคุ ม พอร ต 0 เปนพอรตเอาตพุตอยางงาย (คําอธิบายโปรแกรมภาษาไทยไมตองพิมพ)
โปรแกรมที่ L4-1 ไฟล BinaryOutPort0.bas โปรแกรมแสดงคาเลขฐาน สองแบบ 8 บิตทีพ่ อรต 0 ของไมโครคอนโทรลเลอร P89V51RD2
$regfile = "89C51RD.DAT"
$regfile = "89C51RD.DAT"
$default Xram
$default Xram
$ramstart = 0
$ramstart = 0
$ramsize = 1024
$ramsize = 1024
$crystal = 11059200
$crystal = 11059200
Lamp Alias P0
Lamp Alias P0 Dim I As Byte
P0
Dim J As Byte
Do Lamp = 0
Do For I = 0 To 255
Waitms 500
J = I
Lamp = 255
J = Not J
Waitms 500
Lamp = J
Loop
Waitms 500 Next
(L3.3) รันโปรแกรมดวยการกดสวิตช RESET หากทุกอยางถูกตอง LED 8 ดวงตองติดดับสลับกันทั้ง 8 ดวง จาก โปรแกรมที่ L3-1 จะเห็นวา มีการใชคําสั่ง Lamp = 0 เพื่อให LED ติดทั้ง 8 ดวง และ Lamp = 255 เพื่อดับLED ทั้ง 8 ดวงเชนกัน ทานอาจ สงสัยวา ทําไมตองใชคําสั่ง Lamp = 255 เพื่อให LED ทั้ง 8 ดวงดับ นั่นเปน เพราะวา MCS-51 เปนไมโครคอนโทรลเลอรขนาด 8 บิต มีพอรตตอใชงาน 3 พอรต แตละพอรตมี 8 ขา ในตัวอยางนี้ใช P0 ซึ่งประกอบดวย P0.0, P0.1 ไลตามลําดับจนถึง P0.7 ดังนั้น เมื่อตองการให LED ติดหมด จึงตองทําใหทุกบิตเปน “0” จึง เขียนคา 0 ไปยังรีจิสเตอรของพอรต 0 และเมื่อตองการให LED ดับหมด จึง ตองทําใหทุกบิตเปน “1” จึงเขียนคา 11111111 ฐานสองหรือ 255 ฐานสิบ หรือ &HFF ไปยังรีจิสเตอรของพอรต 0 ¡Ò÷´Åͧ·Õ่ 4 áÊ´§¤‹ÒàÅ¢°Ò¹Êͧ´ŒÇ LED 8 ´Ç§¼‹Ò¹·Ò§ ¾Íà µ 0 ¢Í§äÁâ¤Ã¤Í¹â·ÃÅàÅÍà MCS-51 จากการทดลองที่แลวทําใหเราทราบถึงการสั่งงานขาพอรตแบบงายๆ กันแลว เพื่อใหเขาใจการทํางาน ในระบบการนับเลข และสั่งงานไปยังขาพอรตดวยคาของขอมูลที่มี ความหลากหลายมากขึ้น ในการทดลองนี้จะทําการนับเลข 0 ถึง 255 แลว นําไปแสดงผลที่พอรต 0 ในรูปแบบของเลขฐานสอง
Loop
(L4.3) รันโปรแกรมดวยการกดสวิตช RESET หากทุกอยางถูกตอง LED 8 ดวงต อ งติ ด หรื อ ดั บ เพื่ อ แสดงค า ของเลขฐานสอง 8 บิ ต ตั้ ง แต 00000000 ถึง 11111111 ซึ่งเทากับ 0 ถึง 255 ในเลขฐานสิบ จากการทดลองนี้ โปรแกรมจะนับคาตัวเลขฐานสิบ โดยเริ่มจากให ตัวแปร I เปน 0 และเพิ่มขึ้นครั้งละหนึ่งจนถึง 255 ในแตละครั้งที่คาเพิ่ม ขึ้นจะนําไปแสดงที่พอรต P0 ในรูปแบบเลขฐานสอง โดยมีตัวแปร J ทํา หนาที่กลับสถานะใหแสดงผลเปนเลขฐานสองอยางถูกตอง นั่นคือ LED ติดหมายถึงขอมูล “1” และ LED ดับคือ ขอมูล “0” ทั้งนี้เนื่องจากการขับ LED ที่ P0 เปนการขับแบบแอกตีฟลอจิก “0” หรือขับแบบกระแสซิงก หาก ไมมีการสลับคาการแสดงผลที่ LED จะมีผลกลับกัน นั่นคือ LED จะดับเมื่อ ขอมูลเปน “1” และ LED ติดเมื่อขอมูลเปน “0” ¡Ò÷´Åͧ·Õ่ 5 ½¹´Òǵ¡Í‹ҧ§‹Ò มาถึงเปาหมายของผมเสียที นั่นคือ การทดลองสรางวงจรฝนดาวตก แบบงายๆ ครับ วงจรยังคงใชแบบเดียวกับการทดลองที่ผานมาในรูปที่ L3-1 (L5.1) เปดโปรแกรม Bascom-8051 ขึ้นมา เขียนโปรแกรมที่ L5-1 บันทึกชื่อเปน MeteorShower.bas จากนั้นทําการคอมไพลและดาวนโหลด โปรแกรมลงบอรด TPE-51
(L4.1) ยังคงใชวงจรในรูปที่ L3.-1 ในการทดลอง (L4.2) เปดโปรแกรม Bascom-8051 ขึ้นมา เขียนโปรแกรมที่ L4-1 บันทึกชือ่ เปน BinaryOutPort0.bas จากนัน้ ทําการคอมไพลและดาวนโหลด โปรแกรมลงบอรด TPE-51
The Prototype Electronics
67
Embedded : Basic-51 Course
โปรแกรมที่ L5-1 ไฟล MeteorShower.bas โปรแกรมขับ LED ที่ พอรต P0 ของไมโครคอนโทรลเลอร P89V51RD2 ใหทํางานในรูป แบบฝนดาวตก $regfile = "89C51RD.DAT" $default Xram $ramstart = 0 $ramsize = 1024 $crystal = 11059200 Lamp Alias P0 Dim I As Byte Dim J As Byte Dim K As Byte Do J = &B00000001 Lamp = &B11111110 Waitms 300 For I = 0 To 7 Shift J , Left , 1 K = Not
J
Lamp = K Waitms 300 Next Loop
(L5.2) รันโปรแกรม จะเห็น LED ติดไลทีละดวงจากขา P0.0 คลายๆ กับฝนดาวตก เราสามารถปรับอัตราเร็วในการแสดงผลไดจากการเปลี่ยน คาเวลาที่คําสั่ง Waitms รวมถึงกําหนดรูปแบบการแสดงผลตั้งตนดวยการ กําหนคาของตัวแปร J และ Lamp ซึ่งตองกําหนดใหสัมพันธกันดวย อาทิ หากกําหนดคา J เทากับ 00000011 คาของ Lamp ตองเปน 11111100 เปนตน หากสังเกตจะพบวา คาของ Lamp จะเปนคาที่ตรงขามกับ J เสมอ ตัวอยางนี้มีคําสั่งใหม 2 คําสั่งคือ Shift และ For…Next สําหรับคําสัง่ แรกนัน้ คือคําสัง่ Shift โครงสรางของคําสัง่ ซึง่ เปนการเลือ่ นบิต ประกอบดวย Shift [ตัวแปรทีต่ อ งการ] , [LEFT ซาย หรือ RIGHTT ขวา] , [ จํานวน การเลือ่ นบิต ] สํ า หรั บ คํ า สั่ ง For..Next เป น การวนรอบแบบหนึ่ ง ต า งจาก Do…Loop ตรงทีเ่ ราสามารถกําหนดไดวา ใหวนรอบกีค่ รัง้ จึงจะออกจากลูป เช น จากตั ว อย า งโปรแกรมฝนดาวตกจะมี ก ารวนรอบอยู 8 ครั้ ง คือ จาก 0 ถึง 7 จากนั้นจึงออกจากลูปแลววนกลับไปทําซํ้าในตําแหนง หลัง Do กอนทีจ่ ะมาวนทํางานใน For …Next อีกครัง้ ¡Ò÷´Åͧ·Õ่ 6 ¢Ñº LED µÑÇàÅ¢ 7 ʋǹ ในการทดลองเพื่อใชงานพอรตเอาตพุตแบบไบตนั้นหากขาดการ ทดลองขับ LED ตัวเลข 7 สวนก็คงจะไมสมบูรณเปนแนแท LED ตัวเลข 7 สวนประกอบขึ้นจาก LED จํานวน 7 ตัวที่บรรจุอยูใน ตัวถังเดียวกันและไดรับการจัดเรียงเปนรูปตัวเลข LED แตละตัวจะถูกเรียก วา สวน หรือ เซกเมนต (segment) แตละสวนหรือเซกเมนตมีชื่อเรียกแตก ตางกันตามตําแหนงที่ไดรับการจัดวางคือ a, b, c, d, e, f และ g ดังแสดงใน รูปที่ L6-1 สวน dp เปน LED อีก 1 ตัวที่บรรจุอยูใน LED ตัวเลข 7 สวนนี้ใช เปนตัวแสดงจุดทศนิยมในกรณีที่มีการแสดงผลในลักษณะเลขที่มีทศนิยม 68
The Prototype Electronics
รูปที่ L6-1 รูปราง, การกําหนดชื่อเซกเมนตตางๆ, การจัดขา และชนิดของ LED ตัวเลข 7 สวน LED ตัวเลข 7 สวนมี 2 แบบคือ 1. แบบแคโทดรวม (common cathode) เปนการตอขาแคโทด ทั้งหมดของ LED เขาดวยกัน แลวขับ LED ใหสวางดวยการปอนสัญญาณ ลอจิก "1" เขาที่ขาแอโนดของแตละเซกเมนตตั้งแต a ถึง g และ dp (จุด) ไมโครคอนโทรลเลอรตองขับ LED แบบนี้ดวยวิธีการขับแบบกระแสซอรส 2. แบบแอโนดรวม (common anode) เปนการตอขาแอโนด ทั้งหมดของ LED เขาดวยกัน แลวขับ LED ใหสวางดวยการปอนสัญญาณ ลอจิก “0” เขาที่ขาแคโทดแทน ซึ่งตรงขามกับแบบแคโทดรวม ไมโคร คอนโทรลเลอรตองขับ LED แบบนี้ดวยการขับแบบกระแสซิงก จึงแนะนํา ใหเลือกใช LED ตัวเลข 7 สวนแบบนี้กับไมโครคอนโทรลเลอร MCS-51 สํ า หรั บ การเชื่ อ มต อ ไมโครคอนโทรลเลอร P89V51RD2 เพื่ อ ขั บ LED ตัวเลข 7 สวนมีวงจรตัวอยางแสดงในรูปที่ L6-2 โดยตอขาพอรต P0.0 เขาที่ขาเซกเมนต a ไลไปตามลําดับจนถึงขา P0.6 ตอกับขาเซก เมนต g และตอขา P0.7 เขากับขาของเซกเมนต dp หรือจุด ที่ขารวมหรือ common ของ LED ตัวเลข 7 สวนจะตอกับวงจรทรานซิสเตอร BC557 ซึ่ง เปนทรานซิสเตอรแบบ PNP มีการตอขาเบสของทรานซิสเตอรเขากับตัว ตานทานจํากัดกระแสลงกราวด ทําใหทรานซิสเตอร BC557 ทํางานทันทีที่ มีการจายไฟเลี้ยงใหวงจร สวน LED ตัวเลข 7 สวนจะติดสวางอยางไรขึ้นกับ ขอมูลหรือสัญญาณลอจิกที่ปอนใหแกขาเซกเมนต a ถึง g และ dp การกําหนดให LED ตัวเลข 7 สวนแสดงขอมูลเปนตัวเลขหรือเปน สัญลักษณใดๆ ก็ตาม ตองมีการกําหนดรูปแบบการแสดงผลของเซกเมนต ตางๆ ดวยขอมูลแตละบิตของไมโครคอนโทรลเลอรแลวใชวิธีการเปดตาราง หรือ look up table ดังแสดงตัวอยางตารางขอมูลของการแสดงผลตัวเลข ฐานสิบหกของ LED ตัวเลข 7 สวนในตารางที่ L6-1
จากโปรแกรมที่ L6-1 เป น การวนทํ า งานเพื่ อ นํ า ค า ที่ อ ยู ใ นตาราง 7segment ออกมาแสดง โดยใช คํ า สั่ ง S = Lookup(i , 7segment) เนื่องจาก LED ตัวเลข 7 สวนมี 2 แบบคือ แคโทดรวมและแอโนดรวม จึง ต อ งมี ก ารกํ า หนดเงื้ อ นไขเล็ ก น อ ยเพื่ อ เลื อ กข อ มู ล ที่ เ หมาะสมไปแสดง ผล ในบรรทัด S = Not S เปนการกลับสถานะของขอมูลที่ไดจากตาราง 7segment ของโปรแกรมเพื่อใหใชกับ LED แบบแอโนดรวม แตถาหาก นําไปใชกับ LED ตัวเลข 7 สวนแบบแคโทดรวมใหตัดคําสั่งในบรรทัด S = Not S ออกไป โปรแกรมที่ L6-1 ไฟล 7segPort0.bas โปรแกรมขับ LED ตัวเลข 7 สวนแบบแอโนดรวมที่พอรต P0 ของไมโครคอนโทรลเลอร P89V51RD2 ใหทํางานในรูปแบบฝนดาวตก รูปที่ L6-2 วงจรเชื่อมตอไมโครคอนโทรลเลอร P89V51RD2 สําหรับทดลอง ใชงาน PORT0 เปนเอาตพุตเพื่อขับ LED ตัวเลข 7 สวนแบบแอโนดรวม
$regfile = “89C51RD.DAT” $default Xram $ramstart = 0 $ramsize = 1024 $crystal = 11059200 Dim I As Byte Dim S As Byte 7s Alias P0 Do For I = 0 To 16 S = Lookup(i , 7segment) S = Not S 7s = S Wait 1 Next Loop 7segment: Data &H3F Data &H06 Data &H5b Data &H4f Data &H66 Data &H6d Data &H7d
ตารางที่ L6-1 ตารางขอมูลของการแสดงผลตัวเลข 0-F ของ LED ตัวเลข 7 สวนแบบแอโนดรวม
Data &H27 Data &H7F Data &H6F
(L6.1) ตอวงจรในรูปที่ L6-3 เพื่อใชในการทดลอง หรือจะนําบอรด miniDisplay1 ที่ แ นะนํ า ให ส ร า งใน TPE ฉบั บ นี้ ม าเสี ย บเข า กั บ จุ ด ต อ PORT0 ก็ได (L6.2) เปดโปรแกรม Bascom-8051 ขึ้นมา เขียนโปรแกรมที่ L6-1 บันทึกชื่อเปน 7segPort0.bas จากนั้นทําการคอมไพลและดาวนโหลด โปรแกรมลงบอรด TPE-51 (L6.3) ทําการรันโปรแกรม จะเห็น LED ตัวเลข 7 สวนแสดงคาตัวเลข 0 ถึง F และจุด dp รวม 17 แบบ แลววนกลับมาที่ 0 ใหม
Data &H77 Data &H7C Data &H39 Data &H5E Data &H79 Data &H71 Data &H80
The Prototype Electronics
69
Embedded : Basic-51 Course
¡Ò÷´Åͧ·Õ่ 7 à¡ÁÅ١ൎÒẺµÑÇàÅ¢ ในระหว า งที่ ผ มกํ า ลั ง เขี ย นโปรแกรมเพี่ อ ทดลองขั บ LED ตั ว เลข 7 สวน ก็เกิดปง แวบกับไอเดียการทําของเลนแบบขําๆ นัน่ คือ การทําเกม ลูกเตาตัวเลขเสีย่ งทายแบบงายๆ โดยใชพนื้ ฐานมาจากการทดลองที่ 6 เพียง เพิม่ สวิตชกดติดลปอยดับเขาไปอีกหนึง่ ตัว ก็จะไดวงจรทดลองดังรูปที่ L7-1
รู ป ที่ L7-1 วงจรทดลองสํ า หรั บ สร า งเป น เกมลู ก เต า ตั ว เลขเสี่ ย งทาย อิเล็กทรอนิกส (L7.1) ตอวงจรในรูปที่ L7-1 เพื่อใชในการทดลอง หรือจะนําบอรด miniDisplay1 ที่ แ นะนํ า ให ส ร า งใน TPE ฉบั บ นี้ ม าเสี ย บเข า กั บ จุ ด ต อ PORT0 และ miniButton ตอเขาที่จุดตอ PORT2 โดยอาจเลือกตอเฉพาะ P2.0 ก็ได (L7.2) เปดโปรแกรม Bascom-8051 ขึ้นมา เขียนโปรแกรมที่ L7-1 บันทึกชื่อเปน 7segDice.bas จากนั้นทําการคอมไพลและดาวนโหลด โปรแกรมลงบอรด TPE-51 (L7.3) รันโปรแกรม แลวทดลองกดสวิตช S2 ที่พอรต P2.0 จะเห็น LED ตัวเลข 7 สวนแสดงคาตัวเลข 0 ถึง 9 ออกมาคาหนึ่ง และจะเปลี่ยนไป ในทุกครั้งที่กดสวิตชที่พอรต P2.0
โปรแกรมที่ L7-1 ไฟล 7segPort0.bas โปรแกรมขับ LED ตัวเลข 7 สวนแบบแอโนดรวมที่พอรต P0 ของไมโครคอนโทรลเลอร P89V51RD2 ใหทํางานในรูปแบบฝนดาวตก $regfile = "89C51RD.DAT" $default Xram $ramstart = 0 $ramsize = 1024 $crystal = 11059200 Dim S As Byte 7s Alias P0 Sw Alias P2.0 Do Debounce Sw , 0 , Random , Sub Loop Random: S = Rnd(9) S = Lookup(s , 7segment) S = Not S 7s = S Return 7segment: Data &H3F Data &H06 Data &H5b Data &H4f Data &H66 Data &H6d Data &H7d Data &H27 Data &H7F Data &H6F Data &H77 Data &H7C Data &H39 Data &H5E Data &H79 Data &H71 Data &H80
จากโปรแกรมที่ L7-1 การทํางานในสวนของการอานคาจากตารางใช หลักการเดียวกับโปรแกรมที่ L6-1 มีคําสั่งใหมเพิ่มเขามาในโปรแกรม นั่น คือ คําสั่ง RND เปนคําสั่งสุมตัวเลข มีโครงสรางดังนี้ ตัวแปรรับขอมูล = RND(คาขอบเขตดานสูงของการสุมตัวเลข) ตัวอยาง S = Rnd(9) หมายถึง เมื่อทําการสุมตัวเลข 0 ถึง 9 แลว นํา คาที่ไดเก็บไวในตัวแปร S www.tpemagazine.com
70
The Prototype Electronics
พอหอมปากหอมคอนะครับ สําหรับตัวอยางการทดลองใชงานพอรต เอาตพุตของไมโครคอนโทรลเลอร MCS-51 ที่นําเสอนผานตัวอยางแอป พลิเคชั่นอยางงายที่นําไปตอยอดไดจริง แลวพบกันตอนหนากับเรื่องราว ของการขับโมดูล LCD 16 ตัวอักษร 2 บรรทัดดวยโปรแกรมภาษาเบสิกกับ BASCOM-8051