การชนบิต I2C EEPROM: เขียนดี แต่ถ้าบิตแรกไม่ได้ถูกตั้งค่า


9

ขณะนี้ฉันกำลังทำงานเกี่ยวกับโครงการ I2C EEPROM โดยใช้การทุบบิตเพื่อขับ SDA และ SCL

ฟังก์ชั่นการอ่านของฉันทำงานได้ดี แต่เมื่อใดก็ตามที่ฉันเขียนไบต์ใด ๆ ด้วย "1" นำหน้าฉันจะอ่าน FF ย้อนกลับเสมอ แม้ว่าไบต์จะถูกโปรแกรมด้วยอย่างอื่นมาก่อน นำ "0" สมบูรณ์แบบ มันไม่ใช่รูทีนการอ่านของฉัน อย่างที่ฉันเห็นในขอบเขตมันจะคืนค่า FF

ฉันกำลังมองหาคำแนะนำเกี่ยวกับสาเหตุที่อาจเป็นเช่นนี้ มีอะไรที่ชัดเจนหรือไม่ที่ฉันอาจคิดถึงซึ่งอาจทำให้เกิดปัญหาได้ [ฉันไม่สามารถโพสต์รหัสได้ - บริษัท เป็นความลับ ... :(]

ทุกรูปคลื่นที่ฉันดูตรงตามสเปคอย่างแน่นอน ฉัน decoupling EEPROM pull ups ของฉันคือ 2.2k ดังนั้นภายในสเป็ค ฉันกำลังตอกบัตรอยู่ที่ประมาณ 500 Hz ในต้นแบบนี้ ชิปกำลังส่ง ACK ไปยังแต่ละไบต์ของฉันดังนั้นจึงรับรู้ได้ แต่มันไม่ทำงาน ...

ฉันใช้ Microchip 24LC256

อัลกอริทึมการเขียนที่ง่ายขึ้นสำหรับหนึ่งไบต์:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

อัลกอริทึมการอ่านที่ง่ายขึ้นสำหรับหนึ่งไบต์:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@ จัสติน - ฉันคิดว่าเขากำลังบอกว่าการเขียนค่า 0x7F ไปยังที่อยู่ใดก็ได้ทำงานได้ แต่การเขียน 0x80 ไปยังที่อยู่ใด ๆไม่ทำงาน
Rocketmagnet

1
มันเป็นอย่างนี้ที่ทำให้ฉันเกลียด I2C
Rocketmagnet

1
ฉันมีลางสังหรณ์ที่บ้า ในแต่ละรหัสบิตคุณเข้าสู่ระบบโดยไม่ได้ตั้งใจด้วยการเลื่อนขวาหรือไม่? หากคุณเป็นผู้นำของคุณในที่สุดก็จะทิ้งคุณด้วย 0xFF หลังจาก 7 กะการดำเนินงาน
vicatcu

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

2
มันยากที่จะจินตนาการว่าทำไม บริษัท จึงจำเป็นต้องเก็บรหัสการโจมตีบิตของ I2C ไว้เป็นความลับ มีอยู่มากมายในอินเทอร์เน็ต
Rocketmagnet

คำตอบ:


4

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

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

ดังนั้นการอ่านควรเป็นดังนี้:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

นั่นเป็นประเด็นที่ดี ฉันจะแก้ไขมัน อย่างไรก็ตามข้อมูลของฉันยังคงแสดงเป็น all-(FF) ในขอบเขตของฉันดังนั้นการอ่านของฉันจึงไม่เป็นปัญหา ... :(
Thomas O

3

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


ดีใจที่คุณได้แก้ไขโดย "ตรวจสอบเวลาการเขียน"

3
ฉันบอกคุณว่านี่จะแก้ไขได้โดยดูที่รูปคลื่น
Rocketmagnet

@Rocketmagnet ฉันได้ดูรูปคลื่นเสมอ แต่ไม่เคยสังเกตมาก่อน
โทมัส O

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

@Rocket - ฉันเห็นด้วย ฉันหวังว่าฉันจะมีกล้องในเวลานั้น Tek DPO ที่ฉันใช้มีฟลอปปี้ไดรฟ์ แต่ไม่มีฟลอปปี้ ฉันจะโพสต์ภาพถ้าฉันมี
โทมัส O

2

ตกลงขอบเขตของคุณพิสูจน์ว่าไบต์ที่ 1 ที่เข้ามาใน PIC ไม่ดีดังนั้นจึงไม่ใช่ฟังก์ชั่นการอ่าน PIC

คุณตรวจสอบว่าระยะเวลาการเขียนนั้นตกลงเมื่อสิ้นสุดการรับหรือไม่?

สิ่งนี้ล้มเหลวในทั้งสองโหมดด้านล่างหรือไม่

- Byte mode sequential
- Page mode Sequential

ข้อมูลจำเพาะแสดง "บิตที่มีนัยสำคัญมากที่สุด (MSB) 'b7' ถูกส่ง fi rst" สิ่งนี้ก็เหมือนกันเมื่อ b7 = 1 ที่ไบต์ทั้งหมดถูกอ่านเป็น FF ดังนั้นมันจะไม่ถูกเขียนและลบเฉพาะ (เงื่อนไขข้อผิดพลาด) เมื่อ b7 = 1 หรืออ่านกลับไม่ดีเป็น FF โดยไม่คำนึงถึงเนื้อหาก่อนหน้า เนื่องจากการเขียนทุกครั้งเป็นการลบแบบกว้างไบต์ก่อนที่จะเขียนอาจเป็นการเขียนที่ไม่ดีหรือการอ่านที่ไม่ดีหรือระยะเวลาของไบต์ที่ 1 นั้นแตกต่างกัน

คำแนะนำ: ตรวจสอบสัญญาณ PTC ระหว่างการเขียน / อ่านเพื่อให้แน่ใจว่าการทำงานปกติ ป้อนคำอธิบายรูปภาพที่นี่

มีตัวเลือกในการใช้นาฬิกาภายนอกสำหรับกำหนดเวลาความยาวของรอบ E / W โดยใช้ PTC คุณเคยลองใช้สิ่งนี้หรือไม่?

รอบเวลา tE / W

  • ออสซิลเลเตอร์ภายใน 7ms typ
  • นาฬิกาภายนอก 4 ~ 10 ms นาที ~ สูงสุด

มันผ่านเกณฑ์นี้หรือไม่?


1

ฟังดูเหมือนจะเป็นสองสิ่ง:

  1. บนรถบัสมีอะไรอีกบ้าง? จะมีการช่วงชิงบัสกับอุปกรณ์อื่นที่กำลังถูกรีเซ็ตหรือไม่เตรียมการหรือไม่?
  2. คุณเปลี่ยนทิศทางของพิน I / O อย่างถูกต้องหรือไม่? 0xFFหากมีการปรับการทำงานในกรณีที่ออกคุณอาจจะลืมไม่ได้ตั้งใจที่จะเปลี่ยนทิศทางของขาที่จะป้อนข้อมูลและมักจะอ่าน สลักอาจถูกทิ้งไว้เป็นเอาท์พุทขับรถบัสในขณะที่คุณกำลังอ่านจากมัน
  3. คุณมี pull-ups ภายในที่ขาของตัวเองและ / หรือบนเส้น I / O หรือไม่? ไมโครคอนโทรลเลอร์มักจะให้ช่วงของความต้านทานและไม่ใช่ค่าคงที่ คุณอาจต้องการปิดการใช้งาน pull-ups บนไมโครและเพียงแค่ใช้งานแบบแยกบนบัสเนื่องจากคุณสามารถรับความต้านทาน pull-up ที่แม่นยำยิ่งขึ้นจากส่วนประกอบที่ไม่ต่อเนื่อง
  4. ขั้วของนาฬิกา - คุณแน่ใจหรือไม่ว่าคุณกำลังวัดที่ขอบ / เฟสด้านขวาระหว่างนาฬิกา / ข้อมูล คุณอาจกำลังตอกย้ำสิ่งที่ดูดีสำหรับคุณในขอบเขต แต่ถ้าเฟสอยู่นอกบรรทัด EEPROM ทั้งหมดของคุณจะเห็นเป็น0xFFs (และน่าจะกลับมาเหมือนเดิมเพราะอาจเป็นคำสั่ง / เงื่อนไขที่ไม่ถูกต้อง)

1. เพียงแค่ EEPROM และ MCU 2. ใช่ฉันเชื่อว่าฉันเพราะ EEPROM สามารถถือ SDA / SCL ได้ต่ำ 3. มีแรงดึง 2.2k 5% บนบอร์ดซึ่งอยู่ติดกับ EEPROM
โทมัสโอ

สำหรับ # 2 คุณแน่ใจหรือไม่ว่า EEPROM เป็นคนที่ถือบัสต่ำ EEPROM มีเงื่อนไขใด ๆ ในแผ่นข้อมูลที่จะส่งคืนทั้งหมด0xFFหรือไม่? ดูการแก้ไขของฉันด้านบนด้วย
Joel B

# 4 EEPROM คือ "ACK" ในการส่งคำขอของฉันและทำงานด้วยคำบางคำ แต่ไม่ใช่ทั้งหมด
โทมัส O

0

ฉันส่งสิ่งนี้เป็นความคิดเห็นข้างต้น แต่ความมั่นใจในคำตอบของฉันเพิ่มขึ้นอย่างเงียบ ๆ ในจิตใจของฉันดังนั้นฉันจึงส่งเสริมให้เป็นคำตอบ

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

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

หากคุณสามารถระบุรหัสที่แท้จริงของวงในของคุณและการประกาศตัวแปรที่เกี่ยวข้องเราอาจสามารถตรวจพบข้อบกพร่อง


งานเขียนของฉันดี ฉันเห็นสิ่งนี้ในขอบเขต ความประหลาดอีกอย่าง: ที่อยู่ที่มี MSB ชั้นนำนั้นไม่เป็นไร ข้อมูลเท่านั้นที่ทำให้เกิดปัญหา! ฉันคิดว่าจะโพสต์โค้ดเร็ว ๆ นี้
โธมัสโอ

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