[ บทความ : Robot ] ตอนที่ 4 เรื่อง ... ศึกษา ET-ROBOT (ET-BS2P40 และเครื่องหมายดำเนินการ)

 

ในบทความตอนที่แล้วนั้นผมได้อธิบายถึงเรื่องตัวแปร โดยอ้างอิงจาก BASIC Stamp ตระกูล BS2SX ซึ่งผมเองไม่มั่นใจว่า โครงสร้างของหน่วยความจำใน BS2SX กับ BS2p40 นั้นจะแตกต่างกันหรือไม่ … จากการอ่านเอกสาร และทดลองกับบอร์ดทดลองรุ่น ET-BS2p40 ที่ทาง ETT ส่งมาให้ผมทดลองใช้ เพื่อประกอบการเขียนบทความ ก็ได้ข้อสรุปที่บอกได้ว่า มันเหมือนกับ BS2SX และก็แตกต่างอยู่บ้าง (เพียงเล็กน้อย) … เอาล่ะ ก่อนที่จะเรียนรู้เรื่องของเครื่องหมายดำเนินการ เรามาทำความรู้จักบอร์ด ET-BS2p40 กันก่อนดีกว่าครับ ต้องขออภัยคนที่ใช้ BS2SX ด้วยนะครับ จริงๆแล้วผมเองก็มีบอร์ดรุ่นนี้อยู่ แต่ผมได้ทดลองต่อกับวงจรของ Stepping motor แล้วเกิดความผิดพลาด ทำให้ BS2SX ของส่งเสียงร้องประกอบกับมีควันพวยพุ่งขึ้นมาอีกต่างหาก … ฮาๆ .. (ส่วนใครว่าผมชอบโฆษณาก็ต้องทำใจล่ะกันนะ)

 

ET-BS2P40

บอร์ดรุ่นนี้เป็นบอร์ดที่ใช้ไอซี BASIC Stamp 2 p40 เป็นตัวประมวลผล ซึ่งมีความสามารถตามที่ได้เขียนกันไปแล้วในบทความตอนแรก ส่วนความแตกต่างจาก BS2SX ในเรื่องของสถาปัตยกรรมก็คือ มีขาเพิ่มเข้ามาอีก 16 ขา ซึ่งทั้งหมดนี้เป็น I/O ที่เพิ่มเข้ามา … ขาทั้งสิบหกขานี้มีชื่อเรียกว่า AUX0, AUX1, …, AUX15 นั่นหมายความว่า นอกเหนือจาก P0,P1,..,P15 แล้วเราก็สามารถใช้งาน AUX0, .., AUX15 ได้อีกด้วย ซึ่งการที่จะใช้งานขาเหล่านี้ได้นั้น เราจะต้องสั่งงานเพิ่มเติมคือ ต้องเรียกคำสั่ง AUXIO ก่อนที่จะมีการติดต่อกับขานั้นๆ (ตัวอย่างค่อยเอาไว้ตอนหน้าล่ะกันนะครับ)

 ความแตกต่างอีกเรื่องหนึ่งคือ ปริมาณของหน่วยความจำของส่วน Scratch Pad นั้น จะมีขนาด 128 ไบต์ ทำให้เราสามารถใช้คำสั่ง Get/Put ได้มากขึ้น ซึ่งแน่นอนว่า เราจะสามารถใช้งานได้เพียง 127 ไบต์เท่านั้น เพราะต้องใช้ 1 ไบต์สำหรับเก็บค่าของหมายเลขเพจของหน่วยความจำโปรแกรม ที่กำลังใช้งานอยู่ (ยังจำได้ไหมเอ่ยว่า BS2 มันมีหน่วยความจำโปรแกรมได้ 16 KB แต่ถูกแบ่งเป็น 8 ก้อน และแต่ละก้อนมีขนาด 2KB ซึ่งก้อนเหล่านี้เราเรียกว่า เพจ)

 เอาล่ะ สรุปได้ว่า BS2p40 นั้นมีความสามารถแตกต่างกับ BS2SX ดังที่ผมได้อธิบายมา ส่วนบอร์ด ET-BS2p40 นั้น มีหน้าตาดังนี้ครับ

