Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 I2C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kan35
I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY);

Иногда подвисание происходит вот на этой конструкции, заметил, что такое происходит при остановках JTAGом. Никакие ресеты не помогают - спасает только передергивание питание. Если JTAGом не останавливать, то вроде бы не зависает, но как то боязно, потому что не понятно... Что это такое? и как с этим бороться?
KnightIgor
Цитата(kan35 @ Oct 12 2011, 10:32) *
I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY);

Иногда подвисание происходит вот на этой конструкции, заметил, что такое происходит при остановках JTAGом. Никакие ресеты не помогают - спасает только передергивание питание. Если JTAGом не останавливать, то вроде бы не зависает, но как то боязно, потому что не понятно... Что это такое? и как с этим бороться?


Какая I2C периферия? Довольно общеизвестно, что, например, I2C EEPROM (ее внутренний I2C автомат) может "подвиснуть", если нарушить протокол обмена или не выдержать временнЫе соотношения. Такие состояния на шине I2C и могут возникнуть (наверняка возникают), если вмешиваться в процесс обмена по I2C остановками в прерываниях при отладке. Кроме того, если в отладчике отображаются регистры периферии, то происходит их считывание, что может привести к сбросу флагов (например, флага готовности приема, если прочитан регистр данных). Теоретически JTAG не должен изменять состояние системы (non intrusive), но возможно, что STM32F имеет какой-то баг. В SPI - так это точно, уже накололся.

Чтобы вывести I2C периферию из подвешенного состояния следует выдать на линию SCL по меньшей мере 11 импульсов подряд. Это можно сделать перепрограммированием линии порта SCL в режим GPIO с последующим "ногодрыганием". В Вашем случае можно завести Timeout, и если I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) неразумно долго ждет, выполнить указаную процедуру восстановления (recovery).
Nikitoc
Добрый день. У меня тоже вопрос по I2C, спрошу здесь, чтобы не плодить тем. Есть два stm32f103, которые общаются между собой по I2C. Первый, мастер, выдает слейву два байта команды, получает ACK на каждый из них и генерирует повторный старт. Затем выдает адрес на прием и тут же получает в приемник последний байт команды, который он перед этим передал! При этом слейв ничего не передает. Он даже не загружает в регистр DR никаких данных! Что я делаю не так? Заранее благодарен.
KnightIgor
Цитата(Nikitoc @ Oct 19 2011, 00:57) *
Добрый день. У меня тоже вопрос по I2C, спрошу здесь, чтобы не плодить тем. Есть два stm32f103, которые общаются между собой по I2C. Первый, мастер, выдает слейву два байта команды, получает ACK на каждый из них и генерирует повторный старт. Затем выдает адрес на прием и тут же получает в приемник последний байт команды, который он перед этим передал! При этом слейв ничего не передает. Он даже не загружает в регистр DR никаких данных! Что я делаю не так? Заранее благодарен.

Вопрос к "и тут же получает в приемник последний байт команды, который он перед этим передал": срабатывает прерывание/готовность приема или просто содержимое DR "предыдущее" в отладчике?
Nikitoc
Вот именно, что прерывание срабатывает (типа получены данные)! Причем флаг BTF тоже устанавливается. Но почему в сдвиговом регистре мастера остается это значение? Ведь слейв его благополучно получил и подтвердил ACK-битом.
Nikitoc
Совсем забыл. На этой же шине I2C еще висит акселерометр. Адрес у него, конечно, другой, не такой как у МК, но CS-пин всегда на земле (т.е. он как-бы всегда готов). Может ли такое быть, что он привносит свою "лепту" в обмен между МК?
zksystem
Цитата(Nikitoc @ Oct 21 2011, 10:42) *
Совсем забыл. На этой же шине I2C еще висит акселерометр. Адрес у него, конечно, другой, не такой как у МК, но CS-пин всегда на земле (т.е. он как-бы всегда готов). Может ли такое быть, что он привносит свою "лепту" в обмен между МК?

Не должен отвечать, так как не его адрес.
Nikitoc
Мда. Просто чертовщина какая-то! STM32F103С8 просто непредсказуем в режиме слейва. Получив свой адрес с требованием передачи он может сразу же после чтения статусных регистров передать какой-то "левый" байт. Не дожидаясь загрузки регистра данных!!! И это происходит не всегда. А только при получении перед этим некоторых данных. К примеру, когда мастер отправляет ему два байта 0х1А 0х80 или 0х1А 0х56 (может быть есть еще какие-то варианты, я не проверял). При этом на комбинации 0х1А 0х53 или 0х1А 0х57 или 0х1А 0х52 он реагирует нормально, т.е. сначала загружает ответный байт в регистр DR, а затем корректно передает его. Все это не зависит от частоты. Я пробовал от 10 до 400 кГц. Результаты идентичны. Кто-нибудь работал с stm32 в режиме слейва? Можете привести пример кода? Неделю мучаюсь с этим!
P.S.: Естественно, присутствие акселерометра на шине никоим образом не влияло на эту ситуацию (он был выпаян, ничего не изменилось).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.