เรียนรู้หน้าที่ และการใช้งาน I/O ของ PIC MCU

เรียนรู้หน้าที่ และการใช้งาน I/O ของ PIC MCU

วันนี้ เราจะมาทำความเข้าใจของ ขาแต่ละขาของไมโครคอนโทรลเลอร์ตระกูล PIC จากค่ายไมโครชิพกันครับ โดยเบอร์ที่จะยกตัวอย่างต่อไปนี้ ก็เป็นเบอร์ PIC18F46K22 สำหรับเบอร์อื่นๆ ก็สามารถศึกษาจากดาต้่าชีทของเบอร์นั้นๆ ได้ โดยผมจะอธิบายจากดาต้าชีทเหมือนกัน ดังนั้น ท่านสามารถนำหลักการพิจารณานี้ ไปศึกษาจากเบอร์อื่นๆ ตามดาต้าชีทของมันได้เลย 

สิ่งที่เรารู้เป็นอันดับแรกๆ ก็คือ ไมโครคอนโทรลเลอร์ที่เรากำลังจะเลือกใช้งานนั้น มีจำนวนขาที่ใช้งาน อยู่กี่ขา เพียงพอกับโปรเจคเราไหม และขาที่ต้องใช้งานฟังก์ชั่นพิเศษนอกเหนือจากขาที่เป็นดิจิตอล อินพุต เอาท์พุตนั้น มีอยู่หรือเปล่า เพียงพอไหม ซึ่งข้อมูลคร่าวๆ เหล่านี้ เราจะสามารถพบได้ที่หน้าเว็บของไมโครคอนโทรลเลอร์เบอร์นั้น สำหรับเบอร์ PIC18F46K22 นั้น ก็เช่นเดียวกัน ทางไมโครชิพจะสรุปไว้แล้ว ที่หน้าดาวน์โหลดดาต้าชีทของมัน แต่ รายละเอียดลึกๆ นั้น เราต้องโหลดดาต้าชีทมาดู

เอาหล่ะ เมื่อเราได้โหลดดาต้าชีทของเบอร์ PIC18F46K22 มาแล้ว เราก็มาดูในส่วนของ PIN Diagrams ของมมันก่อน ในตัวอย่างนี้ ผมมี PIC18F46K22 ตัวถังแบบ PDIP 40 PIN อยู๋ในมือ ผมจึงโฟกัสไปที่ Pin Diagrams (40-pin) ซึ่งจากรูป จะเห็นการจัดเรียงตัวของขาไมโครคอนโทรลเลอร์ ซึ่งจะมีทั้งขาที่เป็นแหล่งจ่าย Vcc,Vss  ขาที่เป็นขาโปรแกรม PGD,PGC ส่วนขาอื่นๆ ที่เห็นจะเป็นตำแหน่ง bit ต่างๆ ในแต่ละ PORT เช่น RA0 คือ บิตแรกของรีจิสเตอร์ PORTA ส่วน RA1,RA2,RA3...,RA7 ก็ไล่ไปเรื่อยๆ จนครบ 8 บิต (รีจิสเตอร์ หนึ่งมีขนาด 8 บิต มันจึงได้ชื่อว่า ไมโครคอนโทรลเลอร์ 8 บิต นั่นเอง)  ซึ่งจะเห็นตำแหน่งการเรียงตัวของแต่ละบิต ในแต่ละ PORT จะวางเรียงตัวใกล้ๆ กัน

ต่อมาในตาราง TABLE 1-3: PIC18(L)F4XK22 PINOUT I/O DESCRIPTIONS เขาจะบอกถึงรายละเอียดของแต่ละขา ของไมโครคอนโทรลเลอร์ โดยจะบอกทั้งตัวถัง PDIP, TQFP, QFN, UQFN ซึ่งตัวถังของเราเป็นแบบ PDIP ดังนั้นเราจึงจะสนใจเฉพาะช่องข้อมูลที่เขียนว่า PDIP เท่านั้น ในตารางนี้ มีคำย่อที่ควรทำความเข้าใจสักหน่อย เช่น  ST, TTL , CMOS, Analog,  เหล่านี้ มันคืออะไรกันแน่