มาดูเรื่องการเขียนโปรแกรมกันต่อเถอะครับ :)

 

เครื่องหมายดำเนินการ

 เครื่องหมายดำเนินการ คืออะไรเอ่ย ? … จำโปรแกรมของบทความที่แล้วได้ไหมครับ ที่ผมเขียนว่า 

width=10

height=$A

area = width*height

 ถ้าดูกันให้ละเอียด จะพบว่า เรามีส่วนที่เป็นตัวแปร กับส่วนที่เป็นเครื่องหมาย เจ้าเครื่องหมายเหล่านี้ เราจะเรียกชื่อของมันว่า เครื่องหมายดำเนินการ (Operator) ซึ่งแต่ละเครื่องหมายนั้น ก็จะมีหน้าที่แตกต่างกันออกไป ตัวอย่างเช่น เครื่องหมาย = ที่เราพบจากโปรแกรมทั้ง 3 บรรทัด ก็ถือว่าเป็นเครื่องหมายดำเนินการ … หน้าที่ของเครื่องหมายนี้คือ นำค่าจากทางขวา มาใส่ในตัวแปรทางด้านซ้าย … และเจ้าเครื่องหมาย * นั้น ก็เป็นเครื่องหมายแทนการคูณ ดังนั้น เมื่อ BASIC Stamp เจอคำสั่ง width*height มันก็จะนำค่าที่เก็บในตัวแปร width มาคูณกับค่าในตัวแปร height แล้วนำผลลัพธ์จากการคูณนี้ไปเก็บในตัวแปรที่อยู่ทางซ้ายมือของเครื่องหมาย =  ก็เป็นการจบกระบวนการทำงานของคำสั่ง area = width*height

แล้วเครื่องหมายดำเนินการมีกี่ประเภทล่ะ อืม คำถามนี้ตอบง่ายๆ ว่า มีหลายประเภทครับ (ฮาๆ)  เอาเป็นว่า เท่าที่จะใช้กันก็ได้แก่ เครื่องหมายถ่ายค่า (ก็เจ้า = ไง), เครื่องหมายสำหรับคำนวณ, เครื่องหมายสำหรับกระทำทางตรรกะ และเครื่องหมายเปรียบเทียบ มาดูทีละกลุ่มนะ

 

เครื่องหมายสำหรับคำนวณ

เครื่องหมาย

ความหมาย

+

แทนการบวก

-

แทนการลบ

*

แทนการคูณเลข โดยให้ผลลัพธ์เป็นตัวเลขแบบ 16 บิต

**

แทนการคูณ แล้วให้ผลลัพธ์เป็นเลขแบบ 16 บิต แต่ว่าเลขนี้เป็นเลขของ 16 บิตสูง หรือบิตที่ 15-21

*/

แทนการคูณ แล้วคืนค่าผลลัพธ์ในเลข16 บิต แต่ตัวเลขเป็นตัวเลขจากบิตตรงกลางของผลลัพธ์

/

แทนการหาร

//

แหทนการหาร แบบเอาเศษ (สนใจแต่เศษจากการหาร)

 มาดูตัวอย่างกันดีกว่าครับ จะได้เข้าใจมากขึ้น

'{$STAMP BS2p}

'{$PORT COM1}

I var WORD

J var WORD

K var WORD

I = 10000

J = 100

K = I + J

DEBUG  "K=I+J, ", dec ? K

K= I-J

DEBUG "K=I+J, ", dec ? K

K = I*J

DEBUG "K=I*J, ", "K=",dec K, " or (", bin K, ") base 2",CR

K = I**J

DEBUG "K=I**J, ", "K=",dec K, " or (", bin K, ") base 2",CR

K = I*/J

DEBUG "K=I*/J, ", "K=",dec K, " or (", bin K, ") base 2",CR

I = 10

J = 3

K = I/J

DEBUG "K=I/J, ", dec ? K

K = I//J

DEBUG "K=I//J, ", dec ? K

END 

 

ผลของการทำงานเป็นดังนี้ครับ

 

