HTG2.club
Home Theater Guide webboard => มุม Thai DIY Audio => ข้อความที่เริ่มโดย: พสิษฐ์ ที่ 02 พฤษภาคม, 2006, 07:01:28 pm
-
สวัสดีครับ
จากเจตนารมณ์ของผมที่ต้องการส่งเสริมการสร้างสรรค์งานด้วยตัวเองในเชิงวิชาที่เกี่ยวข้องกับการออกแบบวงจรดิจิตอล และการเขียนโปรแกรม ผมจึงตั้งหัวข้อนี้เพื่อสนองเจตนารมณ์ของผม ซึ่งในหัวข้อนี้ผมจะพูดถึงการออกแบบวงจรและการเขียนโปรแกรมสำหรับควบคุม CD-Rom ซึ่งเป็นงานที่ผมได้พัฒนามานานและมีความถนัด ผมจึงหวังว่าน่าจะให้คำแนะนำและอธิบายการสร้างได้อย่างเข้าใจต่อท่านผู้สนใจ
ในการสอนครั้งนี้ ผมจะใช้วงจรที่ผมได้ออกแบบขึ้นใหม่ (ดังรูป) เพื่อการอ้างอิง Ports ต่าง ๆ MCU ที่เป็นเลือกใช้เป็น AT89c52, จอแสดงผล ผมเลือกใช้แบบ 16 x 2 ที่เป็นไปตามมาตรฐาน H44780 เพราะหาซื้อง่ายครับ
-
ข้อควรรู้เกี่ยวกับ AT89c52 ที่จำเป็นสำหรับการใช้งานในงานนี้ครับ
MCU AT89c52 นี้มี 4 ports รับส่งข้อมูลขนาด 8 bits ส่งสำคัญที่ต้องระวังในการใช้ ports เหล่านี้ คือ ที่ Port0 หรือ P0 ไม่มี Internal Pullup ถ้าต้องการใช้ Port นี้รับส่งข้อมูลต้องต่อ External Pullup ความหมายก็คือ ต้องมี R ต่อระหว่างไฟ +5v กับ ขาทั้ง 8 ขาของ Port0 ค่าประมาณ 10k ใช้ได้ครับ หรือจะใช้ R-Net 10k ก็ได้ ซึ่งมีขนาดเล็กกว่า R รวมกัน 8 ตัว
ที่ Port ทั้ง 4 ports จะสามารถแสดงสถานะได้ 2 แบบ Drain และ High Impedance ซึ่งการโปรแกรมให้ Port อยู่ในสถานะ Drain ก็คือการให้ค่า 0 กับ Address ของ Port นั้น ๆ เช่น ถ้าผมต้องการให้ Port3 ทั้ง 8 บิต อยู่ในสถานะ Drain ผมต้องใช้คำสั่ง
mov P3, #0h*
ซึ่งถ้านำ Volt Meter วัดที่ขาทั้ง 8 ขาของ Port3 จะได้ประมาณ 0 Volt
ในทำนองเดียวกัน ถ้าผมต้องการให้ Port3 อยู่ในสถานะ High Impedance ทั้ง 8 บิต ผมจะใช้คำสั่ง
mov P3, #0FFh**
เช่นกันถ้านำ Volt Meter วัดที่ขาทั้ง 8 ขาของ Port3 จะได้ประมาณ 5 Volt
แต่ถ้าผมต้องการ Drain บิตที่ 3 ของ Port2 เท่านั้น ผมจะใช้คำสั่ง
clr P2.3
ในทางกลับกัน ถ้าผมต้องการให้บิตที่ 4 ของ Port0 เป็น High Imp. ผมจะใช้คำสั่ง
setb P0.4
* ในการให้ค่าที่เท่ากับ 0 ไปยังตัวแปรอื่น ๆ ต้องมี # นำหน้าเสมอ แต่ถ้าต้องการอ้างถึงตำแหน่งหน่วยความจำไม่ต้องมี #
** ในการอ้างถึงค่าที่ขึ้นต้นด้วยตัวอักษร ต้องมี 0 นำหน้า เช่น 0Ah, 0B1h
-
ผมขอบคุณมากครับที่มาให้ทางวิชาการ ถ้าไม่เข้าใจช่วยแนะนำด้วยครับ
-
O0เยี่ยมครับคุณ peet ไม่ทราบว่าพอจะมี ATAPI command ป่าวครับ เผื่ออยากจะลองทำดูบ้างครับ
-
ขอบคุณมากครับที่แนะนำเมื่อคืนนี้ยังนอนคิดอยู่เหมือนกันว่าจะทำให้ได้อย่างไรดี แวบ ๆๆ ไอเดีย ร่วมลงขัน develop แต่ให้คุณ DIY MAN ออกแรงจะดีไหม ;D
-
ขอบคุณมากครับที่แนะนำเมื่อคืนนี้ยังนอนคิดอยู่เหมือนกันว่าจะทำให้ได้อย่างไรดี แวบ ๆๆ ไอเดีย ร่วมลงขัน develop แต่ให้คุณ DIY MAN ออกแรงจะดีไหม ;D
ผมขอ :nono ครับ เนื่องจากจุดขายของโครงงานนี้อยู่ที่ เอา Remote มาสั่งเข้า IDE Port ของ CD-ROM ด้วยคำสั่ง ATAPI Command ต่างๆ ให้ควบคุม CD-ROM ได้อีกที นอกนั้นมันก็ไม่ค่อยมีอะไรน่าสนใจ ผมว่ากว่าเราจะพัฒนาไปถึงขั้นนั้น ผมว่ามันจะเสียเวลานั้งฟังเพลงเพราะๆ ผ่านแอมป์หลอดตัวโปรดของเราซะนะครับ คุณ DIY C ผมว่าถ้าเราจะใช้ CD-Rom ฟังเพลงหรือต่อ DAC ก็ให้หารุ่นเก่าๆ หน่อยที่มี Function Play เลยหรือว่าหาพวก Transport CD/CD Player รุ่นที่ไม่แพงมาก ที่มี Digital OUT เอามาใช้งานผมว่ามันก็จบครับ และก็ดีกว่าเอา CD Rom มา Control ให้ยุ่งยากอีกด้วยครับ เท่าที่ผมลอง Test ใช้งานจริงๆ มาหลายๆ Version ทั้งของในและของนอก ซึ่งชุดพวกนี้ส่วนใหญ่ผมพบว่ายัง Response ต่อคำสั่งไม่ค่อยดีและเร็วพอ และบางทีแถมมีอาการ Hang ค้างไปเลยอีกด้วย Evaluate Versions คงพอได้ครับ เทียบกับราคาถ้าไม่คิดมากนะครับ ผมว่าซื้อ CD Player จีนถูกๆ มาฟังเพลงเล่นได้ซักตัวสองตัวแหละครับ 2f 2f 2f
-
ขอบคุณมากครับที่แนะนำเมื่อคืนนี้ยังนอนคิดอยู่เหมือนกันว่าจะทำให้ได้อย่างไรดี แวบ ๆๆ ไอเดีย ร่วมลงขัน develop แต่ให้คุณ DIY MAN ออกแรงจะดีไหม ;D
เอา CD Rom มา Control ให้ยุ่งยากอีกด้วยครับ เท่าที่ผมลอง Test ใช้งานจริงๆ มาหลายๆ Version ทั้งของในและของนอก ซึ่งชุดพวกนี้ส่วนใหญ่ผมพบว่ายัง Response ต่อคำสั่งไม่ค่อยดีและเร็วพอ และบางทีแถมมีอาการ Hang ค้างไปเลยอีกด้วย
ขอบคุณครับ
-
ขอบคุณคุณpeet ด้วยครับ O0
-
ขอบคุณคุณ peet มากครับ c)
-
ขอบคุณคุณ peet สำหรับความรู้ที่นำมาปันกันครับ :clap อันที่จริงผมอ่านไม่เข้าใจหรอกตอนนี้ แต่น่าสนใจครับ :D
ผมขอ :nono ครับ เนื่องจากจุดขายของโครงงานนี้อยู่ที่ เอา Remote มาสั่งเข้า IDE Port ของ CD-ROM ด้วยคำสั่ง ATAPI Command ต่างๆ ให้ควบคุม CD-ROM ได้อีกที นอกนั้นมันก็ไม่ค่อยมีอะไรน่าสนใจ ผมว่ากว่าเราจะพัฒนาไปถึงขั้นนั้น ผมว่ามันจะเสียเวลานั้งฟังเพลงเพราะๆ ผ่านแอมป์หลอดตัวโปรดของเราซะนะครับ
;D อ่านตอนต้นแล้วยังลุ้นๆ ว่าคุณ DIY Man จะเป็นหัวหอกพัฒนาแล้วเอามาเล่าสู่กันฟังซะอีกครับ น่าเสียดาย :cry2
เท่าที่ผมลอง Test ใช้งานจริงๆ มาหลายๆ Version ทั้งของในและของนอก ซึ่งชุดพวกนี้ส่วนใหญ่ผมพบว่ายัง Response ต่อคำสั่งไม่ค่อยดีและเร็วพอ และบางทีแถมมีอาการ Hang ค้างไปเลยอีกด้วย Evaluate Versions คงพอได้ครับ เทียบกับราคาถ้าไม่คิดมากนะครับ ผมว่าซื้อ CD Player จีนถูกๆ มาฟังเพลงเล่นได้ซักตัวสองตัวแหละครับ 2f 2f 2f
คุณ DIY Man ได้ทดสอบรุ่นไหนมาบ้างแล้วครับ รบกวนกรุณาเล่าประสบการณ์ที่ทดสอบมาให้ฟังทีละรุ่นได้ไม๊ครับ ผมมีความเชื่ออย่างหนึ่งว่ามันไม่ได้แย่ทั้งหมดและหลายๆ Design คงไม่ได้มีปัญหาจุดเดียวกันหมด ประสบการณ์คุณ DIY Man น่าจะเป็นประโยชน์ได้ในแง่ที่ว่านำหลายๆ Design มารวมกันเพื่อกลบจุดอ่อนซึ่งกันและกันครับ แบบนี้น่าจะพัฒนาให้ปัญหาหมดไปและนำมาใช้จริงได้ครับ ผมไม่มีความรู้เรื่อง ATAPI เลยนะครับ แต่รู้เรื่อง Micro Controller พอสมควร ก็เลยคิดว่าน่าจะไปในทางนี้ได้ครับ
คุณดาวเหนือครับ กรณีเพื่อการศึกษาลักษณะนี้คงสามารถนำ Product/Project เหล่านั้นมาวิเคราะห์-วิจารณ์กันได้นะครับ เพราะเจตนาเราคือต้องการหาจุดด้อยเพื่อพัฒนา หรือถ้าเป็นการไม่สมควรก็ไม่เป็นไรครับ :)
-
ในหัวข้อนี้ผมจะเขียนครอบคลุมทุกสาระสำคัญและเนื้อหาทางวิชาการที่เกี่ยวข้องกับการทำ โดยจะลำดับเนื้อหาจากง่ายไปหายาก เพื่อให้ผู้อ่านค่อย ๆ ทำความเข้าใจไปเรื่อย ๆ และเป็นการตรวจสอบว่าการทำงานของ MCU เป็นไปอย่างถูกต้อง เช่น ถ้าผมเริ่มด้วยการเขียนคำสั่ง ATAPI และถ้ามันไม่ทำงาน ผมจะตรวจสอบลำบากมากว่าเป็นเพราะอะไร ผมจึงเห็นว่าเริ่มจากจอแสดงผล และแผงปุ่มกดก่อน
ด้วยเหตุนี้ ผมจะเริ่มจากการใช้งานจอแสดงผล LCD รวมถึงการเขียนโปรแกรมเพื่อควบคุมด้วย
-
หน้าจอ LCD ที่มีมาตรฐานตาม H44780 จะมี Connector ทั้งหมด 14 pins แต่ถ้าสังเกตบางอันจะมี 16 pins ซึ่งอีก 2 pins ที่เพิ่มขึ้นมา คือ ไฟ +5v และ Gnd สำหรับ Backlight.
ขาที่ 1 - 14 มีรายละเอียดดังนี้
ขา 1 GND
ขา 2 +5v
ขา 3 Contrast
ขา 4 RS ใช้สำหรับเลือกว่าต้องการเขียนข้อมูล D0-D7 ลงใน Register คำสั่งหรือตัวอักษร
ขา 5 Read/Write ใช้สำหรับบอก LCD ว่า MCU จะกำลังอ่านหรือเขียนข้อมูล
ขา 6 E ขา Clock
ขา 7 - 14 ขา D0-D7
-
ขอบคุณคุณ peet สำหรับความรู้ที่นำมาปันกันครับ :clap อันที่จริงผมอ่านไม่เข้าใจหรอกตอนนี้ แต่น่าสนใจครับ :D
ผมเองก็เหมือนกัน จบทางสังคมศาสตร์ แต่สนใจทางด้านนี้มากๆ ก็ได้ที่แหละครับ จุดประกาย
-
คุณ peet ครับ เติมอีกครับ น่าติดตามมากๆเลย ถึงทำเล่นเองจะแพงกว่าซื้อมา ก็ถือว่า "เราทำได้" ครับ
-
สวรรค์มาโปรดแล้วครับ...นี่คุณ peet จะสอนพวกเราให้เขียนโปรแกรม MCU จนกระทั่งใช้รีโมตได้เลยไหมครับ..ผมมีวงจรพร้อมใช้งานอยู่2วงจรทั้งรุ่น 1รุ่น2 ใช้งานได้ขาดแต่รีโมตไม่ได้เท่านั้นเองครับ...เพื่อนๆช่วยกันเรียนรู้ไว้นะครับส่วนของวงจรที่จะนำมาทดลองกันผมพร้อมที่จะสนับสนุนครับ..พร้อมเครื่องโปรแกรม MCU ด้วยครับ...งานนี้ยอมถวายตัวครับและผมว่ายังมีเพื่อนๆผมอีกหลายสิบคนในซีเอ็ดเวบบอร์ดที่ทำแล้วยังใช้รีโมตไม่ได้ผมจะไปตามมาสมัครในชมรมเราเพื่อมาเรียนรู้กันครับ...ถ้าลองคุณPeetลงมาสอนเองแล้วผมเขียนโปรแกรมให้ใช้รีโมตไม่ได้คงจะเลิกเล่น DIY ไปตลอดชีวิตเลยล่ะครับเจ้าของโปรแกรมมาสอนเองทั้งที(เดี๋ยวไปโพสไว้ในซีเอ็ดเวบบอร์ดดีกว่า..ดีใจจังเลยครับ)........ : :help c)
-
ผมก็อยากรู้การใช้งาน Microcontroler เหมือนกันครับเผื่อเอาไปประยุกต์ใช้งานอื่นๆรบกวนคุณ Peet แนะนำ เครื่องมือที่จะใช้ร่วมในการพัฒนาด้วยครับด้วยครับ O0
-
การใช้งานจอ LCD โดยปกติแล้วผมจะต่อขา 5 (Read/Write) ลง GND ครับ เพราะต้องการส่งคำสั่งจาก MCU ไปยัง LCD เท่านั้น ก็คือ Write อย่างเดียวครับ
ขา 4 (RS) ผมจะต่อเข้ากับ MCU ในกรณีที่ MCU ต้องการจะส่งคำสั่งให้กับ LCD ขานี้จะเป็น Low เช่น คำสั่ง ลบหน้าจอ, เลื่อนเคอร์เซอร์, หรือขึ้นบรรทัดใหม่เป็นต้น โปรแกรมที่ผมเขียนก็จะมีคำสั่ง
clr P1.7
แต่ถ้า MCU จะส่งตัวอักษรไปแสดงบน LCD ขานี้จะเป็น High ครับ อักษรต่าง ๆ ก็จะประกอบด้วย A-Z, a-Z, 0-9 , และสัญลักษณ์ต่าง ๆ โดยจะใช้คำสั่ง
setb P1.7
ขา 7-14 ก็ต่อกับ MCU port ใด port หนึ่งครับ เพื่อส่งข้อมูลแบบ 8 บิต ทั้งที่เป็นคำสั่ง หรือตัวอักษร
ขา 6 (E) เป็นขา Clock ครับ เมื่อต้องการให้ LCD รับข้อมูล 8 บิตที่รออยู่ที่ขา 7-14 ก็เปลี่ยนแรงดันจาก Low เป็น High ที่ขา 6 ครับ
จากที่ผมได้อธิบายหน้าที่ต่าง ๆ ของแต่ละขา คราวนี้จะเป็นลำดับการสั่งงานเพื่อส่งข้อมูลให้กับ LCD
เช่น ผมต้องการส่งตัวอักษร A ไปแสดง ณ ตำแหน่งที่เคอร์เซอร์อยู่ ผมจะต้อง
ส่งค่า 41h* ไปที่ P0 ด้วยคำสั่ง
mov P0, 41h
เนื่องจากเป็นการส่งตัวอักษร ผมต้องให้ RS เป็น High ด้วยคำสั่ง
setb P1.7
ตอนนี้ข้อมูลทั้งหมดได้ถูกรออยู่ที่ขาต่าง ๆ ของ LCD แล้ว ก็จะมาถึงขั้นตอนให้ LCD รับข้อมูลทั้งหมดไป โดยใช้คำสั่ง
clr P2.0
nop
setb P2.0
* A มีค่าตามรหัส ASCII เป็น 41h
-
กำลังมันเลยครับ อาจารย์ peet ต่อเลยครับเดี๋ยวสมองไม่แล่น ใจผมอยากให้ใช้รีโมตได้ในเร็ววันเลยครับ...ตอนแรกกะว่าจะทิ้งซะแล้ว...หายไปไหนแล้วครับกลับมาสอนต่อด่วนครับ สมาชิกตั้งตารอกันครับบบบบบ
-
หยั่งงี้ก้อเฮียดัน ล่ะสิ...555 c)
-
ถ้าไม่อยากรอก็ซื้อหนังสือ MCS 51 มาลองศึกษาเองก็ได้ครับ
พวกวิธีการเชื่อมต่อน่าจะมีอยู่ในหนังสือหมด แต่มันจะยากที่การเขียนโปรแกรมนี่แหละ :-\ :headphone
-
ผมว่าลืมไปซะแล้วมาสนใจกระทู้นี้กันดีกว่าครับ http://www.htg2.net/index.php?topic=10528.0 (http://www.htg2.net/index.php?topic=10528.0) ต้องนับถือน้ำใจกันเลยครับ
-
ผมว่าลืมไปซะแล้วมาสนใจกระทู้นี้กันดีกว่าครับ http://www.htg2.net/index.php?topic=10528.0 (http://www.htg2.net/index.php?topic=10528.0) ต้องนับถือน้ำใจกันเลยครับ
เห็นด้วยเป็นอย่างยิ่งครับ :drunkเฮีย Pongpond พูดถูก เพราะจะได้รู้กันไปเลยว่า นัก Audio DIY ไม่ชอบการใหว้ครูนานๆ แบบนี้ ถ้าว่างก็
มาว่าต่อเลยครับอาจารย์ Peet เน้นๆ Remote Function ให้จบๆ ไปเลยครับ 2f 2f
กำลังมันเลยครับ อาจารย์ peet ต่อเลยครับเดี๋ยวสมองไม่แล่น ใจผมอยากให้ใช้รีโมตได้ในเร็ววันเลยครับ...ตอนแรกกะว่าจะทิ้งซะแล้ว...หายไปไหนแล้วครับกลับมาสอนต่อด่วนครับ สมาชิกตั้งตารอกันครับบบบบบ
เรารอกันมาเกือบปีแล้ว รออีกหน่อยจะเป็นไรครับเฮีย เอาด้ามไม้กวาดจิ้มแทน Remote ไปพลางๆก่อน...5555 ผมลงมือทำไว้ 4-5 ชุด ถ้างานนี้ไม่จบ คงต้องกวาดมันทั้งหมดลงถังขยะซะแล้วครับ :nonono
-
ตอนที่แล้วผมพูดเกี่ยวกับการเขียนตัวอักษรเพื่อแสดงผลบนจอ LCD ส่วนในการเขียนคำสั่งก็ได้พูดไปบ้างแล้วซึ่งก็ต่างกันแค่สัญญาณ RS เป็น 0 เท่านั้น
ที่นี้เมื่อเริ่มจ่ายไฟให้กับ LCD จะต้องมีการกำหนดค่าต่าง ๆ เพื่อให้ตรงกับการใช้งานครับ โดยปกติแล้วผมจะเริ่มส่งค่าต่าง ๆ ไปยัง LCD ดังนี้
เริ่มแรกผมส่งค่า 38h เพื่อกำหนดให้ LCD แสดงผลแบบ 2 บรรทัด จากนั้นเป็น 0Ch เพื่อแสดงผลแต่ไม่แสดงเคอร์เซอร์ครับ และตามด้วย 06h เพื่อให้แสดงผลแบบเลื่อนเคอร์เซอร์ไปทางขวา
และอีกคำสั่งที่ใช้บ่อย ๆ คือ 01h เป็นคำสั่งสำหรับลบหน้าจอครับ หลังจากที่ LCD ได้รับคำสั่งนี้ตัวหนังสือบนหน้าจอจะถูกลบทั้งหมดและเคอร์เซอร์จะกลับไปหยุดอยู่ซ้ายสุดบรรทัดบนครับ
แต่ถ้าต้องการให้เคอร์เซอร์ย้ายไปอยู่ที่ตำแหน่งนี้โดยไม่ลบหน้าจอก็ใช้คำสั่ง 80h ครับ และถ้าต้องการให้เคอร์เซอร์ไปอยู่ซ้ายสุดของบรรทัดที่ 2 ก็ใช้คำสั่ง C0h
*** การใช้คำสั่งเหล่านี้ RS ต้องเป็น 0 เท่านั้น ***
-
การเขียนโปรแกรมสำหรับรับคำสั่งจากผู้ใช้งาน
จากวงจรที่ออกแบบไว้จะเห็นว่าปุ่มกดทั้งหมดรวมถึงตัวรับสัญญาณรีโมทคอนโทรลอยู่ที่ Port 3 ทั้งหมด ในกรณีที่มีการกดปุ่มก็หมายถึงถูกเชื่อมต่อกับ GND ซึ่งก็คือ 0
ดังนั้นการเขียนโปรแกรมก็เริ่มจากให้ทุกขาของ Port 3 เป็น 1 ทั้งหมด โดยใช้คำสั่ง
mov P3, #0FFh
จากนั้นอ่านค่ากลับมาเป็นไว้ที่ A* ด้วยคำสั่ง
mov A, P3
ค่าที่อ่านกลับมานี้ จะเป็นแบบ 8 บิต แต่ชุดรับคำสั่งต่ออยู่กับบิตที่ 0-6 ผมจึงเปลี่ยนบิตที่ 7 ให้เป็น 0 ทุกกรณีเพื่อใช้เปรียบเทียบค่าด้วยคำสั่ง
anl A, #7Fh
จากนั้นนำค่าที่ได้มาเปรียบเทียบเพื่อหาว่าปุ่มไหนถูกกด ด้วยคำสั่ง
cjne A, #3Fh, Next1
acall (P3.6 , เรียกคำสั่งที่ต้องการให้ปุ่มนี้ทำ)
ret**
จากคำสั่งข้างต้นผมเปรียบเทียบกับค่า 3F (00111111) เพราะผมต้องการหาว่าบิต P3.6 เป็น 0 หรือ 1 ในกรณีที่เป็น 0 แปลว่าปุ่มที่ต่อกับบิตนี้ถูกกด ถ้าเป็น 1 ก็แสดงว่าไม่ได้ถูกกด
ซึ่งถ้าปุ่มถูกกดค่า A ที่ได้มาตั้งแต่แรกจะมีค่าเท่ากับ 3F จากนั้นโปรแกรมก็จะดำเนินการในคำสั่งต่อไป ซึ่งก็คือ เรียกคำสั่งที่เป็นของปุ่มที่ถูกกดด้วยคำสั่ง acall หรือ lcall
แต่ถ้าปุ่มนี้ไม่ถูกกดค่า A ก็จะไม่เท่ากับ 3F โปรแกรมก็จะกระโดดไปที่ตำแหน่ง Next1
Next1: cjne A, #05Fh, Next2
acall (P3.5 , เรียกคำสั่งที่ต้องการให้ปุ่มนี้ทำ)
ret**
คล้าย ๆ กับการเปรียบเทียบค่าครั้งแรกครับ แต่ครั้งนี้ผมเปรียบเทียบกับ 5F (01011111) เพราะผมต้องการหาว่าบิต P3.5 เป็น 0 หรือ 1
ถ้าปุ่มนี้ถูกกด ค่า A จะเท่ากับ 5F ถ้าไม่ถูกกดก็จะไม่เท่ากับ 5F และจะกระโดดไปทำงานต่อที่ Next2
Next2: cjne A, #0DCh, Next3
lcall StopCD
ret
ในการเปรียบเทียบค่าเพื่อหาปุ่มที่ถูกกดที่เหลือ ก็ทำเหมือนกับคำสั่งข้างต้นแต่เปลี่ยนที่นำมาเปรียบเทียบด้วย ดังนี้
ปุ่มที่ต่อกับ P3.4 เปรียบเทียบกับค่า 6F
ปุ่มที่ต่อกับ P3.3 เปรียบเทียบกับค่า 77
สัญญาณรีโมทต่อกับ P3.2 เปรียบเทียบกับค่า 7B
ปุ่มที่ต่อกับ P3.1 เปรียบเทียบกับค่า 7D
ปุ่มที่ต่อกับ P3.0 เปรียบเทียบกับค่า 7E
ในกรณีที่ไม่มีการกดปุ่มใด ๆ เลย ค่า A ก็จะไม่เท่ากับค่าใด ๆ เลยที่นำมาเปรียบเทียบ จากนั้นก็จบด้วยคำสั่ง
ret**
ในขั้นนี้ควรตรวจสอบความถูกต้องของโปรแกรมด้วยการแสดงสัญลักษณ์ของปุ่มขึ้นบนจอแสดงผล ที่ได้ทำไว้ในตอนแรกครับ เช่น แสดงเป็นค่าตัวเลข 1-6 ของแต่ละปุ่มขี้นหน้าจอครับ
* A เป็นตำแหน่งหน่วยความจำที่สามารถคำนวณหรือเปรียบเทียบค่าได้ จึงต้องอ่านค่ามาเก็บที่หน่วยความจำนี้เสมอ
** คำสั่ง ret เป็นการบอกให้ MCU กระโดดการอ่านหน่วยความจำโปรแกรมกลับไปยังตำแหน่งสุดท้ายก่อนหน้านี้
-
ในตอนที่แล้วเป็นการสแกนปุ่มกด ครั้งนี้จะเป็นการจำแนกสัญญาณ IR เพื่อรับคำสั่งด้วย Remote Control
Remote Control ส่งคำสั่งด้วยสัญญาณ IR มีการแยกรหัส 0 และ 1 ด้วยความยาวของพัลส์ และมีคลื่นพาห์ประมาณ 38-40 kHz. การแยกรหัส 0 และ 1 มีอยู่ 3 มาตรฐาน ดังนี้
1. Pulse Coded ในมาตรฐานนี้ รหัส 0 และ 1 พัลส์จะมีความยาวไม่เท่ากัน โดยรหัส 0 จะมีความยาวพัลส์สั้นกว่าพัลส์รหัส 1
2. Space Coded แบบนี้จะตรงกันข้ามกับแบบแรก กล่าวคือ รหัส 0 และ 1 ช่องว่างระหว่างพัลส์จะยาวไม่เท่ากัน โดยรหัส 0 จะมีช่องว่างระหว่างพัลส์สั้นกว่ารหัส 1
3. Shift Coded รหัส 0 พัลส์จะเปลี่ยนจาก Low เป็น High ในทางกลับกันรหัส 1 พัลส์จะเปลี่ยนจาก High เป็น Low
ในการเขียนโปรแกรมเพื่อจำแนกสัญญาณ IR ออกเป็นคำสั่งต่าง ๆ ดังนี้
เริ่มจาก Label ที่มีชื่อว่า Remote ซึ่งในตอนที่แล้ว ผมได้เขียนคำสั่งเรียก Label นี้ เมื่อ P3.2 เป็น 0
Remote: mov RCode, #0h (เป็นการให้ค่า RCode เป็น 0)
mov Period, #0h (เป็นการให้ค่า Period เป็น 0 ตัวแปรตัวนี้มีหน้าที่วัดความยาวของพัลส์หรือช่องว่าง เพื่อจำแนกว่าเป็นรหัส 0 หรือ 1)
RMC1: inc Period (คำสั่ง inc เป็นคำสั่ง +1 ให้กับตัวแปร)
jnb RM, RMC1 (RM คือสัญญาณที่รับเข้ามาทาง P3.2, คำสั่ง jnb เป็นคำสั่งวน Loop ในกรณีที่ RM เป็น 0 จะกระโดดกลับไปที่ RMC1)
ใน loop ข้างต้นนี้เป็น loop ที่รอรับพัลส์เริ่มต้นหรือ Head ของสัญญาณที่ส่งมาจาก Remote Control
mov Period, #0h
RMS1: inc Period
mov A, Period
cjne A, #10h, RMS2 (cjne เป็นคำสั่งเปรียบเทียบค่า ในกรณีที่ Period มีค่าเท่ากับ 10h จะจบการทำงานของการรับคำสั่งจาก Romote Control เนื่องจากไม่ใช่สัญญาณที่มาจาก Remote Control ที่เป็นคู่ของมัน)
sjmp RMEnd
RMS2: jb RM, RMS1 (เป็นคำสั่งวน Loop ในกรณีที่ RM เป็น 1 กระโดดกลับไปที่ RMS1
ใน loop ข้างต้นนี้เป็น loop วัดความยาวพัลส์ของสัญญาณที่ส่งมาจาก Remote Control
mov Period, #0h
RMC2: inc Period
jnb RM, RMC2
mov A, Period
mov Period, #0h
cjne A, #8Bh, INT_C1
sjmp RMS3
INT_C1: jc RMEnd
cjne A, #0A5h, INT_C2
sjmp RMS3
INT_C2: jnc RMEnd
RMEnd: ret
ใน loop ข้างต้นนี้เป็น loop วัดความยาวช่องว่างของสัญญาณที่ส่งมาจาก Remote Control
ในการเขียนโปรแกรมสำหรับสัญญาณจาก Remote Control จะต้องตรวจจับสัญญาณด้วย Loop ต่าง ๆ ตามข้างต้นไปเรื่อย ๆ จนถึงพัลส์สุดท้ายของสัญญาณที่ Remote Control ส่งมา
และเมื่อนำมาเปรียบเทียบจะพบว่ารหัสของแต่ละปุ่มจะไม่เหมือนกัน ซึ่งจะสามารถแยกได้ว่าผู้ใช้งานกดปุ่มใด เพื่อใช้สั่งงานต่อไป