ที่ท้ายตารางนี้ ได้บอกไว้แล้วว่า แต่ละคำ มีความหมายอย่างไร ซึ่งบางคำเราอาจจะรู้จักอยู่แล้ว แต่บางคำเราอาจจะไม่รู้จัก โดยเฉพาะผู้ที่มีความถนัดทางด้านการเขียนโปรแกรม แต่มีความรู้ทางอิเล็กทรอนิกส์น้อยนิด อาจจะมีปัญหาได้ ดังนั้น ผมจะขออธิบายแบบนี้สักหน่อย

ST: Schmitt Trigger input with CMOS levels ความหมายก็คือ ขาที่กระทำหน้าที่ใดๆ ก็ตามที่มี Buffer Type เป็นแบบ ST จะมีพฤติกรรมเหมือนวงจร Schmitt Trigger โดยแรงดันอ้างอิงเหมือน CMOS ซึ่งโดยมากแล้วจะทำหน้าที่เป็น Digital Input คือรับสัญญาณในรูปแบบ Digital นั่นเอง แต่ ความแตกต่างมันอยู่ที่ระดับแรงดันที่มันจะตัดสินใจว่าจะให้เป็น Logic High (1) หรือว่า Logic Low (0) ในตอนที่มันทำหน้าที่เป็น Input ดูรูปประกอบเพื่อความเข้าใจกันดีกว่า 

ที่มาของรูป Wikipedia

จากรูปจะเห็นได้ว่า หากเรามีสัญญาณใดๆ (กราฟรูป U)  ก็ตาม ซึ่งในความเป็นจริงแล้ว สัญญาณที่รับมาจากภายนอกนั้น มันไม่ได้มีความสมบูรณ์ไปหมด มันอาจจะมีการแกว่งของสัญญาณ ดังรูป หากเราให้สัญญาณนี้ เข้ามาทาง Digital input pin ที่เป็น ST buffer type แล้วหล่ะก็ ทางไมโคร

คอนโทรลเลอร์จะเริ่มตัดสินใจ ว่าอินพุตที่เข้ามา มีค่า Logic High (1) เมื่อสัญญาณมีความสูงของระดับแรงดันสัญญาณเกินเส้นสีเขียว และจะคงรับรู้อยู่แบบนั้นไปเรื่อยๆ จนกระทั่งสัญญาณตกลงมาต่ำกว่าระดับเส้นสีเขียวประ เส้นล่าง ไมโครคอนโทรลเลอร์ก็จะตีความหมายว่าระดับสัญญาณเป็น Logic Low (0) ซึ่งตรงกับกราฟรูป B ซึ่งจะแตกต่างกับวงจรเปรียบเทียบแรงดันในรูป A

TTL , CMOS : ส่วนอินพุตขาใด เป็นแบบ TTL หรือ CMOS ถ้าดูจากรูปจะเข้าใจมากกว่า ซึ่งสามารถอธิบายง่ายๆ ดังนี้ คือ ถ้าแรงดันของสัญญาณอินพุตอยู่ระหว่าง 0 ถึง 0.8V สำหรับ TTL แล้วจะมองว่า มีสภาวะ Logic Low ในขณะที่ CMOS จะมองว่า Logic Low นั้นอยู่ในช่วง 0 ถึง 1.3V   และถ้าระดับแรงดันสัญญาณอินพุตอยู่ระหว่าง 2.0 ถึง 5V สำหรับ TTL จะมองว่า มีสภาวะ Logic High ในขณะที่ CMOS จะมีย่านที่สูงกว่านั้น คือ ตั้งแต่ 2.5V จนถึง 5V จะมองว่ามีสภาวะ Logic High ส่วนช่วงที่เป็นช่วงสีฟ้า ของทั้ง TTL และ CMOS เป็นช่วงที่ไม่สามารถบอกได้ว่าจะเป็น High หรือว่าเป็น Low เอาแน่เอานอนไม่ได้ ในช่วงดังกล่าว แต่ถ้าขาใดๆ ของไมโครคอนโทรลเลอร์ ทำหน้าที่เป็น Output Digital แล้ว ก็พิจารณาตามช่องสีเหลืองอ่อน และช่องสีส้ม ของแต่ละ buffer type ได้เลยครับ 

Analog : ทำหน้าที่เป็นได้เฉพาะอินพุตเท่านั้น ซึ่งมันเอาไว้อ่านค่าสัญญาณที่มีการเปลี่ยนแปลงแรงดันตลอดเวลา ที่เรามักพูดกันทั่วๆไป ว่าเป็น