เอาล่ะ มาดูเฉพาะส่วนที่น่าสนใจกันดีกว่าครับ คำสั่งแรกที่เพิ่มเติมจากคราวที่แล้วคือ

DEBUG  "K=I+J, ", dec ? K

ตรงที่เขียนว่า dec ? K มีความหมายว่า ให้แสดงข้อความว่า K = และตามด้วยข้อความแบบตัวเลขของตัวแปร L ดังนั้นที่จอภาพจึงแสดงข้อความว่า K=I:J, K = 10100

มาดูเรื่องการคูณแบบธรรมดากันก่อนครับ เนื่องจากเราใช้ K=I*J โดยที่ I=10000 และ J=100 ผลของการคูณนั้น จะได้ 100000 แต่ถ้าเขียนเป็นเลขฐานสอง ก็จะได้ผลลัพธ์เป็น (00000000000011110100001001000000)2 แต่การคำนวณนั้นคืนค่าเพียง 16 บิต มันเลยแสดงผลเพียง (0100001001000000)2 ซึ่งก็คือ 16960

เมื่อเราเปลี่ยนคำสั่งมาเป็น K=I**J ด้วยเหตุนี้ผลลัพธ์จึงเป็น (0000000000001111)2 แต่เลข 0 ด้านหน้านั้นไม่มีความหมาย BASIC Stamp จึงตอบคำตอบออกมาเป็น (1111)2 หรือ 15

