ดันดึง / เปิดท่อระบายน้ำ; ดึงขึ้น / เลื่อนลง


49

ฉันกำลังอ่านแผ่นข้อมูลของชิป ARM Cortex โดยเฉพาะบท GPIO ในที่สุดฉันต้องการกำหนดค่าหมุด GPIO ต่างๆเพื่อใช้ในโหมด "ฟังก์ชันสำรอง" สำหรับการอ่าน / เขียนการเข้าถึง SRAM

จากการลงทะเบียน GPIO ทั้งหมดที่มีอยู่ฉันไม่เข้าใจสิ่งที่สอง: GPIO_PUPDRและGPIO_OTYPEซึ่งตามลำดับคือ "pull-up / pull-down register" และ "register type output"

สำหรับGPIO_PUPDRฉันมีสามทางเลือก:

  • ไม่มีการดึงขึ้นหรือดึงลง
  • ดึงขึ้น
  • ดึงลงมา

สำหรับGPIO_0TYPEฉันมีสองทางเลือก:

  • เอาท์พุทดึง
  • เอาท์พุทเปิดท่อระบายน้ำ

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

เอกสารสำหรับคณะกรรมการที่ฉันทำงานอยู่สามารถดูได้ที่นี่ (ดูหน้า 24 สำหรับแผนงาน SRAM) คู่มืออ้างอิงสำหรับชิป ARM มีอยู่ที่นี่ (ดูหน้า 145 และ 146 สำหรับการลงทะเบียน GPIO)


คุณสามารถจัดหาหมายเลขรุ่น / ลิงค์ไปยังเอกสารข้อมูลทางเทคนิคของ SRAM และ ARM CPU ของคุณโดยใช้
ดีน

@Dean: แน่นอน ฉันได้อัปเดตคำถามของฉันด้วยลิงก์สองลิงก์
Randomblue

คำตอบ:


54

คำตอบนี้เป็นเรื่องทั่วไปสำหรับโปรเซสเซอร์และอุปกรณ์ต่อพ่วงและมีความคิดเห็นเฉพาะ SRAM ในตอนท้ายซึ่งอาจเกี่ยวข้องกับ RAM และ CPU เฉพาะของคุณ

สามารถขับเคลื่อนหมุดเอาต์พุตในโหมดที่แตกต่างกันสามโหมด:

  • open drain - ทรานซิสเตอร์เชื่อมต่อกับต่ำและไม่มีอะไรอื่น
  • ท่อระบายน้ำเปิดพร้อมดึงขึ้น - ทรานซิสเตอร์เชื่อมต่อกับต่ำและตัวต้านทานเชื่อมต่อกับสูง
  • push-pull - ทรานซิสเตอร์เชื่อมต่อกับสูงและทรานซิสเตอร์เชื่อมต่อกับต่ำ (เพียงครั้งเดียวจะดำเนินการในเวลา)

พินอินพุตสามารถเป็นอินพุตเกตด้วย:

  • pull-up - ตัวต้านทานที่เชื่อมต่อกับสูง
  • pull-down - ตัวต้านทานที่เชื่อมต่อกับต่ำ
  • pull-up และ pull-down - ทั้งตัวต้านทานที่เชื่อมต่อกับสูงและตัวต้านทานที่เชื่อมต่อกับต่ำ (มีประโยชน์เฉพาะในกรณีที่หายาก)

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

ท่อระบายน้ำแบบเปิดมีประโยชน์เมื่อมีการเชื่อมต่อประตูหรือหลายขาพร้อมกับดึงขึ้น (ภายนอกหรือภายใน) หากพินทั้งหมดมีค่าสูงพวกมันจะเป็นวงจรเปิดทั้งหมดและตัวดึงจะผลักให้พินสูง หากพินใดที่ต่ำพวกมันก็จะต่ำลงไป การกำหนดค่านี้เป็นANDประตูได้อย่างมีประสิทธิภาพ

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

ด้วย SRAM ที่มีอินพุตข้อมูลจาก SRAM หาก RAM IC ทำการตรวจสอบข้อมูลอยู่เสมอพินที่ไม่มีการดึงอาจเป็น OK เนื่องจาก RAM ตั้งค่าระดับเสมอและสิ่งนี้จะลดภาระให้น้อยที่สุด หากบางครั้งสายข้อมูล RAM เป็นวงจรแบบเปิดหรือ tristate คุณจะต้องใช้หมุดอินพุตเพื่อให้สามารถตั้งค่าสถานะที่ถูกต้องได้ ในการสื่อสารที่มีความเร็วสูงมากคุณอาจต้องการดึงขึ้นและดึงลงเพื่อให้ความต้านทานแบบขนานที่มีประสิทธิภาพคือความต้านทานที่สิ้นสุดและแรงดันไฟฟ้าไม่ได้ใช้งานบัสถูกกำหนดโดยตัวต้านทานสองตัว แต่นี่เป็นผู้เชี่ยวชาญ