สัญญาณอนาล๊อก นั่นแหละครับ ซึ่งสัญญาณอนาล๊อกที่รับได้ มันก็ควรจะอยู่ในช่วงไม่เกิน Vref ของมัน ซึ่งถ้า Vref ของมันเท่ากับ Vcc และ Vcc ของไมโครคอนโทรลเลอร์ตัวนั้นรองรับ Vcc=5V ดังนั้นแรงดันอนาล๊อกที่จะป้อนเข้าขานี้ ก็ต้องมีแรงดันไม่เกิน 5V ด้วยเช่นกัน ไม่เช่นนั้น อาจจะทำให้ขาอินพุตอนาล๊อก ขานั้น เสียหายได้ 

หมายเหตุ: เมื่อเราพิจารณากันที่ระดับแรงดันไฟเลี้ยง 5V 

จากตารางที่  TABLE 1-3 มีปัญหาที่ว่า ทำไมในขาหนึ่งของไมโครคอนโทรลเลอร์ PIC18F46K22 จึงมี Pin Name มากกว่า 1 ชื่อ หล่ะ และแต่ละ Pin Name ก็ทำหน้าที่แตกต่างกัน คำถามก็คือ เราจะรู้ได้ไง ว่าขานั้น จริงๆ แล้วทำหน้าที่อะไรเป็นหน้าที่หลัก เราจะพิจารณาจากตรงไหน ซึ่งตรงนี้ ไม่ยากครับ คำตอบก็คือ ให้ไปดูหัวข้อ 10.0 I/O Port โดยในหัวข้อย่อย PORTx Register เขาจะมี Note บอกไว้อยู่ครับ  เช่น หัวข้อ 10.1 PORTA Register จะมี Note บอกไว้ดังรูป 

"Note:  On a Power-on Reset, RA5 and RA<3:0> are configured as analog input and read as '0'. RA4 is configured as a digital input"

แปลได้ว่า เมื่อตอนที่เกิด Power-on Reset ซึ่งนั่นก็คือสภาวะเมื่อจ่ายไฟให้กับไมโครคอนโทรลเลอร์ครั้งแรก นั้น RA5 และ RA3, RA2, RA1, RA0 จะถูกกำหนดให้เป็น Analog input และอ่านค่า Pin เหล่านั้นได้ค่า Logic Low (0)  ในขณะที่ RA4 นั้น จะถูกกำหนดให้เป็น Digital input นั่นก็แปลว่า หากในโค๊ดเราไม่ได้กำหนดให้ขาเหล่านี้ ทำหน้าที่ฟังก์ชั่นอื่นๆ หรือไม่ได้กำหนดอะไรเลยขา PORTA ส่วนใหญ่จะเป็น Analog Input มีเพียงขา RA4 เท่านั้นที่เป็น Digital input ซึ่ง PORTx อื่นๆ ก็ต้องพิจารณาเอาจาก Note ที่เขาเขียนไว้เหมือนกัน

แล้วถ้าหากเราต้องการให้มันทำหน้าที่อื่นๆ หล่ะ อันนี้ก็ต้องบอกว่า เราก็ต้องไปดูก่อนว่า มี Register อะไรที่ควบคุมมัน เช่น หากต้องการใช้ความสามารถ EUSART ที่อยู่ใน PORTC เราก็ต้องดูวา PORTC ขาไหนทำหน้าที่ EUSART และ Register ไหนที่ต้องเซตแล้วทำให้ขานั้น ทำหน้าที่ EUSART  ซึ่งเดี๋ยวเราเอาไว้ค่อยพูดกันครั้งหน้าแล้วกันครับ 

สุดท้ายมีเรื่องน่ารู้เกี่ยวกับ I/O PORT ของ PIC นั่นก็คือ การใช้งาน PORTx ใดๆก็ตาม ถ้าต้องการให้มันทำหน้าที่เป็น Input หรือ Output มันมี Register ที่เกี่ยวข้องกับการทำหน้าที่เหล่านี้หลักๆ อยู่ 3 ตัว คือ TRIS, PORT, ANSEL Register (จริงๆ มีมากกว่านี้ แล้วแต่เบอร์ที่เลือกใช้ ) ซึ่งทั้ง 3 Register จะเป็นตัวกำหนดให้ Pin หรือ PORT นั้น ทำหน้าที่เป็น Input หรือว่าเป็น Output และให้ทำหน้าที่เป็น Analog input หรือว่าเป็น Digital I/O เรามาดูกันว่า แต่ละตัวมีผลอย่างไร 