หลังจากนั้น เมื่อเปลี่ยนคำสั่งเป็น K=I/*J ซึ่งเครื่องหมาย /* นั้นจะให้คำตอบเป็นเลข 16 บิต ที่เกิดจากการนำบิตตรงกลางของผลลัพธ์มาใช้ ดังนั้น คำตอบจึงเป็น (0000111101000010)2 หรือ 3906

ส่วนคำสั่งที่เขียนว่า

DEBUG "K=I*J, ", "K=",dec K, " or (", bin K, ") base 2",CR

คำว่า ,CR นั้น มีความหมายว่าให้แสดง ASCII 13 หรือขึ้นบรรทัดใหม่ ซึ่งเมื่อคราวที่แล้วเราสั่งขึ้นบรรทัดใหม่ด้วย ,13 … พอจะจำได้ไหมครับ

 

คราวนี้มาดูคำสั่งหารกันบ้าง

I = 10

J = 3

K = I/J

DEBUG "K=I/J, ", dec ? K

K = I//J

DEBUG "K=I//J, ", dec ? K

จากบรรทัดที่เขียนว่า K=I/J ผลการคำนวณที่ตอบออกมาว่าเป็น 3 แทนที่จะเป็น 3.3333…3 นั้นเนื่องมาจากว่า BASIC Stamp ไม่มีความสามารถคำนวณค่าตัวเลขทศนิยมได้นั่นเอง ดังนั้น มันจึงตัดเศษทิ้งไป คำตอบที่ได้หลังจากตัดเศษ จึงเป็น 3 ไงล่ะครับ แต่ถ้าเราต้องการทราบว่าเศษจากการหารนั้นเป็นเท่าไร เราก็สั่งว่า K=I//J เพียงเท่านี้เราก็ได้รู้แล้วเศษจากการหารนั้น ก็คือ 1 นั่นเอง

  

เครื่องหมายสำหรับกระทำทางตรรกะ

เครื่องหมาย

ความหมาย

&

กระทำการ AND

    1 AND 0 ได้ 0

    1 AND 1 ได้ 1

    0 AND 0 ได้ 0

    0 AND 1 ได้ 0

|

กระทำการ OR

    1 OR 0 ได้ 1

    1 OR 1 ได้ 1

    0 OR 0 ได้ 0

    0 OR 1 ได้ 1

^

กระทำการ XOR

    1 XOR  0  ได้  1

    1 XOR 1 ได้ 0

    0 XOR 0 ได้ 0

    0 XOR 1 ได้ 1

~

กระทำการ 1’s complement

~1  ได้ผลลัพธ์เป็น 0

~0 ได้ผลลัพธ์เป็น 1

<<

เลื่อนบิตไปทางซ้าย

>>

เลื่อนบิตไปทางขวา

 

มาดูตัวอย่างโปรแกรมและผลลัพธ์ของการทำงานกันดีกว่าครับ

'{$STAMP BS2p}

'{$PORT COM1}

I var BYTE

J var BYTE

K var BYTE 

I = %10110001

J = %01110011 

K = I & J

DEBUG bin I, " and ", bin J, " = ", bin K,CR

K = I | J

DEBUG bin I, "  or ", bin J, " = ", bin K,CR

K = I ^ J

DEBUG bin I, " xor ", bin J, " = ", bin K,CR

K=~I

DEBUG "not ", bin I, " = ", bin K, CR

K=I<<1

DEBUG bin I, " << 1 = ", bin K,cr 

END

 

เนื่องจากโปรแกรมนั้นไม่มีความซับซ้อนอะไรมากมาย ผมขอไม่อธิบายโปรแกรมล่ะกันครับ ลองดูผลลัพธ์เปรียบเทียบกันดูเองล่ะกันครับ … อย่าหลงตัวเลขนะครับ เพราะผมกำหนดให้ J=%01110011 เนื่องจากนำหน้าด้วย 0 เวลาแสดงผล BASIC Stamp มันไม่แสดงให้เราเห็น พอดูแบบผ่านๆ มันจะมึนนิดๆ

 

เครื่องหมายเปรียบเทียบ

เครื่องหมาย

ความหมาย

=

เปรียบเทียบความเท่ากัน คือ ถ้าค่าทางขวา เท่ากับค่าทางซ้าย จะคืนค่าเป็น 1 แต่ถ้าไม่ใช่ก็จะคืนค่าเป็น 0

<>

เปรียบเทียบความไม่เท่ากัน คือ ถ้าค่าทางขวา ไม่เท่ากับค่าทางซ้าย จะคืนค่าเป็น 1 แต่ถ้าไม่ใช่ก็จะคืนค่าเป็น 0

<

เปรียบเทียบความน้อยกว่า คือ ถ้าค่าทางซ้ายน้อยกว่าค่าทางขวาจะคืนค่าเป็น 1 แต่ถ้าไม่ก็จะคืนค่าเป็น 0

>

เปรียบเทียบความมากกว่า คือ ถ้าค่าทางซ้ายมากกว่าค่าทางขวาจะคืนค่าเป็น 1 แต่ถ้าไม่ก็จะคืนค่าเป็น 0

<=

เปรียบเทียบความน้อยกว่าหรือเท่ากัน คือ ถ้าค่าทางซ้ายน้อยกว่าหรือเท่ากับค่าทางขวาจะคืนค่าเป็น 1 แต่ถ้าไม่ก็จะคืนค่าเป็น 0

>=

เปรียบเทียบความมากกว่าหรือเท่ากัน คือ ถ้าค่าทางซ้ายมากกว่าหรือเท่ากับค่าทางขวาจะคืนค่าเป็น 1 แต่ถ้าไม่ก็จะคืนค่าเป็น 0

 

เนื่องจากเครื่องหมายดำเนินการในกลุ่มนี้ต้องใช้กับคำสั่งเปรียบเทียบ ดังนั้น ผมขอไม่กล่าวถึงในตอนนี้ล่ะกันครับ

 

สรุป

 

เอาล่ะ เราได้เรียนรู้ตัวอย่างการทำงานของเครื่องหมายดำเนินการเป็นที่เรียบร้อยแล้ว  ในตอนต่อไป เราจะมาศึกษาการเขียนโปรแกรมแบบมีเงื่อนไข พร้อมกับทดสอบเรื่องการรับข้อมูลจาก I/O กันครับ .. ส่วนตอนนี้ก็ขอพักผ่อนก่อนนะครับ เพราะตอนนี้ปาเข้าไปเกือบๆ ตีหนึ่งแล้ว … อูย ย ย ย ง่วง

 


เขียนโดย : ศุภชัย บุศราทิจ
Author : Supachai Budsaratij
e-mail : raek@se-ed.net
วันที่ทำการปรับปรุง : ๑๒ ต.ค. ๒๕๔๖