Jump to content

    
Sign in to follow this  
Dron_Gus

stm32 i2c

Recommended Posts

Что-то не совсем адекватно работает модуль I2C2. Или я что-то не учел.

Кто-нить с ним работал. Есть какие-нить дополнительные грабли, кроме описанных в errat'е?

Симптомы: идет постоянный обмен с 8 устройствами. STM32 мастер. В какой-то момент общение со всеми устройствами выпадает на Ack Failed в момент передачи адреса. Отваливаются сразу все. Через некоторое время обмен восстанавливается.

 

З.Ы. на первом i2c висят часы и с ними никаких проблем не обнаружено.

Share this post


Link to post
Share on other sites

Покопался на форуме ST. Вообщем, хотели как лучше, получилось как всегда.

 

З.Ы. ни у кого нет bit bang реализации i2c? И вообще, как на "быстром" проце делать привязку к времени? Не висеть же все время в процедуре обмена. С другой стороны вешать на прерывание таймера - больно часто выходит.

Share this post


Link to post
Share on other sites
Посмотрите здесь свежак: STM32F10xxx devices: advanced I²C examples, если ещё не видели.

 

Спасибо. Глядел диагонально. Еще пару месяцев назад этот пример содержал реализации на основе прерываний и полинга. Теперь только ДМА. У меня же основная засада в том, что заранее неизвестно, сколько данных отдаст периферийное устройство. Количество данных идет в первом байте. Т.е. ДМА не мой вариант.

Share this post


Link to post
Share on other sites

У меня тоже он че-то не идет. Работает некоторое время, потом виснет. помогает только полный рестарт i2c + передергивание вручную SCL.

прерывания забустил.

Также есть несколько веток (типа https://my.st.com/public/STe2ecommunities/m...urrentviews=304 ) на их форуме, тоже без решений по сути.

Сделал софтовый I2C, благо, шина не сильно нагружена

Share this post


Link to post
Share on other sites

Еще вопрос

 

Пытаюсь запустить обмен по шине на прерываниях. Так вот не пойму, у них прерывание по Start bit send работает в принципе?

То есть выставляю в I2C1->CR1 бит I2C_CR_START. По идее, после генерации старта на шине я должен попасть в прерывание I2C1_EV_IRQHandler() и там увидеть выставленный фдаг SB в SR1, однако, в прерывание не попадаю. Или я что то не так понял?

 

Другие прерывания вроде работают (например ADDR TxE).

Прерывания разрешены, переферия затактирована...

 

Share this post


Link to post
Share on other sites
Еще вопрос

 

Пытаюсь запустить обмен по шине на прерываниях. Так вот не пойму, у них прерывание по Start bit send работает в принципе?

То есть выставляю в I2C1->CR1 бит I2C_CR_START. По идее, после генерации старта на шине я должен попасть в прерывание I2C1_EV_IRQHandler() и там увидеть выставленный фдаг SB в SR1, однако, в прерывание не попадаю. Или я что то не так понял?

 

Другие прерывания вроде работают (например ADDR TxE).

Прерывания разрешены, переферия затактирована...

 

Резисторы подтягивающие в наличии?

Линии SDA и SCL в норме?

Share this post


Link to post
Share on other sites

Рекомендации ST по поводу I2C:

Это периферийное устройство в STM32 - сложное с кучей диагностических флагов и множеством режимов работы. Кроме того, оно чувствительно к таймингам, оттого инженеры саппорта ST обещают наложить проклятие на каждого, кто будет работать с этим модулем напрямую (и потом будет жаловаться на глюки). Вместо этого строго рекомендуется применять библиотеку CPAL, она доступна с сайта st.com. Не факт, что это ваш случай, но вероятность далеко не нулевая.

Share this post


Link to post
Share on other sites
Теперь только ДМА. У меня же основная засада в том, что заранее неизвестно, сколько данных отдаст периферийное устройство. Количество данных идет в первом байте. Т.е. ДМА не мой вариант.

Это как так? Мастер не знает, сколько спрашивает? Протокол I2C весьма детерминированный. Мастер определяет, сколько читать/писать. Если у ведомого запросить больше, чем он может дать, он выставит NACK. Это ловится в прерывании, обмен завершается, DMA останавливается. Все чисто. Не глядел еще примеры от ST: в свое время написал свою поддержку, работающую по прерываниям и с использованием DMA, работает стабильно.

Share this post


Link to post
Share on other sites
Если у ведомого запросить больше, чем он может дать, он выставит NACK.

 

Не, 24LC можно читать до посинения по кругу, только оно никому не надо.

Share this post


Link to post
Share on other sites

Всем доброго времени суток!

Помогите разобраться с опросом MS5611, никак не могу прочитать два байта при опросе, читается старший и все... Может кто сталкивался уже?

Share this post


Link to post
Share on other sites
Всем доброго времени суток!

Помогите разобраться с опросом MS5611, никак не могу прочитать два байта при опросе, читается старший и все... Может кто сталкивался уже?

Что значит "читается старший и все"? Что значит "всё", то есть, как это проявляется: выставляется NACK, либо I2C виснет вообще, либо младший байт неправильный по содержанию?

 

Как можно вообще так пространно вопросы ставить и потом на ответы надеяться?...

Share this post


Link to post
Share on other sites

Доброго времени суток. Юзаю i2c на STM32F4DISCOVERY для опроса датчика. Использую библиотеку CPAL. Появилась проблема, которая вот уже много времени гложет мозг. Суть в следующем.

 

CPAL проверяет таймауты, для чего на CPAL у меня выделен TIM3, по прерыванию раз в мс вызывается библиотечная функция CPAL_I2C_TIMEOUT_Manager(). И все вроде хорошо. НО! Возникают моменты, когда программа затыкается на __CPAL_I2C_TIMEOUT(). Это дефайн, который представляет из себя цикл, выход из которого возможен по одному из двух условий: 1) наступило ожидаемое событие (например, скинулся бит BUSY статусного регистра); 2) превышен лимит ожидания. То есть, если щелкает таймер, то рано или поздно цикл будет покинут. НО! При зависании в __CPAL_I2C_TIMEOUT() таймер хоть и работает, и выставлены нужные флаги, но прерывание, и соответственно, подсчет таймингов, не вызываются.

 

Привожу рисунок, на нем - собственно место затыка во время отладки, а также регистры 3-го таймера. Ниже по коду в комментах - определение самой __CPAL_I2C_TIMEOUT()

post-77447-1373446754_thumb.png

Share this post


Link to post
Share on other sites
таймер хоть и работает, и выставлены нужные флаги, но прерывание, и соответственно, подсчет таймингов, не вызываются.

Так определите, кто (где, почему) запретил прерывание, если оно не вызывается.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this