การทำให้บัสที่ใช้ร่วมกันทำหน้าที่เป็น OR


10

สำหรับคนที่ใจร้อนคุณสามารถข้ามพื้นหลังได้

พื้นหลัง

ฉันกำลังเขียนโปรแกรมชุดไมโครคอนโทรลเลอร์ที่สื่อสารกับ SPI มีเจ้านายและnทาสหนึ่งคนที่แชร์รถบัส ไม่มีการเลือกชิป (ไม่ใช่การออกแบบที่ไม่ดี แต่nมีขนาดใหญ่และมีพื้นที่ไม่เพียงพอสำหรับnบรรทัดเพิ่มเติม)

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

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

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

แม้ว่าจะมีปัญหาอย่างหนึ่ง การตอบกลับแบบรวมจำเป็นต้องเป็นตรรกะหรือ (หรือตรรกะ AND) ของการตอบกลับทั้งหมด ฉันได้รับแจ้งว่าสามารถกำหนดค่าสายในลักษณะที่บัส MISO สามารถทำหน้าที่เป็นตรรกะหรือ สิ่งที่ฉันบอกคือ:

  • ตั้งค่า MISO เป็น master เป็น Pull-up และ
  • ตั้ง MISO บนทาสทุกคนเป็นแบบเปิด

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

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

คำถาม

คำถามของฉันคือถ้าเป็นไปได้และถ้าเป็นเช่นนั้นฉันจะกำหนดค่าหมุดอินพุตและเอาต์พุตของต้นแบบและทาสได้อย่างไรเพื่อให้สาย MISO ที่ใช้ร่วมกันทำหน้าที่เป็นตรรกะ OR (หรือตรรกะ AND)


แก้ไข

  1. ปรากฎว่ามันกลายเป็น OR ด้วยตรรกะเชิงลบจริง (โดยทั่วไปคือ AND)

  2. ปัญหาของบ่าวคนเดียวได้รับการแก้ไขโดยการเขียน 1 ไปที่ขาดึงขึ้นบนต้นแบบ ก่อนหน้านี้มีสถานะเริ่มต้นเป็น 0

แก้ไข 2

กลายเป็นทาส ST แทนที่การตั้งค่า GPIO ของ MISO ของฉันเป็น open-drain และถูกบังคับให้สูงเมื่อมีคนเขียน ฉันตัดสินใจปิดปาก SPI และส่งมอบ MISO ในกรณีนี้ด้วยตนเอง


ฉันเกลียดที่จะถามเพราะฉันแน่ใจว่าคุณคิด แต่คุณได้พิจารณาใช้ I2C หรือ CAN? พวกเขาถูกออกแบบมาสำหรับอุปกรณ์ n ในขณะที่ SPI ถูกออกแบบมาเพื่อใช้กับชิปที่เลือกสำหรับแต่ละอุปกรณ์
บ๊อบ

@ บ๊อบใช่ พวกมันช้าเกินไป อย่างไรก็ตามถ้าคำตอบสำหรับคำถามของฉันคือ "มันเป็นไปไม่ได้" เราก็แค่ต้องทำงานด้วยตนเองเล็กน้อย แต่ก็ยังมีผลิตภัณฑ์ที่ดีกว่า SPI
Shahbaz

1
มันน่าเสียดายที่คุณใช้ 32 บิตเป็นที่อยู่เพราะถ้าคุณใช้ 24 บิต (16,772,216 รูปแบบ) คุณสามารถส่งคำสั่ง "Discover" และรอนาฬิกา 16,772,216 และคุณสามารถมีข้อมูลทาสทั้งหมดของคุณ ที่ 10Mbps นั้นจะใช้เวลาน้อยกว่า 2 วินาทีและไม่มีการปะทะกันที่จะคิดออก เฮ้โฮ - คุณทำให้ฉันคิดอย่างนั้น +1
Andy aka

