กดแถวคีย์เดียวกันในเวลาเดียวกัน


9

ฉันกำลังออกแบบปุ่มกดใน VHDL ทุกอย่างทำงานได้ดีเมื่อกดปุ่มเพียงปุ่มเดียว ฉันกำลังสแกนแต่ละคอลัมน์เพื่อกดปุ่มในเครื่องสถานะและเมื่อไม่มีการกดปุ่มซึ่งเป็นเงื่อนไขที่pin4pin6pin7pin2 = "0000"ฉันสลับไปยังสถานะถัดไปเพื่อสแกนคอลัมน์ถัดไป ดังนั้นผมจึงตั้งคอลัมน์pin3pin1pin5ตามลำดับเพื่อ"001", และ"010""100"

ในขณะที่การสแกนpin3pin1pin5เป็น"001"และถ้าpin4pin6pin7pin2เป็น"0100"แล้วก็ "9" ถูกกด ฉันประกาศใน VHDL pin4pin6pin7pin2เป็นอินพุตและpin3pin1pin5พอร์ตเอาต์พุต เมื่อฉันกด 6 และ 9 ในเวลาเดียวกันpin6และมีpin7 highปุ่มกดแรกจะถูกอ่านปุ่มที่สองจะถูกละเว้น เมื่อฉันกด 3 และ 7 ในเวลาเดียวกันคนแรกที่กดด้วยไม่กี่มิลลิวินาทีก่อนที่จะชนะและที่สำคัญคือการอ่านครั้งแรกที่สำคัญที่สองจะถูกละเว้นpin2และมีpin4high

นี่คือส่วนที่ยุ่งยาก. เมื่อฉันกด 4 และ 6 ในเวลาเดียวกันฉันคาดว่าpin7จะเป็นhighแต่มันจะกลายเป็นlowและpin4pin6pin7pin2 = "0000"ซึ่งฉันไม่เข้าใจว่าทำไมและทำไม เนื่องจาก"0000"ตรวจพบว่าไม่มีการกดปุ่มใด ๆ เครื่องของรัฐจะกระโดดจากรัฐหนึ่งไปยังอีกรัฐหนึ่ง ในขณะที่ถือ 4 และ 6 หากผลักดันและใบ 4 หลายครั้งก็จะถูกตรวจพบว่าเป็น 6 กดหลายครั้งซึ่งเป็นปัญหาใหญ่ ฉันจะดีใจถ้าคุณสามารถช่วยฉันแก้ปัญหานี้!