เพื่อให้ชัดเจนคุณหมายถึงอะไรโดย "ทรานซิสเตอร์เชื่อมต่อกับต่ำและไม่มีอะไรอื่น"? ทรานซิสเตอร์มี 3 พิน ขาแต่ละอันเชื่อมต่อกันอย่างไร?
Randomblue

@ Randomblue - ขอโทษ - ตัวเก็บประจุทรานซิสเตอร์หรือท่อระบายน้ำเมื่อทำหน้าที่เป็นเอาท์พุท
รัสเซลแม็คมาฮอน

เพื่อชี้แจงคำตอบของคุณในการ "ดึงลง" อะไรคือความแตกต่างระหว่าง "กราวด์", "ต่ำ" และ "-ve"
Randomblue

ฉันได้ทำการแก้ไขคำถามของคุณมากมายคุณช่วยโปรดตรวจสอบว่าฉันไม่ได้ทำผิดพลาดได้หรือไม่?
Randomblue

@ Randomblue - การแก้ไขดูเหมือนจะดี มันทำให้ฉันสงสัยในสิ่งที่ฉันเขียนตอนแรก? คุณดูเหมือนจะพูดในสิ่งที่ฉันคิดว่าฉันคิดว่า :-)
รัสเซลแม็คมาฮอน

17

ฉันพบคำตอบนี้จากSTM32 การทำความเข้าใจการตั้งค่า GPIO

  • GPIO_PuPd (ดึงขึ้น / ดึงลง)

ในวงจรดิจิตอลเป็นสิ่งสำคัญที่ไม่อนุญาตให้สายสัญญาณ "ลอย" กล่าวคือพวกเขาต้องอยู่ในสถานะที่สูงหรือต่ำเสมอ เมื่อลอยตัวสถานะจะไม่ถูกระบุและทำให้เกิดปัญหาที่แตกต่างกันสองสามชนิด

วิธีการแก้ไขสิ่งนี้คือการเพิ่มตัวต้านทานจากสายสัญญาณไปยัง Vcc หรือ Gnd ด้วยวิธีนี้หากเส้นไม่ได้ถูกผลักดันอย่างสูงหรือต่ำตัวต้านทานจะทำให้มีแนวโน้มที่จะลอยไปสู่ระดับที่รู้จัก

ARM (และไมโครคอนโทรลเลอร์อื่น ๆ ) มีวงจรในตัวเพื่อทำสิ่งนี้ ด้วยวิธีนี้คุณไม่จำเป็นต้องเพิ่มส่วนอื่นในวงจรของคุณ หากคุณเลือก "GPIO_PuPd_UP" มันจะเท่ากับการเพิ่มตัวต้านทานระหว่างสายสัญญาณและ Vcc

  • GPIO_OType (ประเภทขาออก):

พุช - พุช: นี่เป็นประเภทเอาต์พุตที่คนส่วนใหญ่คิดว่าเป็น "มาตรฐาน" เมื่อเอาท์พุทต่ำลงมันจะถูก "ดึง" ไปที่กราวด์ ในทางกลับกันเมื่อเอาต์พุตถูกตั้งค่าเป็นสูงจะมีการ "ผลัก" ไปยัง Vcc อย่างแข็งขัน ง่ายขึ้นดูเหมือนว่านี้: ป้อนคำอธิบายรูปภาพที่นี่

ในทางกลับกันเอาต์พุตของ Open-Drain จะทำงานในทิศทางเดียวเท่านั้น มันสามารถดึงพินไปที่พื้น แต่ไม่สามารถขับได้สูง ลองนึกภาพก่อนหน้านี้ แต่ไม่มี MOSFET ด้านบน เมื่อมันไม่ได้ถูกดึงลงกราวด์ MOSFET (ด้านล่าง) จะไม่นำไฟฟ้าซึ่งทำให้เกิดการส่งออกลอย

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