@Andyaka 24 บิตอาจไม่เลว (แต่ 32 บิตดีกว่าแน่นอน) ถ้าฉันเข้าใจคุณถูกต้องคุณหมายถึงทาสแต่ละคนตอบนาฬิกาของมันด้วยนาฬิกา 1 อันและอาจารย์ดูนาฬิกาที่สร้างนาฬิกาหรือไม่? มันไม่ได้เลวร้ายยกเว้นทาสที่ตอบสนองเป็นไบต์ ดังนั้นทาสแต่ละคนตอบสนองด้วย 8 บิตและถ้าฉันไม่สามารถทำให้รถบัสทำหน้าที่เป็นหรือยังคงคำตอบจากทาสคนหนึ่งได้รับ "หลงทาง" ภายในการตอบสนองโดยทาสอื่น ๆ (1 จากทาสคนหนึ่งถูกดึงลงโดย 0 จากทั้งหมด ส่วนที่เหลือ).
Shahbaz

@Shahbaz หากคุณควบคุมรหัสของทาสคุณสามารถทำให้มันเป็น "พิเศษ" ที่ซึ่งทาสตอบสนองเพียง 1 บิตในเวลาที่จัดสรร ใช่คุณได้รับส่วนสำคัญของเพลงของฉัน
แอนดี้อาคา

คำตอบ:


5

SPI-without-select ของคุณคือสิ่งที่ Microchip ใช้กับชิป MCP23017 (และอื่น ๆ ) ไม่มีอะไรผิดปกติกับวิธีการนั้น

ใช่สิ่งที่คุณต้องการเป็นไปได้ แต่คุณต้องให้ทาสเป็นแบบเปิดโล่ง คุณสามารถโกงได้โดยใส่ไดโอด (schottky) เป็นอนุกรมกับเอาต์พุตแต่ละตัวหากคุณไม่สามารถทำให้มันทำงานแบบ open-drain ได้

วิธีการแจงนับของคุณเป็นวิธีเดียวกับที่ใช้โดยรถบัส one-wire ของ Dallas สำหรับการแจงนับและรถบัส CAN สำหรับการอนุญาโตตุลาการ

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

หากคุณมีสองพินที่จะสำรองทาสแต่ละตัวคุณสามารถใช้โซ่เดซี่และมีรูปแบบการแจกแจงตามตำแหน่งในห่วงโซ่เดซี่


ใช่ฉันลืมที่จะพูดถึงฉันยังบอกด้วยว่าฉันต้องลดความเร็วลง (ซึ่งฉันทำได้ประมาณ 20 เท่า (ลดลงจาก 4Mpbs เป็น 128Kbps)) นั่นเป็นระยะเริ่มต้นและอัลกอริทึมของฉันสามารถจัดการกับความเร็วที่ช้าลงได้ (มันค่อนข้างเร็ว) น่าเสียดายที่ฉันสงสัยว่าเราต้องการออกแบบฮาร์ดแวร์ใหม่ตอนนี้ ค่าใช้จ่ายเป็นมากกว่าเพียงแค่เพิกเฉยขั้นตอนนี้และแจ้งให้นายทราบถึงรหัสที่คาดหวัง
Shahbaz

กลับไปที่คำถามฉันได้กำหนดค่าทาสเป็น open-drain แล้ว ฉันจะกำหนดค่าหลักได้อย่างไร
Shahbaz

1
ไม่มีอะไรพิเศษที่พิน MISO ของมาสเตอร์ยกเว้น pullup ฉันสงสัยว่าคุณจะไปถึง 128Kbps ด้วยการออกแบบแบบเลื่อนขึ้น แต่ YMMV การอ่านเอกสาร I2C เชิงลึกบางอย่างอาจช่วยได้นั่นก็คือรถบัสแบบ wire หรือ pull-up ดังนั้นเคล็ดลับทุกอย่างที่นำมาใช้อาจช่วยคุณได้
Wouter van Ooijen

ขอบคุณมาก. ฉันจะพยายามทำให้รถช้าลงเพื่อดูว่าเกิดอะไรขึ้น ฉันคิดว่าในที่สุดฉันต้องศึกษาและทำความเข้าใจว่าสิ่งเหล่านี้จริง ๆ แล้วเป็นแบบ pull-up, open-drain และอื่น ๆ (วิศวกรซอฟต์แวร์ที่นี่!)
Shahbaz