สิ่งเดียวกันเกิดขึ้นกับ "1" และ "2" เหมือนกันกับ "7" และ "8" สำหรับคีย์ในแถวเดียวกันเท่านั้น เนื่องจากนี่เป็นโครงการต่อเนื่องฉันไม่สามารถใส่รหัส VHDL ของฉันทางออนไลน์ได้ :( ฉันจะดีใจถ้าคุณสามารถให้เคล็ดลับแก่ฉันเพื่อเอาชนะสิ่งนี้!

ป้อนคำอธิบายรูปภาพที่นี่

ด้านล่างฉันไม่ได้อัปโหลดรหัสของฉันไปยังบอร์ดไม่มีรหัสกำลังทำงานอยู่ การเชื่อมPin5ต่อกับกราวด์กดเพียงครั้งเดียวบน 1,2,4,5,7,8, *, 0 ไม่ได้เปิดPin3ไฟ LED แต่ถ้าฉันกด 6 แล้ว 4 ในเวลาเดียวกันPin3LED จะติดและPin7LED ยังคงเปิดอยู่ แต่ เมื่อรหัสของฉันกำลังทำงานสิ่งนี้จะไม่เกิดขึ้น บางทีฉันอาจจะเชื่อมต่อบางอย่างผิดปกติและโชคดีPin7ที่ฉันไม่ทราบ ...

ป้อนคำอธิบายรูปภาพที่นี่

ด้านล่างเป็นแผนผังของแผงปุ่มกด:

แผนงาน


คุณจะมั่นใจได้อย่างไรว่าการกด 4 และ 6 ในเวลาเดียวกันไม่ได้ทำให้สั้น 3 และ 5 ด้วยกัน
fru1tbat

@ fru1tbat คุณช่วยอธิบายเพิ่มเติมอีกหน่อยได้ไหม? โดยไม่ต้องอัปโหลดรหัสของฉันเมื่อบอร์ดไม่มีอะไรฉันเชื่อมต่อ pin5 กับกราวด์แล้ว LED pin5 เปิดแล้วฉันกด "6" pin7 LED ติดสว่างในภายหลังฉันกด "4" และ "6" ในเวลาเดียวกัน pin3 ในเวลานี้ LED ติดสว่างและ pin7 LED ยังคงติดสว่าง
Anarkie

@ คุณหมายความว่าฉันควรใช้ pull-up สำหรับแถวและดึงขึ้นสำหรับคอลัมน์หรือไม่ ฉันไม่สามารถปรับเปลี่ยนวงจรได้ นอกจากนี้ยังไม่เข้าใจมากจากความคิดเห็นของคุณ :(
Anarkie

เพื่อให้สมบูรณ์ยิ่งขึ้นฉันจะให้คำตอบ มันจะมีประโยชน์ถ้าคุณสามารถให้วงจรแสดงตัวต้านทาน, LED, ตัวขับคอลัมน์และอินเวอร์เตอร์หรือทรานซิสเตอร์ใด ๆ ที่อาจอยู่ในวงจร 4 แถวและ 3 คอลัมน์เชื่อมต่อโดยตรงกับ CPLD หรือ FPGA หรือไม่
Tut

@Tut แป้นพิมพ์ไม่ได้เชื่อมต่อโดยตรงกับ FPGA ที่มีบอร์ดอื่นอยู่ระหว่างการเชื่อมต่อบอร์ดต่าง ๆ กับ FPGA และฉันเพิ่มแผนงาน
Anarkie

คำตอบ:


4

คำตอบสั้น ๆ :

สลับตรรกะของคุณ ขับเคลื่อนบรรทัดเลือกคอลัมน์ด้วยตรรกะopen-drain (หรือ open-collector)โดยที่คอลัมน์ที่เลือกถูกดึงต่ำและคอลัมน์ที่ไม่ได้เลือกลอยอยู่ เมื่อคุณดูแถวหนึ่งปุ่มกดจะถูกตรวจพบโดย '0' ปุ่มที่ไม่ถูกกดจะถูกตรวจจับโดย '1'

ตอนนี้รายละเอียด:

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

เนื่องจากการเพิ่มไดโอดไม่ใช่ตัวเลือกสำหรับคุณคุณจะต้องลอยเอาท์พุทของคอลัมน์ที่ไม่ใช้งานของคุณเพื่อหลีกเลี่ยงการพยายามขับไปยังขั้วตรงข้ามเมื่อเลือกคอลัมน์ที่ใช้งานของคุณ สิ่งนี้ทำได้โดยใช้ตรรกะ open-drain หากคอลัมน์ที่คุณเลือกนั้นเชื่อมโยงโดยตรงกับ CPLD หรือ FPGA คุณควรจะสามารถทำได้ในโค้ด VHDL ของคุณ

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

ฉันต้องตั้งสมมุติฐานบางอย่างเกี่ยวกับวงจรของคุณเนื่องจากคุณยังไม่ได้เตรียมวงจรที่สมบูรณ์หรือรหัส VHDL ของคุณ คุณพูด

เมื่อไม่มีการกดปุ่มซึ่งเป็นเงื่อนไข pin4pin6pin7pin2 = "0000"

แต่จากภาพที่คุณให้ตัวต้านทานแบบดึงขึ้นจะปรากฏขึ้น นี่หมายความว่าคุณมีการผกผันทางตรรกะอยู่แล้วบางแห่งอาจเป็นในรหัส VHDL ของคุณหรืออินเวอร์เตอร์ (น่าจะน้อยกว่า) ระหว่างแถวของคุณกับอุปกรณ์ลอจิกของคุณ (CPLD หรือ FPGA)

แก้ไข:

ตามความคิดเห็นของคุณคุณกำลังใช้ตรรกะเชิงลบในคำอธิบายของคุณ: "0000" หมายถึงหมุดทั้งสี่นั้นสูง ฯลฯ ในกรณีนี้สมมติว่าคอลัมน์ที่เลือกและสัญญาณแถวเข้าโดยตรงจากตัวเชื่อมต่อ 2 ในแผนผังของคุณไปยัง FPGA เพียง ทำตามคำแนะนำของฉันข้างต้นโดยใช้ตรรกะ open-drain สำหรับคอลัมน์เลือกเอาต์พุตใน FPGA ของคุณ

ฉันไม่ใช่ผู้เชี่ยวชาญ VHDL แต่ฉันพบสิ่งนี้จาก Xilinx :

อนุมานบัฟเฟอร์ของท่อระบายน้ำเปิดโดยใช้รหัสต่อไปนี้:

VHDL:

dout <= 'Z' เมื่อ din = '1' else '0';

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


ฉันกำลังจะสแกนแผนงานที่ติดตั้งไดรเวอร์เครื่องสแกน
Anarkie

คุณมีสิทธิเกี่ยวกับการไม่กดปุ่มเป็นจริงpin4pin6pin7pin2 = "0000" 1111ในคำถามของฉัน 1s ควร 0, 0 ควรเป็น 1s ฉันพยายามเข้ารหัสคำถามนิดหน่อยขออภัยที่ถ้ามันทำให้เกิดความเข้าใจผิด ...
Anarkie

ฉันเพิ่มแผนงาน
Anarkie

ขอบคุณมากสำหรับคำอธิบายของคุณหลังจากอ่านคำตอบของคุณฉันมีความคิด แต่แรกคุณหมายถึงอะไรกับ "คอลัมน์ลอย", "ต้องลอยผลลัพธ์" โดยลอยคุณหมายถึง: 110, 101, 011? สิ่งนี้ฉันกำลังทำอยู่แล้วจริง ๆ แล้วในรหัสของฉันเมื่อกดคีย์อื่น ๆ คีย์ทั้งหมดควรละเว้นฉันไม่เข้าใจว่า LED จะปิดและ pin7 จะสูง (1) ในขณะที่รหัสกำลังทำงานอยู่ อย่างไรก็ตามถ้าฉันเข้าใจถูกต้องก็คือคำตอบของคุณในขณะที่ฉันกำลังสแกน pin5, พอร์ตเอาต์พุต "110", ฉันควรจะได้รับ out <= 'pin3' when din='1' else '0';
Anarkie

1
ดูที่ลิงค์ที่ผมให้: เปิดท่อระบายน้ำ (หรือเปิดสะสม) คอลัมน์ที่ใช้งานอยู่ถูกเลือกโดยการผลักดัน 0V บนบรรทัดคอลัมน์นั้น คอลัมน์ที่ไม่แอ็คทีฟไม่ควรถูกขับเคลื่อนด้วย 3.3V บนบรรทัดนั้น แต่ต้องลอย (ใส่สถานะอิมพีแดนซ์สูง) ซึ่งจะตัดการเชื่อมต่อบรรทัดเหล่านั้นจากวงจรอย่างมีประสิทธิภาพ หากคุณพยายามที่จะผลักดันพวกเขาไปยัง 3.3V, ลัดวงจรที่สร้างขึ้นโดยการกด 2 ปุ่มในแถวเดียวกันในเวลาเดียวกันจะทำให้เกิดความขัดแย้งระหว่างคนพยายามขับต่ำและคนอื่นพยายามขับสูง
ตุ้ย

2

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

ดูคำถามที่ฉันถามเมื่อไม่นานมานี้: VHDL: รับโมดูลสุ่มล้มเหลวเมื่อนับจำนวนบิต

ตอนนี้คุณพูดว่า:

เนื่องจากตรวจพบ "0000" โดยไม่มีการกดปุ่มใด ๆ เครื่องของรัฐจึงกระโดดจากสถานะหนึ่งไปยังอีกรัฐหนึ่ง ในขณะที่ถือ 4 และ 6 หากมีใครผลักและออกจาก 4 หลายครั้งมันถูกตรวจพบว่าเป็น 6 กดหลายครั้งซึ่งเป็นข้อผิดพลาดใหญ่

ซึ่งค่อนข้างคล้ายกับสิ่งที่ฉันเผชิญ ฉันมีปัญหาที่เครื่องของรัฐจะข้ามรัฐซึ่งดูเหมือนเป็นไปไม่ได้

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

ป้อนคำอธิบายรูปภาพที่นี่

การไม่มีปุ่มอินพุตของคุณที่ทำให้ข้อมูลตรงกันกับ HW ของคุณทำให้เกิดปัญหาที่แปลกประหลาดมากซึ่งฉันได้พบกับโครงการ N64 ของฉัน การเพิ่ม HW เล็ก ๆ น้อย ๆ นี้เป็นเหมือนเวทมนต์

ดังนั้นโปรดตรวจสอบก่อนว่าอินพุตของคุณกำลังซิงค์


ในการใช้งานซิงโครไนเซอร์กับคำตอบนั้นดูเหมือนจะไม่ยาก แต่เมื่อฉันอ่านกระบวนการสิ่งที่ฉันเข้าใจasync_inคือความล่าช้า 3 รอบนาฬิกา แต่ค่าและทุกอย่างเหมือนกันหรือไม่
Anarkie

ความแตกต่างใหญ่คือสัญญาณของคุณจะถูกแปลงจากแบบอะซิงโครนัสเป็นซิงโครนัส สิ่งที่เกิดขึ้นใน HW บางครั้งที่มีสัญญาณอะซิงโครนัส (เช่นปุ่มของคุณ) คือบิตอยู่ใน "meta-stabil" ซึ่งทำให้เกิดข้อผิดพลาดที่แปลกมากใน HW การใช้ D Flip Flops ทำให้มั่นใจได้ว่า meta-stabilization จะไม่เกิดขึ้นในการออกแบบของคุณ ฉันยังสงสัยในประสิทธิภาพของสิ่งนี้ แต่มันแก้ไขปัญหาของฉันได้อย่างสมบูรณ์แบบ
Nick Williams

ฉันลองแล้วมันก็คุ้มค่าที่จะลอง แต่ไม่ได้ช่วย :(
Anarkie

1

นี่เป็นคำถามที่น่าสนใจ! เหตุผลที่คุณเห็น pin7 ต่ำเมื่อคุณกด key4 และ key6 เป็นเพราะ pin3 และ pin5

เพื่ออธิบายเพิ่มเติมpin3 และ pin5 จะไม่สูงในเวลาเดียวกัน - หนึ่งในนั้นจะเป็นเส้นทางสู่พื้นดิน (ตามการออกแบบของคุณ) ดังนั้นเมื่อคุณกดปุ่ม 4 และปุ่ม 6 คุณกำลังสร้างเส้นทางสู่กราวด์สำหรับ pin7

ดูภาพ:

พิน 7 เห็นเส้นทางสู่พื้นดิน  คุณมีไฟฟ้าลัดวงจร


ฉันเพิ่มรูปภาพในคำถามของฉันและ pin7 ยังคงสูงเมื่อกดปุ่มทั้งสอง
Anarkie

OP อธิบายว่าเขาไม่ได้เพิ่มพิน 3, 1 หรือ 5 สูงในเวลาเดียวกันในเวลาใดก็ได้ เขาเรียงลำดับคอลัมน์ด้วย: "001", "010" และ "100 หมุด 3 และ 5 ไม่เคยสูงพร้อมกันเพื่อเริ่มต้นด้วย
วิลเลียมส์วิลเลียมส์

1
นั่นคือจุดที่ @EEIngenuity กำลังพยายามทำ - มีเส้นทางที่ชัดเจนระหว่างหมุด 3 และ 5 ซึ่งจะไม่มีค่าเท่าเดิม "ดังนั้นเมื่อคุณกดปุ่ม 4 และปุ่ม 6 คุณกำลังสร้างเส้นทางเพื่อพิน 7 "
fru1tbat

1
@Anarkie ในภาพ Pin3 ไม่ได้เชื่อมต่อกับ GND หรือ VDD มันเป็นโหนดลอย สิ่งนี้ไม่ได้สร้างสถานการณ์การลัดวงจรที่คุณมีในการทดลองใช้ครั้งแรกของคุณ ลองเชื่อมต่อ pin 3 กับ VDD และ Pin5 กับ GND แล้วทดสอบซ้ำ
Miron V

1
@EEIngenuity คุณพูดถูก !!! ใช่แล้วเมื่อฉันเชื่อมต่อ pin3 กับ VDD pin7 จะต่ำ !!! ดังนั้นโปรดช่วยฉันฉันจะเอาชนะปัญหานี้ได้อย่างไรและทำงานได้ :( ฉันใช้ VHDL และเพื่อนร่วมงานอีกคนที่อยู่ในโครงการเดียวกันในทีมอื่นไม่ต้องเผชิญกับปัญหานี้ดังนั้นเขาจึงแก้ไขมัน แต่ฉันไม่สวม ไม่รู้ว่าแผงปุ่มกดเหมือนกันกระดานเดียวกัน!
Anarkie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.