Atmega328P Datasheet 18. I/O Ports 1

Started by tha, August 25, 2019, 09:42:42 AM

Previous topic - Next topic

tha

18. I/O-Ports

18.1. Overview(ภาพรวม)

ทุก AVR ports มีฟังก์ชัน Read-Modify-Write ที่แท้จริง เมื่อใช้เป็น general digital I/O ports. นี้หมายความว่าทิศทางของขาหนึ่งของ port สามารถถูกเปลี่ยน โดยปราศจากการเปลี่ยนทิศทางของขาอื่น ๆโดยไม่ได้ตั้งใจ ด้วยคำสั่ง SBI(set bit) และ CBI(clear bit). เช่นเดียวกันกับเมื่อเปลี่ยน drive value (ถ้ากำหนดเป็น output) หรือการเปิด/ปิดการใช้งานของ pull-up resistors (ถ้ากำหนดเป็น input). แต่ละ output buffer แต่ละตัวมีลักษณะของการไดรฟ์แบบสมมาตรกัน ด้วยมีทั้งความสามารถในการดึงลงกราวน์(sink)และเป็นแหล่งจ่ายไฟ(source)ที่สูง. pin driver นี้มีความแข็งแรงเพียงพอที่จะไดรฟ์ LED displays ได้โดยตรง. ทุกพิน (port pins) มี pull-up resistors ที่เลือกได้เป็นรายขาไป ด้วยแหล่งจ่ายไฟที่มีความต้านทานที่คงที่. ทุกพิน(I/O pins) มี protection diodes ทั้ง VCC and Ground ดังแสดงในรูปต่อไปนี้.



รีจีสเตอร์และบิททั้งหมดที่อ้างอิงในบทนี้ถูกเขียนในรูปแบบทั่วไป. ตัวพิมพ์เล็ก "x" หมายถึงตัวอักษรสำหรับ port นั้นๆ, และตัวพิมพ์เล็ก "n" หมายถึง bit number นั้นๆ อย่างไรก็ตามเมื่อใช้ register หรือ bit กำหนดลงใน program, รูปแบบที่แน่นอนต้องถูกใช้ ตัวอย่างเช่น PORTB3 สำหรับ bit no. 3 ในเอกสารนี้โดยทั่วไปอ้างเป็น PORTxn.

I/O memory address locations ถูกจัดสรรสำหรับแต่ละ port หนึ่งแห่งสำหรับ Data Register – PORTx, Data Direction Register – DDRx, และ Port Input Pins – PINx. Port Input Pins I/O location สามารถอ่านได้เพียงอย่างเดียว ขณะที่ Data Register และ  Data Direction Register ทั้งอ่าน/เขียนได้. อย่างไรก็ตามการเขียน '1' ไปยังบิตหนึ่งใน PINx Register จะทำให้เกิดการสลับ(toggle)ในบิทที่ตรงกันใน Data Register. นอกจากนี้บิท Pull-up Disable – PUD bit ใน MCUCR จะปิดการใช้งานฟังชั่น pull-up ของทุกพินในทุก ports เมื่อเซทบิทนี้ให้เป็น"1".

การใช้ I/O port เป็น Digital I/O ทั่วไป ถูกอธิบายในส่วนถัดไปนี้ "Ports as General Digital I/O"  พิน(port pins)โดยมากแล้วใช้ร่วมกันกับหน้าที่ทางเลือกอื่น (alternate functions อย่าง usart, spi i2c) สำหรับอุปกรณ์ต่อพ่วงต่างๆ บน mcu นี้. แต่ละ alternate function เกี่ยวข้องกับพิน(port pin)อย่างไร ถูกอธิบายใน Alternate Port Functions section ในบทนี้.  โปรดดูในบทเป็นรายโมดูลไป(usart, spi i2c) สำหรับการคำอธิบายที่ครอบคลุมทั้งหมดของ alternate functions

การเปิดใช้งาน alternate function ของบางพิน( port pins) ไม่มีผลกระทบต่อการใช้งานพินอื่นๆใน port นี้ที่ใช้เป็น general digital I/O.

ปล. จำไม่ได้แล้ว เลยเริ่มใหม่เลย แน่นดี หมู่นี้ครึ้มฟ้าครึ้มฝน ถึงไม่มีแอร์ก็พอจะไปได้

tha

ดูรถกระบะในยูทูปมากไปหน่อย มันเลยขึ้นแทรกโฆษณา ford ranger ในหน้านี้เลย ยุคเทคโนโลยี่มันดีไหมนี่ ทำคนตกอยู่ในความอยากตลอดเลย ต้องดิ้นรนหาเงินไปสิ อยากได้นี่ ทุกข์หรือสุขกันแน่เนี้ย มันดาบสองคมไหมนี่ จะเอาเงินไปทำอะไรนักหนาหล่ะเจ้ากูเกิ้ล ติงๆไว้ว่าคิดถูกไหม

tha

18.2. Ports เป็น General Digital I/O
ports นี้เป็นพอร์ตอินพุทเอ๊าพุทสองทิศทาง (bi-directional I/O ports) พร้อมด้วยทางเลือก pull-ups ภายใน. รูปต่อไปนี้แสดงการอธิบายหน้าที่ของ I/O-port pin อันหนึ่ง, ในที่นี้เรียกว่า Pxn.