จาก TRIS register และตารางของมัน บอกไว้ว่า หากคุณต้องการให้ PORT หรือ PIN ใดๆ ทำหน้าที่เป็น Input ให้กำหนดเป็น 1 (ในโค๊ด) และหากต้องการให้เป็น Output ให้กำหนดเป็น 0 เช่น ต้องการให้ PORTB ทั้งหมดเป็น Output ทุกขา เราสามารถทำแบบนี้ได้ด้วยการกำหนดให้ TRISB = 0x00; หรือ TRISB = 0b00000000; แบบนี้ก็ได้ หรือถ้าต้องการให้เป็น Input ด้วยและ Output ด้วยใน PORT เดียวกันก็สามารถกำหนดได้เช่น TRISB = 0xF0; มีค่าเท่ากับ TRISB = 0b11110000;  แปลว่า ให้ RB7, RB6, RB5, RB4 ทำหน้าที่เป็น Digital Input และให้ RB3, RB2, RB1, RB0 ทำหน้ัาที่เป็น Digital Output 

ในขณะที่ PORT register ทำหน้าที่ในการสั่งให้ Pin หรือ PORT มีค่า Logic เป็น High (1) หรือว่า Low (0) แต่ก็ต้องขึ้นอยู่กับว่า PORT หรือ PIN นั้น ได้ถูกกำหนดให้เป็น Output จาก TRIS register แล้วหรือยัง เช่น หากต้องการให้ Pin RB0 ที่อยู๋ใน PORTB สั่งให้ Output เป็น Logic High เราสามารถกำหนดได้ดังนี้ 

TRISB = 0xFE;  // มีค่าเท่ากับ TRSB = 0b11111110;

PORTB = 0x01; // ทำให้ RB0 มีค่าเป็น 1 จะทำให้เกิด Logic High ที่ RB0 

สิ่งหนึ่งที่ต้องระวัง ก็คือ หาก PORT หรือ Pin ใดๆ มีความสามารถที่เป็น Analog function รวมอยู่ด้วยแล้วหล่ะก็ เราต้องสั่งให้ Analog function นั้น ไม่ทำงาน เมื่อเราต้องการใช้ความสามารถที่เป็น Digital function แทน เช่น เมื่อต้้องการให้ PORTA ทำหน้าที่เป็น Digital I/O เราต้องกำหนดให้ Analog function ของ PORTA ซึ่งควบคุมด้วย ANSELA register อยู่ ยกเลิกการทำงาน analog function ซะ ด้วยการกำหนด ดังนี้

ANSELA = 0xFE; // มีค่าเท่ากับ ANSELA = 0b11111110; นั่นก็คือ ทำให้ ANSA0 มีค่าเป็น 0 

TRISA = 0xFE;   // มีค่าทำให้ RA0 ทำหน้าที่เป็น Digital Output

PORTA = 0x01; // สั่งให้ Logic High ออกที่ RA0 นั่นเอง 

ซึ่งตรงนี้ เคยพบเห็นหลายๆ คน ซึ่งรวมทั้งผมด้วย เมื่อครั้งเริ่มศึกษาไมโครคอนโทรลเลอร์ใหม่ๆ เจอปัญหาว่า ไม่สามารถสั่งให้ไฟกระพริบที่ PORTA ได้ เพราะที่ PORTA นั้นทำหน้าที่เป็น Analog input เป็นค่า Default มันอยู่แล้ว จึงทำให้เราไม่สามารถสั่งให้มันเป็น Digital Output ได้ แม้จะกำหนดให้ TRSA = 0x00; แล้วก็ตาม 

นี่ก็เป็นเรื่องราวคร่าวๆ การใช้ PORT I/O ของไมโครคอนโทรเลอร์ตระกูล PIC นะครับ อย่าได้นำไปยึดถือปฏิบัติกับไมโครคอนโทรลเลอร์ตระกูลอื่นๆ หากไม่ได้ถูกออกแบบโดยใช้ PIC เป็นมาตรฐานแล้วหล่ะก็ ทางที่ดี ควรจะอ่านดาต้าชีทของไมโครคอนโทรลเลอร์เบอร์นั่นๆ ประกอบไปด้วย 

ดูตัวอย่างการตั้งค่าง่ายๆ สำหรับการทำไฟกระพริบ จากตอนที่แล้วครับ MPLAB® XC8 Getting Started Guide