I2C EEPROM біт-стук: чудово пише, але лише якщо перший біт не встановлений


9

Зараз я працюю над проектом I2C EEPROM, використовуючи біт-удари для керування лініями SDA та SCL.

Моя функція читання працює добре, але коли я пишу будь-який байт з провідним "1", я завжди читаю FF назад; навіть якщо байт раніше був запрограмований на чомусь іншому. Ведучий "0" ідеальний. Це не моя читання; як я бачу, за обсягом він повертає FF.

Я шукаю пропозиції, чому це може бути. Чи є явне я можу пропустити, що могло б викликати проблему? [Я не можу розмістити код - конфіденційність компанії ... :(]

Кожна форма хвилі, на яку я дивлюсь, точно відповідає специфікації. Я відокремлюю EEPROM. Мої підтяжки складають 2,2 тис. Т. В межах специфікації. Я працюю на частоті приблизно 500 Гц у цьому прототипі. Чіп надсилає 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
@Justin - Я думаю, що він говорить, що записувати значення 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

Це хороший момент; Я це виправлю. Однак, мої дані все ще показують, що все-таки (FF) в моєму просторі, тому моє читання не може бути проблемою ... :(
Thomas O

3

Проблема зрештою виявилася в тому, що я ненавмисно надсилав умову STOP за деяких умов через невдалий час. Я відмовився від використання області застосування і вийшов з логічного аналізатора, і зміг виправити проблему за 15 хвилин, оскільки він виділив STOP, який не повинен був там бути. На основі найбільш корисної відповіді я виберу, кому дати винагороду. Дякую за всі рішення.


Радий, що ви вирішили це питання "перевірити терміни запису"

3
Я сказав вам, що це вирішиться, поглянувши на форму хвилі.
Rocketmagnet

@Rocketmagnet Я завжди дивився на форму хвилі, але ніколи цього не помічав.
Томас О

Так, але ви не показали нам форму хвилі, незважаючи на те, що ми неодноразово просили вас про це. Ви могли б вирішити цю проблему днями тому.
Rocketmagnet

@Rocket - я згоден. Мені б хотілося, щоб у мене на той час була доступна камера. Tek DPO, яким я користувався, мав дискету, але не має дискети. Я б розмістив фотографію, якби міг.
Томас О

2

Гаразд, ваш обсяг доводить, що 1-й байт, що надходить до PIC, поганий, тому це не функція читання PIC.

Ви перевірили, чи відповідає час запису в кінці прийому?

Це не вдається в обох режимах нижче?

- Byte mode sequential
- Page mode Sequential

Спеціалізація показує "Найбільш значущий біт (MSB) 'b7' надсилається вперше" Це також збігається, коли b7 = 1 весь байт зчитується як FF. Отже, або він не записується, а стирається лише (стан несправності), коли b7 = 1, або він зчитується погано як FF незалежно від попереднього вмісту. Оскільки кожне записування - це байтове стирання перед записом, чи може це все-таки бути поганим чи поганим читанням, або час 1-го байта відрізняється.

Пропозиція: Перевірте сигнал PTC під час запису / читання, щоб забезпечити нормальну роботу. введіть тут опис зображення

Існує можливість використання зовнішнього годинника для визначення часу E / W циклу за допомогою PTC. Ви намагалися використовувати це?

час циклу tE / W

  • внутрішній генератор 7мс тип
  • зовнішній годинник 4 ~ 10 мс хв ~ макс

Чи відповідає цим критеріям?


1

Здається, це може бути кілька речей:

  1. Що ще є в автобусі? Чи може існувати суперечка шини з іншим пристроєм, який утримується в режимі скидання чи неініціалізації?
  2. Ви правильно змінюєте напрямок вводу-виводу? Якщо це добре працює у вихідному випадку, ви могли ненароком забути змінити напрямок штифта на вхід і завжди буде читати 0xFF. Штифт може бути залишений як вихід, що веде шину, поки ви з нього читаєте.
  3. Чи є внутрішні підтяжки на самому штифті та / або на лініях вводу / виводу? Мікроконтролери зазвичай дають діапазон опору, а не фіксовану величину. Можливо, ви захочете відключити підключення мікрофонів і просто використовувати дискретні на шині, оскільки ви зможете отримати більш точний опір підтягування від дискретних компонентів.
  4. Полярність годин - Ви впевнені, що вимірюєте правий край / фазу між годинником / даними? Ви можете вирішувати те, що вам здається чудовим в області застосування, але якщо фаза не відповідає всім вашим EEPROM буде бачити 0xFFs (і, швидше за все, поверне те саме, що це, мабуть, недійсна команда / умова).

1. Просто EEPROM та MCU. 2. Так, я вважаю, що я є, оскільки EEPROM здатний утримувати низький рівень SDA / SCL. 3. На платі, що прилягає до EEPROM, є 2,2 тис. 5% підтягувань.
Thomas O

для №2, ви впевнені, що EEPROM - це той, хто тримає шину низько. Чи є в EEPROM якісь умови в таблиці даних, де він повертає всі 0xFFs? Дивіться також мої зміни вище.
Джоель Б

№4. EEPROM "ACK" відповідає моїм запитам і працює з деякими словами, але не з усіма.
Томас О

0

Я подав це як коментар вище, але моя впевненість у відповіді тихо зростала в глибоких глибинах мого розуму, тому я просуваю це до відповіді.

У мене шалене уявлення про те, що це майже напевно програмна помилка низького рівня, що стосується підписаності деяких змінних. У своєму коді для кожного бітового коду ви ненароком підписуєте розширення під час операції зсуву праворуч? Якщо ви тоді є вашим ведучим, з часом ви отримаєте 0xFF після 7 операцій у зміну.

Стівен на це наголосив у коментарі, але ви були свідком святості ваших операцій запису на осілоскопі, або ви лише припускаєте, що вони працюють на основі половини прочитаних зворотних позицій? Якщо ви не пробували дивитися на операцію запису значення 0xAA, це може бути непогано спробувати.

Якщо ви можете надати фактичний код вашого внутрішнього циклу та пов'язані з ним декларації змінної, ми можемо виявити помилку.


Мої записи хороші; Я можу це бачити на межі. Ще одне диво: Адреси з провідним MSB добре. Лише дані викликають проблеми! Думаю про розміщення коду найближчим часом.
Томас О

1
На підтвердження цієї відповіді: якщо це код C, змініть усі "char" декларації на "неподписані символи" та спробуйте ще раз.
Wouter van Ooijen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.