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
Jawaban:
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.
Jadi bacaan harus seperti ini:
sumber
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.
sumber
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?
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.
Ada opsi untuk menggunakan jam eksternal untuk menentukan waktu panjang siklus E / W menggunakan PTC. Sudahkah Anda mencoba menggunakan ini?
waktu siklus tE / W
Apakah ini memenuhi kriteria ini?
sumber
Kedengarannya seperti beberapa hal:
0xFF
. Pin dapat dibiarkan sebagai output mengemudi bus saat Anda membaca dari itu.0xFF
s (dan kemungkinan besar akan mengembalikan yang sama karena itu mungkin perintah / kondisi yang tidak valid).sumber
0xFF
s? Lihat hasil edit saya di atas juga.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.
sumber