Почему установка резисторов между Vcc/SDA и Vcc/SCL в I2C приводит к прямоугольной волне?

Я пытаюсь понять, почему размещение резисторов между Vcc и линиями данных/часов помогает моей форме сигнала быть квадратной, когда я общаюсь между Arduino и микросхемой EEPROM. Если в цепь не поставить резисторы, волны выглядят как плавники акулы. Цепь все еще работает, но это определенно странные волны.

Для справки, этот вопрос возник после подключения Arduino к микросхеме 24LC256 (EEPROM) с использованием I2C. Изучив сигналы с помощью моего осциллографа ( пытаясь отладить что-то несвязанное ), я заметил, что волны выглядят ужасно. Мне они показались плавниками акулы (есть ли для этого более общепринятая фраза ЭЭ?). Я проверил несколько раз, чтобы убедиться, что мои осциллографы пробников настроены/компенсированы правильно, и убедился, что на других схемах такого поведения не было. Вот так выглядела проводка:

Оригинальная проводка

Желтый сигнал — это линия SDA, а синий — SCL.

В случайном разговоре я рассказал об этом EE - и они сказали, что это не редкость для I2C. Он рекомендовал поставить резистор 10 кОм между Vcc и SCL и попробовать резистор с меньшим сопротивлением между Vcc и SDA. Кроме того, он рекомендовал снизить скорость I2C до минимального значения (31 кГц для Uno). Конечно, если я поставлю резистор 10 кОм между Vcc/SCL и резистор 4,7 кОм между Vcc/SDA — они будут выглядеть красиво и квадратно. Я также снизил скорость с нормальной до 31 кГц, но это оказало гораздо меньшее влияние (если вообще имело место).

К сожалению, у меня никогда не было возможности спросить, почему! Я новичок в электронике, но мне очень любопытно, почему резистор, размещенный таким образом, заставляет их лучше выглядеть прямоугольными? Эта фотография ниже сделана после использования резисторов, но до выбора «оптимальных» значений резисторов для получения наилучших прямоугольных сигналов. Я думаю, что это выглядит намного лучше.

введите описание изображения здесь

Я искал объяснения на Stack Exchange, но безрезультатно. Они казались (потенциально) похожими на мою проблему: проблема со связью I2C EEPROM (его волны выглядят так же, как мои, но ответ не касается моего вопроса) интерфейс I2C между двумя чипами (этот тоже казался довольно многообещающим, но не не вникайте в «почему») Странные сигналы I2C, испускаемые FPGA (казалось, что это связано с чем-то другим… хотя похоже на то, что ее волны выглядят «уродливыми»)

Спасибо за помощь!

Короче говоря (и упрощенно): он должен быть квадратным, и отсутствие резистора делает его неквадратным. Или на самом деле сопротивление было слишком велико, и дополнительное сопротивление снизило его (из-за параллельности) достаточно далеко, чтобы зафиксировать время нарастания. Загляните во времена RC.

Ответы (2)

I2C — это шина, использующая выходы с открытым стоком. Открытый сток похож на переключатель, подключенный между выходом и землей. Он не будет работать без подтягивающих резисторов, потому что нет ничего, что могло бы поднять его.

Если подтягивающие резисторы имеют слишком большое значение, он не будет работать (или не будет работать надежно), потому что резистор не будет достаточно быстро заряжать емкость входов, выходов, провода и, возможно, щупа осциллографа . Если они слишком низки, выходной сигнал не будет достаточно сильным, чтобы потянуть его вниз.

Вы замечаете, что при измерении осциллографом выходы очень быстро становятся низкими, но медленно поднимаются до логического уровня 1.

Если код на вашем Arduino использует внутренние подтягивающие резисторы на ATMega для битового взрыва интерфейса I2C, то они, вероятно, имеют слишком большое значение (десятки кОм и не точно указаны) для надежной работы, поэтому их необходимо быть запараллелен внешними резисторами.

Лично я бы написал код, чтобы не использовать внутренние подтяжки (по умолчанию), чтобы избежать ситуации, когда шина «почти» не работает, и заставить пользователя использовать резисторы или сознательно выбрать использование внутренних. Возможно, они приемлемы, если чипы расположены очень близко друг к другу, используется низкая скорость (100K) и не подключены зонды осциллографа (особенно в x1).

Я видел очень похожую ситуацию, когда случайно были установлены цепи резисторов 47K, а не 4,7K.

Спасибо Спехро, это очень полезно. Я не уверен, использует ли библиотека «wire» на Arduino внутренние подтягивающие резисторы по умолчанию, но я не делаю ничего явного в своем коде для их использования. Я согласен с тем, что я бы предпочел, чтобы эти резисторы были выбраны сознательно, а не полагались на них в коде. Может помочь предотвратить подобные ситуации. Извините, один быстрый дополнительный вопрос: почему на это повлияли датчики прицела (особенно в x1)?
Пробники осциллографа в режиме x1 добавляют к емкости примерно 30-40 пФ, что может более чем удвоиться по сравнению с уже имеющимся значением из-за других факторов. В x10 добавленная нагрузка больше похожа на 1/10 от этого.

I2C вообще не должен работать без подтягивающих резисторов; они явно требуются в конструкции шины.

Так что, по сути, ваш вопрос спорный - сделай что-то неправильно, и случится что-то плохое.

Если вы действительно хотите точно понять, что происходит, вероятно, вы получаете какой-то слабый эффект подтяжки от тока утечки или, возможно, даже от внутреннего подтягивающего резистора, который примерно в 10 раз больше, чем должен быть резистор шины I2C. Это вызывает экспоненциальную форму нарастания RC - классическую форму зарядки конденсатора через резистор. С подтягивающим резистором правильного значения это все еще происходит, но достаточно быстро, чтобы экспонента выглядела вертикально на прицеле.

Какой бы источник тока ни приводил линию к высокому уровню при отсутствии настоящего подтягивающего резистора, он слаб (т. е. цепь имеет очень высокий импеданс), поэтому он также крайне чувствителен к емкостной связи с тактовой линией, поэтому вы видите верхние части сигнала линии данных, показывающие артефакты при переключении часов.

Используйте необходимые подтягивающие резисторы. Поместите блокировочный конденсатор питания на микросхему. Проводка должна быть как можно короче. Следуйте правилам, и вы избежите проблем, которые обычно возникают при их нарушении.

Спасибо, Крис. Я полагаю, что слепо следовать онлайн-руководству, в котором не используются подтягивающие резисторы, опасно. Спасибо за объяснение (и да, я действительно хотел знать, какова основная причина того, что происходит).
@Thomas - к сожалению, мир онлайн-руководств по Arduino представляет собой набор того, чего не следует делать , и того, что следует делать, включая даже некоторые официальные руководства от Arduino. Это не значит, что они не могут быть полезными, но вам часто приходится пробираться и отбрасывать три или четыре плохих, чтобы найти что-то, что действительно работает и с пользой использует любой чип, который, как надеялись, извлечение Arduino может помочь быстро оценить.