I2C EEPROM bit-banging: Menulis dengan baik, tetapi hanya jika bit pertama tidak disetel


9

Saat ini saya sedang mengerjakan proyek I2C EEPROM menggunakan bit-banging untuk menggerakkan jalur SDA dan SCL.

Fungsi baca saya berfungsi dengan baik tetapi setiap kali saya menulis byte dengan "1" yang memimpin, saya selalu membaca FF kembali; bahkan jika byte telah diprogram dengan sesuatu yang lain sebelumnya. Memimpin "0" sempurna. Ini bukan rutinitas membaca saya; seperti yang saya lihat pada lingkup mengembalikan FF.

Saya mencari saran mengapa ini terjadi. Adakah yang jelas saya bisa lewatkan yang dapat menyebabkan masalah? [Saya tidak dapat memposting kode - rahasia perusahaan ... :(]

Setiap bentuk gelombang yang saya lihat memenuhi spesifikasi persis. Saya memisahkan EEPROM. Pull up saya 2.2k jadi dalam spec. Saya bekerja sekitar 500 Hz dalam prototipe ini. Chip mengirimkan ACK ke masing-masing byte saya sehingga mengenali mereka. Tapi itu tidak berhasil ...

Saya menggunakan Microchip 24LC256 .

Algoritma penulisan sederhana untuk satu byte:

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

Algoritma pembacaan sederhana untuk satu byte:

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
@Justin - Saya pikir dia mengatakan bahwa menulis nilai 0x7F ke alamat mana pun berhasil, tetapi menulis 0x80 ke alamat mana pun tidak berhasil.
Rocketmagnet

1
Hal-hal seperti inilah yang membuat saya membenci I2C.
Rocketmagnet

1
Saya punya firasat gila. Dalam setiap kode bit Anda, apakah Anda secara tidak sengaja menandatangani perpanjangan dengan operasi shift kanan? Jika Anda kemudian yang terkemuka Anda akhirnya akan meninggalkan Anda dengan 0xFF setelah 7 operasi shift.
vicatcu

3
Ironisnya, di sini, adalah kode "rahasia perusahaan". Itu berharga bagi mereka. Semua orang di sini membagikan kode yang berfungsi. Yang membedakan kode perusahaan ini dari yang lain adalah bahwa kode itu tidak berfungsi.
gbarry

2
Sulit membayangkan mengapa perusahaan sangat perlu menjaga rahasia kode bit I2C. Ada begitu banyak di internet.
Rocketmagnet

Jawaban:


4

Anda membaca data setelah jam rendah lagi. Anda harus melakukannya antara membuat jam tinggi dan membuatnya rendah. Setelah jam rendah, budak diizinkan untuk mengubah saluran data, bukan saat sedang tinggi.

masukkan deskripsi gambar di sini

Jadi bacaan harus seperti ini:

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

Itu poin yang bagus; Saya akan memperbaikinya. Namun, data saya masih menunjukkan semua-yang (FF) pada ruang lingkup saya sehingga pembacaan saya tidak menjadi masalah ... :(
Thomas O

3

Masalahnya pada akhirnya ternyata adalah saya secara tidak sengaja mengirimkan kondisi STOP dalam beberapa kondisi karena pengaturan waktu yang kacau. Saya menyerah menggunakan lingkup dan keluar dari penganalisa logika, dan mampu memperbaiki masalah dalam 15 menit karena menyoroti STOP yang seharusnya tidak ada di sana. Saya akan memilih siapa yang akan diberikan hadiah berdasarkan jawaban yang paling membantu. Terima kasih atas semua solusinya.


Senang Anda mengatasinya dengan "memverifikasi waktu penulisan"

3
Saya katakan bahwa ini akan diselesaikan dengan melihat bentuk gelombang.
Rocketmagnet

@Rocketmagnet Saya selalu melihat bentuk gelombang, tetapi tidak pernah menyadarinya sebelumnya.
Thomas O

Ya, tetapi Anda tidak menunjukkan kepada kami bentuk gelombang, meskipun kami berulang kali meminta Anda melakukannya. Anda bisa mengatasi masalah ini beberapa hari yang lalu.
Rocketmagnet

@ Roket - Saya setuju. Saya berharap saya memiliki kamera yang tersedia saat itu. Tek DPO yang saya gunakan memiliki floppy drive tetapi tidak ada floppy. Saya AKAN telah memposting gambar jika saya bisa.
Thomas O

2

OK lingkup Anda membuktikan byte pertama yang masuk ke PIC buruk sehingga bukan fungsi baca PIC.

Apakah Anda memverifikasi waktu penulisan OK di ujung penerima?

Apakah ini gagal di kedua mode di bawah ini?

- Byte mode sequential
- Page mode Sequential

Spesifikasi menunjukkan "Bit Paling Signifikan (MSB) 'b7' dikirim pertama" Ini juga merupakan kebetulan ketika b7 = 1 bahwa seluruh byte dibaca kembali sebagai FF. Jadi itu tidak ditulis dan hanya dihapus (kondisi kesalahan) ketika b7 = 1, atau dibaca kembali sebagai FF terlepas dari konten sebelumnya. Karena setiap penulisan adalah penghapusan byte lebar sebelum menulis, mungkinkah itu menulis yang buruk atau pembacaan yang buruk atau waktu dari byte pertama berbeda.

Saran: Verifikasi sinyal PTC selama penulisan / baca untuk memastikan operasi normal. masukkan deskripsi gambar di sini

Ada opsi untuk menggunakan jam eksternal untuk menentukan waktu panjang siklus E / W menggunakan PTC. Sudahkah Anda mencoba menggunakan ini?

waktu siklus tE / W

  • osilator internal ketik 7ms
  • jam eksternal 4 ~ 10 mnt min ~ maks

Apakah ini memenuhi kriteria ini?


1

Kedengarannya seperti beberapa hal:

  1. Apa lagi yang ada di bus? Mungkinkah ada perselisihan bus dengan perangkat lain yang ditahan di reset atau tidak diinisialisasi?
  2. Apakah Anda mengubah arah pin I / O dengan benar? Jika itu berfungsi dengan baik dalam kasus keluaran, Anda bisa secara tidak sengaja lupa untuk mengubah arah pin ke input dan akan selalu membaca 0xFF. Pin dapat dibiarkan sebagai output mengemudi bus saat Anda membaca dari itu.
  3. Apakah Anda memiliki pull-up internal pada pin itu sendiri dan / atau pada garis I / O? Mikrokontroler biasanya memberikan rentang resistensi dan bukan nilai tetap. Anda mungkin ingin menonaktifkan pull-up pada mikro dan cukup gunakan yang diskrit di bus karena Anda bisa mendapatkan resistensi pull-up yang lebih tepat dari komponen diskrit.
  4. Polaritas jam - Apakah Anda yakin Anda mengukur di tepi kanan / fase antara jam / data? Anda bisa mencatat apa yang tampak hebat bagi Anda pada lingkup, tetapi jika fase tidak sesuai semua EEPROM Anda akan lihat adalah 0xFFs (dan kemungkinan besar akan mengembalikan yang sama karena itu mungkin perintah / kondisi yang tidak valid).

1. Hanya EEPROM dan MCU. 2. Ya, saya percaya saya, karena EEPROM mampu menahan SDA / SCL rendah. 3. Ada 2.2k 5% pull up di papan yang berdekatan dengan EEPROM.
Thomas O

untuk # 2, apakah Anda yakin EEPROM adalah yang menahan bus rendah. Apakah EEPROM memiliki kondisi dalam datasheet di mana ia akan mengembalikan semua 0xFFs? Lihat hasil edit saya di atas juga.
Joel B

# 4 EEPROM adalah "ACK" permintaan saya dan bekerja dengan beberapa kata, tetapi tidak semua.
Thomas O

0

Saya mengirimkan ini sebagai komentar di atas, tetapi kepercayaan diri saya pada jawaban telah diam-diam tumbuh di ceruk yang dalam dari pikiran saya, jadi saya mempromosikannya sebagai jawaban.

Saya punya firasat gila bahwa ini hampir pasti merupakan bug perangkat lunak tingkat rendah yang berkaitan dengan penandatanganan beberapa variabel. Dalam setiap kode bit Anda, apakah Anda secara tidak sengaja menandatangani perpanjangan dengan operasi shift kanan? Jika Anda kemudian yang terkemuka Anda akhirnya akan meninggalkan Anda dengan 0xFF setelah 7 operasi shift.

Steven menyinggung ini dalam komentar, tetapi apakah Anda telah menyaksikan kesucian operasi penulisan Anda pada osilloscope, atau apakah Anda hanya menganggap bahwa mereka bekerja berdasarkan setengah dari read back yang terlihat bagus? Jika Anda belum mencoba melihat operasi penulisan nilai 0xAA, itu mungkin hal yang baik untuk dicoba.

Jika Anda dapat memberikan kode aktual loop dalam Anda dan deklarasi variabel terkait, kami mungkin dapat menemukan bug.


Tulisan saya bagus; Saya bisa melihat ini di ruang lingkup. Keanehan lain: Alamat dengan MSB terkemuka tidak masalah. Hanya data yang menyebabkan masalah! Saya berpikir tentang memposting kode segera.
Thomas O

1
Untuk mendukung jawaban ini: jika ini adalah kode C, ubah semua deklarasi 'char' menjadi 'unsigned char' dan coba lagi.
Wouter van Ooijen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.