ชื่อนี้มาจากข้อเท็จจริงที่ว่าการระบายของ MOSFET ไม่ได้เชื่อมต่อกับสิ่งใดภายใน เอาต์พุตประเภทนี้เรียกอีกอย่างว่า "open-collector" เมื่อใช้ BJT แทน MOSFET

  • GPIO_Speed

โดยพื้นฐานแล้วสิ่งนี้จะควบคุมอัตราการฆ่า (เวลาเพิ่มขึ้นและเวลาตก) ของสัญญาณเอาต์พุต ยิ่งอัตราการฆ่าเร็วขึ้นเท่าไหร่เสียงก็ยิ่งเปล่งออกจากวงจรมากขึ้นเท่านั้น เป็นวิธีปฏิบัติที่ดีที่จะรักษาอัตราการฆ่าช้าและเพิ่มเฉพาะในกรณีที่คุณมีเหตุผลเฉพาะ


3

อีกนิดหน่อย tid-bit: สำหรับไมโครคอนโทรลเลอร์ที่ไม่มีโหมด "open drain" อย่างชัดเจนเช่นบอร์ด AVR และบอร์ด Arduino ATmega328 ที่ใช้ ATmega328 เช่น Uno โหมด "open drain" นี้สามารถจำลองได้โดยการเขียนฟังก์ชั่น wrapper เพียงตั้งพินเป็น "เอาท์พุทต่ำ" เมื่อคุณส่ง0และกำหนดพินเป็น "อินพุตต่ำ" (โหมดอิมพีแดนซ์สูงความต้านทานภายใน pullup - ไม่เปิด) เมื่อคุณส่ง1เมื่อคุณส่งมัน ด้วยวิธีนี้คุณจะได้รับผลกระทบที่เหมือนกัน ไมโครคอนโทรลเลอร์ ARM แบบ 32 บิตที่ทันสมัยเหล่านี้มีตัวเลือกเพิ่มขึ้นมากมาย

ยิ่งไปกว่านั้น p146 ของคู่มืออ้างอิง STM32 ที่เชื่อมโยงไปยังสถานะด้านบน[การเพิ่มเติมของฉันอยู่ในวงเล็บเหลี่ยม] :

- โหมด Open drain: A“ 0” ใน Output register จะเปิดใช้งาน N-MOS [ดังนั้นจึงขับ LOW อย่างแข็งขันโดยเชื่อมต่อพินกับ GND]ในขณะที่“ 1” ใน Output register ออกจากพอร์ตใน Hi-Z (P- MOS ไม่เคยเปิดใช้งาน) [โหมดความต้านทานสูง - เช่นเดียวกับอินพุตแบบลอยที่ไม่มีตัวต้านทานแบบดึงขึ้นหรือเลื่อนลง]

- โหมด Push-pull: A“ 0” ใน Output register จะเปิดใช้งาน N-MOS [ใช้งาน LOW ต่ำโดยการเชื่อมต่อพินกับ GND]ในขณะที่“ 1” ใน Output register จะเปิดใช้งาน P-MOS [แรงขับสูงโดยการเชื่อมต่อ พินถึง VCC]


ในรหัส Arduino ว่า "ฟังก์ชั่น wrapper" สามารถนำไปใช้เช่นนี้:

digitalWriteOpenDrain(byte pin, bool state)
{
    // Actively drive LOW
    if (state==LOW)
    {
        pinMode(pin, OUTPUT);
        digitalWrite(pin, LOW);
    }
    // High impedance mode 
    // (note that an internal or external pull-up resistor can optionally be added if you like, according to your requirements)
    else //state==HIGH
    {
        pinMode(pin, INPUT);
        digitalWrite(pin, LOW);
    }
}

หรือทำให้ง่ายขึ้น:

digitalWriteOpenDrain(byte pin, bool state)
{
    digitalWrite(pin, LOW);

    // Actively drive LOW
    if (state==LOW)
    {
        pinMode(pin, OUTPUT);
    }
    // High impedance mode
    // (note that an internal or external pull-up resistor can optionally be added if you like, according to your requirements)
    else //state==HIGH
    {
        pinMode(pin, INPUT);
    }
}

โปรดทราบว่าในการเปิดตัวต้านทาน pullup ภายในบน Arduino คุณสามารถทำได้:

pinMode(pin, INPUT_PULLUP);

หรือ (สิ่งเดียวกัน):

pinMode(pin, INPUT);
digitalWrite(pin, HIGH);

อ่านเพิ่มเติม:

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.