1
วางออสซิลโลสโคปไว้บนรถบัสแล้วตรวจดูว่าเกิดอะไรขึ้น เวลาที่เพิ่มขึ้นอาจช้าเกินไป แต่อาจมีเสียงดังได้เช่นกัน
Wouter van Ooijen

4
  • ตั้งค่า MISO เป็น master เป็น Pull-up และ
  • ตั้ง MISO บนทาสทุกคนเป็นแบบเปิด

ฉันเคยลองมาแล้ว แต่ถึงแม้จะเป็นแค่ทาสคนเดียวการปรับแต่งนี้ก็ใช้ไม่ได้ (ออสซิลโลสโคปแสดงค่าคงที่เป็นศูนย์ในบรรทัด)

คุณต้องตรวจสอบว่าอะไรคือความต้านทานเทียบเท่าของขา i / o หลักในโหมดพูลอัพ

โดยทั่วไปแล้วโหมด pull-up มีความต้านทานสูงมากอาจจะ 50 kOhms หรือสูงกว่า มันมีจุดประสงค์เพื่อป้องกันไม่ให้เข็มหลุดเนื่องจากอีเอ็มไอหรือเสียงอื่น ๆ หรือเพื่อตั้งค่าเริ่มต้นสำหรับสัญญาณควบคุมที่ช้ามากและในเวลาเดียวกันก็ไม่ต้องเปลืองพลังงานมากเกินไปในการทำเช่นนั้น

เมื่อ Wouter ชี้ไปที่บัส open-drain ความเร็วจะถูก จำกัด โดยตัวต้านทานแบบดึงขึ้น ค่าตัวต้านทานที่สูงขึ้นทำให้บัสช้าลง ค่าทั่วไปใน I2C (ซึ่งรับ 100 หรือ 400 kHz) คือ 1 ถึง 5 kOhms คุณจะต้องการความต้านทานแบบดึงขึ้นที่คล้ายกันเพื่อให้ได้ความเร็วที่ใกล้เคียงกัน

ฉันคิดว่าคุณต้องใช้ตัวต้านทาน pull-up ภายนอก (จาก 1 ถึง 5 kOhms หรือมากกว่านั้น) แทนที่จะใช้ i-o pin pull-up ของต้นแบบเพื่อให้โครงร่างนี้ทำงาน


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

หากคุณมี pin i / o ฟรีหนึ่งตัวบน micro master คุณสามารถเชื่อมต่อกับบัสได้โดยบอกว่า 5 kOhms จากนั้นหมุนให้สูงในระหว่างการแจงนับบัสและทำให้สูง -Z ในระหว่างการสื่อสารปกติ
โฟตอน

1

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

  • ตรรกะลดลงโดยการดึงลงอย่างมากและ
  • ตรรกะสูงโดยตัดการเชื่อมต่อจากบัส

นอกจากนี้รถบัสจะต้องดึงขึ้นอย่างอ่อน

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

คุณต้องพิจารณาว่าสิ่งใดที่เกิดขึ้นข้างต้น

ใส่ทาสเข้าสู่โหมดความต้านทานสูงและเชื่อมต่อบัสกับกราวด์ผ่านตัวต้านทาน 10k หากแรงดันไฟฟ้าของสายไม่เปลี่ยนแปลงอย่างมีนัยสำคัญต้นแบบจะถูกดึงขึ้นมาอย่างรุนแรงและคุณจำเป็นต้องแก้ไข มิฉะนั้นให้ทำตามขั้นตอนเดียวกันกับทาส (คราวนี้เชื่อมต่อตัวต้านทานกับ Vcc); หากแรงดันไฟฟ้าเพิ่มขึ้นอย่างมีนัยสำคัญทาสจะถูกดึงลงมาเล็กน้อย (แก้ไข) มิฉะนั้นให้มองหาการบิดเบือนเวลาในพื้นที่รอบ ๆ ตัวคุณ


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