หมายเหตุ: 1. WRx, WPx, WDx, RRx, RPx, and RDx ใช้ร่วมกันทุก pins ภายใน port เดียวกัน. clkI/O, SLEEP, and PUD ใช้ร่วมกันทุก ports.

ปล. ลองไล่การทำงานของวงจรได้หรือเปล่า ไม่น่าจะยากนะ


tha

จะลองอธิบายดู ยากเหมือนกันอธิบาย

ดูที่ตัว pull-up ก่อนว่าเป็นยัง ก็จะเป็นว่า
          บิท pud (pull-up disable) ต้องเป็น "0"
          DDR data direction register ต้องเป็น "0" (เป็นอินพุท)
          PORT data register ต้องเป็น "1"
ถึงจะ pull-up ของบิทนั้นทำงานใช่ไหม

ดูที่ตัว D-flipflop ตัวบน เป็น DDRx (data direction register) ควบคุมการเป็น input หรือ output ใช่ไหม
   ถ้าใน data bus บิทนี้เป็น "1" มา พร้อมกับมีสัญญาน WDx (Write DDRx) ก็จะมีสัญญานออกที่ Q เป็น "1" ไป ทำให้เกตเปิด เป็น output ใช่ไหม
   แต่ถ้าใน data bus บิทนี้เป็น "0" มา พร้อมกับมีสัญญาน WDx (Write DDRx) ก็จะมีสัญญานออกที่ Q เป็น "0" ไป ทำให้เกตปิด เป็น input ใช่ไหม
   แล้วก็มีเกตสำหรับ Read DDR โดยเมื่อมีสัญญาน RDx (Read DDRx) ทำให้ค่าบิทนี้มาอยู่บน data bus ทำให้เราสามารถเช็คทิศทางของพินได้ว่าเป็น input หรือ output

ดูที่ตัว D-flipflop ตัวถัดมา เป็น PORT (data register) ควบคุมบิทนี้ให้เป็น "0" หรือ "1" เมื่อเป็น output ใช่ไหม
   ถ้าใน data bus บิทนี้เป็น "1" มา พร้อมกับมีสัญญาน WRx (Write PORTx) ก็จะมีสัญญานออกที่ Q เป็น "1" ไป ทำให้ output บิทนี้เป็น "1" (output high) ใช่ไหม
   แต่ถ้าใน data bus บิทนี้เป็น "0" มา พร้อมกับมีสัญญาน WRx (Write PORTx) ก็จะมีสัญญานออกที่ Q เป็น "0" ไป ทำให้ output บิทนี้เป็น "0" (output low) ใช่ไหม
   ถ้าใน data bus บิทนี้เป็น "1" มา พร้อมกับมีสัญญาน WPx (Write PINx Register) บิทนี้ก็จะ toggle ใช่ไหม ลองไล่ดูอธิบายยาก
   แล้วก็มีการอ่านค่าบิทนี้กลับมาที่ data bus เมื่อมีสัญญาน RRx (Read PORTx Register)

แล้วมาดูที่ D-flipflop สองตัว (Synchronizer) เป็น PINx (Port Input Pin)
   เมื่อสัญญาน clkio เป็น "1" แล้วกลับไปเป็น "0" อีกที สัญญานของพินนี้ถึงจะออกมาจาก Synchronizer ใช่ไหม ดูจะงงๆหน่อย ไม่รู้เหตุผลว่าเขาทำแบบนี้ทำใม แล้วเมื่อมีสัญญาน RPx (Read PORTx Pin) ค่าของพินนี้ถึงจะอ่านไปสู่ data bus ใช่ไหม
   ส่วน sleep อะิบายไม่ถูกนะ คงจะมีผล เมื่อเราเให้เข้าสู่โหมด sleep แล้วปิดบิทนี้เพื่อประหยัดพลังงาน

tha

Synchronizer  สัญญาน clkio เป็น "0" แล้วกลับไปเป็น "1" อีกที สัญญานของพินนี้ถึงจะออกมาจาก Synchronizer หรือเปล่า ไปดู d-flipflop ตัวบนมา น่าจะเป็นแบบนี้นะ ผิดอยู่ไม่รู้ท่านใดบอกมา ขอบคุณครับ มีพรายกระซิบบอกนี่แน่นอนจริงๆ  ;D

tha

ค่าของพินที่อ่านได้ ก็จะไม่ใช่ค่าของพินขณะนั้นทันทีสิใช่ไหม ก็เป็นค่าที่หน่วงช้าไป 1 clock (clkio) สิใช่ไหม สงัสยพรายกระซิบบอกมาอีกแล้ว เอ๊ะไม่รู้เขาออกแบบมาแบบนี้ทำใม เพื่อแก้ปัญหาอะไร อ่านไปต่อข้างหน้าจะมีคำอธิบายไว้ไหม ลองอ่านดูไปก่อนก็ได้นะครับ

tha

18.2.1. Configuring the Pin ( การกำหนดค่า Pin)

