В настоящее время я работаю над проектом I2C EEPROM, использующим битовые удары для управления линиями SDA и SCL.
Моя функция чтения работает нормально, но всякий раз, когда я пишу какой-либо байт с ведущей «1», я всегда читаю FF назад; даже если байт был запрограммирован с чем-то еще раньше. Ведущий «0» идеален. Это не моя рутина чтения; как я вижу по области, он возвращает FF.
Я ищу предложения о том, почему это может быть. Есть ли очевидное, что я мог пропустить, что может вызвать проблемы? [Я не могу опубликовать код - компания конфиденциальна ... :(]
Каждая форма волны, на которую я смотрю, точно соответствует спецификации. Я отделяю EEPROM. Мои подтягивания 2,2 к, так что в пределах спецификации. Я работаю на частоте около 500 Гц в этом прототипе. Чип отправляет ACK на каждый из моих байтов, чтобы он их распознал. Но это просто не работает ...
Я использую микрочип 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
Ответы:
Вы читаете данные после того, как часы снова низки. Вам придется делать это между повышением часов и снижением их. После того, как время на часах низкое, ведомому разрешается изменять линию данных, а не когда она высокая.
Так что чтение должно быть таким:
источник
В конце концов, проблема заключалась в том, что я случайно отправлял условие STOP при некоторых условиях из-за искаженного времени. Я отказался от использования прицела и вышел из логического анализатора, и смог исправить проблему за 15 минут, поскольку он выдвинул на первый план ОСТАНОВКУ, которой не должно было быть. Я выберу, кому отдать награду, основываясь на наиболее полезном ответе. Спасибо за все решения.
источник
Хорошо, ваша область действия доказывает, что 1-й байт, поступающий в PIC, плох, так что это не функция чтения PIC.
Вы проверили правильность времени записи на принимающей стороне?
Это терпит неудачу в обоих режимах ниже?
Спецификация показывает, что «самый старший бит (MSB) 'b7' отправляется первым». Это также совпадает, когда b7 = 1, что весь байт считывается как FF. Таким образом, либо он не записывается, а стирается (состояние ошибки), когда b7 = 1, или плохо считывается как FF независимо от предыдущего содержимого. Поскольку каждая запись перед записью является стиранием шириной в байт, может ли она быть плохой записью или неправильным чтением, или время первого байта отличается.
Предложение: Проверьте сигнал PTC во время записи / чтения, чтобы обеспечить нормальную работу.
Существует возможность использования внешних часов для синхронизации продолжительности цикла E / W с использованием PTC. Вы пытались использовать это?
время цикла tE / W
Это соответствует этим критериям?
источник
Похоже, это может быть пара вещей:
0xFF
. Вывод может быть оставлен в качестве выхода, управляющего шиной, в то время как вы будете читать с него.0xFF
s (и, скорее всего, вернет то же самое, что, вероятно, неверная команда / условие).источник
0xFF
s? Смотрите мои правки выше тоже.Я представил это как комментарий выше, но моя уверенность в ответе тихо росла в глубине моего разума, поэтому я продвигаю его до ответа.
У меня есть безумное предчувствие, что это почти наверняка ошибка программного обеспечения низкого уровня, связанная с сигнатурой некоторых переменных. В вашем для каждого битового кода вы невольно расширяете знак с помощью операции сдвига вправо? Если вы станете лидером, со временем вы получите 0xFF после 7 смен.
Стивен упомянул об этом в комментарии, но вы были свидетелем святости ваших операций записи на осциллографе, или вы только предполагаете, что они работают, основываясь на том, что половина считываний выглядит хорошо? Если вы не пробовали смотреть на операцию записи значения 0xAA, это может быть полезно.
Если вы можете предоставить фактический код вашего внутреннего цикла и объявления переменных, мы могли бы обнаружить ошибку.
источник