@Shahbaz แย่มากแน่นอนว่ารถบัสจะเป็นแบบมีสายและฉันก็แก้ไขคำตอบ หากคุณต้องการแบบมีสายหรือเพียงแค่กลับขั้ว (ปรมาจารย์ดึงลงมาเบา ๆ ทาสดึงขึ้นอย่างรุนแรง)
avakar

การอ่านในวิกิพีเดียฉันรู้ว่าพวกเขาอ้างถึงมันเป็นแบบใช้สายและแบบใช้สายหรือมีตรรกะเชิงลบจริง
Shahbaz

1

ฉันอยากจะแนะนำให้มีการดึงขึ้นหรือดึงลงบนรถบัสเรื่อย ๆ (ฉันจะถือว่าเป็นแบบเลื่อนขึ้น) และมีทาสขับรถอย่างแข็งขัน (ขับรถสูงและขับต่ำ) เมื่อพวกเขามีอะไรจะพูดและลอยมันเป็นอย่างอื่น . มีคำสั่งที่อยู่แบบสอบถามซึ่งใช้ที่อยู่และมาสก์และสั่งให้สลาฟแต่ละอันส่งออก 00 หรือไม่ทำอะไรเลย (ลอยเอาท์พุทของมัน) ตามว่ามันชอบที่อยู่และรูปแบบ ถ้าเป็นไปได้ให้นายขับรถบัสให้สูงก่อนที่ทาสจะเริ่มขับมัน ขึ้นอยู่กับความแรงของการดึงขึ้นและการที่อาจารย์ขับรถบัสสูงก่อนที่ทาสจะได้รับอนุญาตให้ดึงต่ำอาจจำเป็นต้อง จำกัด ความเร็วบัสในระหว่างขั้นตอนการตั้งค่า ในทางกลับกันเมื่อการตั้งค่าเสร็จสมบูรณ์


หากทาสสองคนขับรถสูงและต่ำฉันคาดหวังอะไรจากรถบัส?
Shahbaz

หนึ่งควรหลีกเลี่ยงการมีทาสหนึ่งพยายามขับสูง ทาสควรขับรถบัสเมื่อ (1) รู้ว่ามันจะเป็นเพียงสิ่งเดียวที่ทำเช่นนั้นหรือ (2) รู้ว่ามันและทุกคนที่ขับรถจะต้องขับรถไปทางตรงข้ามกับที่ไม่ได้ใช้งาน สถานะ.
supercat

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

@Shahbaz: เมื่อมีทาสพูดอะไรก็ควรขับรถบัสให้สูงเพื่อส่งบิต "1" และต่ำเพื่อส่ง "0" บิต เมื่อทาสไม่มีอะไรจะพูดก็ไม่ควรขับรถบัสเลย โปรดทราบว่าการมีทาสขับรถบัสสูงเมื่อพวกเขาต้องการส่งบิต "1" จะช่วยให้รถบัสทำงานได้เร็วกว่าที่ต้องพึ่งพาการดึงขึ้นเรื่อย ๆ เพื่อขับรถบัสสูง
supercat

@Shahbaz: สิ่งที่ supercat พยายามที่จะพูดคือว่าในสถานะการนับตัวต้านทานควรดึงขึ้นบรรทัดและทาสควรส่ง "0" หรืออะไร (เปิดท่อระบายน้ำออก) แต่หลังจากนั้นในการสื่อสารปกติเพียง สลาฟเดี่ยวควรแอ็คทีฟทีละครั้งและสลาฟที่แอ็คทีฟควรส่ง "0" หรือ "1" (เอาต์พุตปกติ) ดังนั้นตัวต้านทานแบบดึงขึ้นและความจุของเส้นจะ จำกัด อัตราบิตระหว่างการแจงนับเท่านั้น หลังจากนั้นในการสื่อสารตามปกติอัตราบิตอาจสูงขึ้นได้เนื่องจากการขับขี่แบบแอ็คทีฟอนุญาต
Laszlo Valko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.