В моей системе я использую I2C и понимаю, что при большой нагрузке прерывания (из других источников) связь I2C легко прерывается. Это ожидаемое поведение для I2C? Я ожидал бы, несмотря на загрузку прерывания, все было бы в порядке, поскольку I2C не является интерфейсом, критичным ко времени, часы снабжены данными.
Обновить:
Процессор STM32. Прерывания происходят из-за АЦП, я не могу отключить прерывания во время событий чтения, поэтому я должен найти решение, где я мог бы сделать связь i2c более стабильной. STM32 является ведущим, а ведомым устройством является другое устройство (акселерометр).
Update2:
Когда я подключаю к часам логический анализатор с помощью небольшого летающего кабеля, проблема исчезает. Интересно, что нет прерывания загрузки, чтение и запись работает хорошо, когда есть прерывание загрузки, они не делают. Однако, если я присоединяю зонд к часам, чтение-запись работает и при прерывании. Я думаю, что где-то есть проблема с емкостью.
Ответы:
Это проблема программного обеспечения, вы тратите слишком много времени на обслуживание прерываний, и ваша подпрограмма I2C не может справиться с этим (так что это две вещи, которые не верны). Я прошел через несколько подобных ситуаций.
Во-первых: вам нужно делать как можно меньше в прерываниях, только читать и хранить данные, не выполнять никакой обработки, которую вы могли бы выполнять за пределами ISR, математика может занять МНОГО циклов ЦП, а ЦП не может делать ничего другого. в то время как в этом прерывании.
Второе: исследуйте DMA, чтобы автоматизировать вещи, чтобы ваши прерывания стали почти фоновым автоматизированным процессом.
Третье: если важен I2C, включите ТА и в прерывание, но убедитесь, что вы решаете приоритеты!
В-четвертых: выясните, почему ваша процедура I2C дает сбой, сам I2C может выдерживать очень прерывистые периоды времени, паузы, ожидания и т. Д., Поэтому ваша процедура может нуждаться в изменении, чтобы позволить это.
Пятое. Посмотрите, можете ли вы «цеплять» прерывания, вы можете обнаружить, что можете более эффективно обслуживать считывания АЦП или перевести АЦП в другой режим, где он выполняет больше работы перед прерыванием (например, дождитесь, пока все показания не будут доступны, затем читать все в одном обращении, а не 8 отдельных прерываний для 8 отдельных операций чтения канала АЦП).
Шестое: используйте осциллограф или логический анализатор и запасные выводы ввода-вывода на плате, чтобы отслеживать, сколько времени вы тратите на каждый бит кода, чтобы увидеть, сможете ли вы его ускорить. (Установите высокий пин при входе в функцию / ISR, снова установите низкий при выходе).
Седьмое: Решите, если вам действительно нужно читать АЦП так много, будет ли хуже работать? Это нелогично, но иногда работает медленнее, на самом деле дает более хорошие результаты, выполняя работу по усреднению сигнала для вас и сокращая пики / переходные процессы, которые могут вызвать проблемы или потребовать дополнительной обработки для удаления. Мы улучшили процедуру PID управления двигателем, просто выполнив ее на 1/4 скорости, высвободив нагрузку из процессорного времени.
источник
У ведомого автобуса, который занят другими вещами, есть возможность растягивать часы, чтобы выиграть время, пока он не сможет продолжить свою связь. Он делает это, не посылая немедленно тактовый импульс ACK / NACK, поддерживая связь в промежуточном состоянии, пока не будет готов ответить.
Растягивание часов - подходящий способ справиться с подобной ситуацией. Устройство, которое не растягивается и выполняет другие плохие действия (зависание / перезапуск шины, NACK-адрес, действительный адрес или команда и т. Д.), Может быть проблематичным и накладывать дополнительную нагрузку на мастер, чтобы он не разбирался (он должен повторять команды , следить за NACKs и т. д.)
источник
В зависимости от возможностей STM32 (я никогда не использовал его), вы можете попробовать один из следующих подходов. Если вы можете предоставить более подробную информацию о том, что вы пытаетесь сделать, и привести убедительные аргументы о том, почему каждое прерывание необходимо в той форме, в которой оно у вас есть сейчас, то можно подумать о более конкретном ответе. Тем не менее, в вашем случае I2C достаточно медленный, чтобы не создавать проблем с хорошо написанными подпрограммами обработки прерываний.
Прерывания для чего-либо обычно могут быть отключены. В любом обычном контроллере имеется не более одного или двух немаскируемых прерываний, одно из которых сбрасывается. Если вам не нужен управляемый прерываниями контроль чего-либо (в вашем случае АЦП или I2C), то превратите этот периферийный код в код, не использующий прерывания, а затем отключите прерывания.
Обработчики прерываний не должны быть длинными. Постарайтесь сделать как можно меньше из самого вектора прерывания. Экстремальный минималистический подход к прерываниям состоит в том, чтобы просто установить флаг из подпрограммы обработчика прерываний и, скажем, с помощью основного цикла выполнить всю тяжелую работу с этого момента. То, что требует ваше конкретное приложение и архитектура прошивки, может быть не таким простым, как это, но действительно стоит приложить усилия, чтобы увидеть, сколько действительно нужно сделать из прерываний.
Если у вас есть периферийный DMA, используйте его вместо прерывания на каждый байт. Как правило, было бы проще поставить АЦП на DMA, а не на I2C, но разные чипы имеют разные реализации. Я не удивлюсь, если бы существовал чистый способ отменить обмен I2C на DMA. DMA позволяет сократить количество прерываний и освобождает ядро процессора от необходимости обрабатывать каждый блок данных.
Попробуйте определить конкретные случаи, когда вы видите повреждение данных, и механизм, с помощью которого происходит повреждение данных. Это гораздо труднее сделать, но при творческом использовании современного осциллографа / логического анализатора вы сможете увидеть некоторые из проблем. В частности, убедитесь, что проблема связана с синхронизацией, а не с памятью (что возможно при сочетании ужасного кода и либерального компилятора)
РЕДАКТИРОВАТЬ: Некоторые конкретные заметки, касающиеся этого случая проблемы, из ваших комментариев к вопросу:
источник
В данной системе может быть шум, поступающий на часы и шины данных. Тот факт, что ваш логический анализатор устраняет проблему, показывает это. Для практической и быстрой реализации просто следуйте подсказке, данной вашим наблюдением. На шине i2c с реализацией 400 кбит / с, основанной на аналогичных наблюдениях, я подключил 2M параллельно с 12pf к земле из точек синхронизации и данных и обнаружил, что проблема решена. Это удаляет / фильтрует шум вне интересующей полосы, необходимой для конкретной связи i2c. Пожалуйста, попробуйте и посоветуйте.
источник