แต่ละพิน(port pin) ประกอบด้วย 3 register bits: DDxn, PORTxn, และ PINxn. ดังแสดงใน Register Description หน้า 100, DDxn bits ถูกเข้าถึงที่ DDRx I/O address, PORTxn bits ที่ PORTx I/O address, และ PINxn bits ที่ PINx I/O address.
DDxn bit ใน DDRx Register จะเลือกทิศทางของ pin นี้. ถ้า DDxn ถูกเขียนเป็น '1', Pxn ถูกกำหนดเป็น output pin. ถ้า DDxn ถูกเขียนเป็น '0', Pxn ถูกกำหนดเป็น input pin.

ถ้า PORTxn ถูกเขียนเป็น '1' เมื่อ pin นั้นถูกกำหนดเป็น input pin, pull-up resistor จะถูกเปิดใช้งาน. เพื่อเปลี่ยน pull-up resistor เป็นปิดใช้งาน, PORTxn ต้องถูกเขียนเป็น '0' หรือ pin นั้นต้องถูกกำหนดเป็น output pin. port pins จะเป็น tri-stated เมื่อ reset condition ทำงาน, ถึงแม้ว่าสัญญานนาฬิกาไม่ได้รันอยู่ก็ตาม.

ถ้า PORTxn ถูกเขียนด้วย '1' เมื่อ pin นั้นถูกกำหนดเป็น output pin, port pin นั้นจะถูกขับให้เป็นสูง(ให้เป็น1). ถ้า PORTxn ถูกเขียนด้วยลอจิก "0" เมื่อ pin นั้นถูกกำหนดเป็น output pin, port pin นั้นจะถูกขับให้เป็นต่ำ(ให้เป็น 0).

18.2.2. Toggling the Pin (การสลับค่า PIN)

การเขียน '1' ไปยัง PINxn จะสลับค่าของ PORTxn, โดยเป็นอิสระจากค่าของ DDRxn. คำสั่ง SBI(set bit instruction) สามารถถูกใช้สลับค่าของหนึ่ง bit เดี่ยวใน a port .

18.2.3. Switching Between Input and Output(การสวิทช์ระหว่าง  Input และ Output)

เมื่อสวิทช์ระหว่าง tri-state ({DDxn, PORTxn} = 0b00) และ output high ({DDxn, PORTxn} = 0b11), สถานะระหว่างกลางอย่างใดอย่างหนึ่ง pull-up enabled {DDxn, PORTxn} = 0b01) หรือ output low ({DDxn, PORTxn} = 0b10) ต้องเกิดขึ้น. โดยปกติ, pull-up enabled state เป็นที่ยอมรับอย่างสมบูรณ์ในฐานะ a highimpedance environment จะไม่สังเกตเห็นความแตกต่างระหว่าง strong high driver และ pull-up. หากไม่เป็นเช่นนั้น, บิท PUD bit ใน the MCUCR Register สามารถถูกเซทเพื่อปิดใช้งานl pull-ups ทั้งหมดในทุก ports.

การสวิทช์ระหว่าง input with pull-up และ output low จะเกิดปัญหาเดียวกัน. ผู้ใช้ต้องใช้ tri-state ({DDxn, PORTxn} = 0b00) หรือ  output high state ({DDxn, PORTxn} = 0b11) เป็นขั้นตอนกลาง

ตารางต่อไปนี้แสดงรวบยอด control signals สำหรับ pin value.



ปล. ช่วงนี้มีของเก่าอยู่ เลยได้เยอะหน่อย เดี๋ยวจะลองโปรแกรมมีสวิทช์แล้วใช้การ pull-up ดู
เดี๋ยวจะลองลง CodeVision AVR v3.14 ดู มีอยู่ในนี้แหละ สงสัยพรายกระซิบบอกมาอีกแล้ว แต่ไม่ทำโปรเจ็คในนี้หรอกนะ จะทำใน AVR Studio 4 นะเพราะเป็นตัวฟรี

tha

http://www.mediafire.com/file/ttp7mrzsintlyj7/Switch_1.rar/file
ตัวอย่างนี้เป็นตัวอย่างสวิทช์ปุ่มกด ใช้ตัวต้านทานภายนอกพูลอัฟนะครับ รูปแบบก็เป็นแบบมาตรฐาน ก็เอาตัวอย่างมาจากในหนังสือไมโครฯ AVR

http://www.mediafire.com/file/mbi83k30j5apuy7/Switch_pull-up.rar/file
ตัวอย่างนี้เป็นตัวอย่างสวิทช์ปุ่มกด ใช้การพูลอัฟภายในแล้วนะครับ อย่าลืมถอดตัวต้านทานภายนอกพูลอัฟออกด้วยหล่ะ


ปล. Codevision ผมลงตัวทดลองใช้ Evaluation นะ http://www.hpinfotech.ro/cvavr-download.html ได้ 4Kbytes แต่คอมไพล์เป็นภาษา Assembly ให้ด้วยใช่ไหม ดูแล้วเล่นยากอยู่ ค่อนข้างยุ่งยาก ลงไปก่อนเผื่อได้ใช้ครับ