реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32 I2C, почему подвисает иногда?
kan35
сообщение Oct 12 2011, 08:32
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY);

Иногда подвисание происходит вот на этой конструкции, заметил, что такое происходит при остановках JTAGом. Никакие ресеты не помогают - спасает только передергивание питание. Если JTAGом не останавливать, то вроде бы не зависает, но как то боязно, потому что не понятно... Что это такое? и как с этим бороться?
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Oct 13 2011, 07:22
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(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).
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Oct 18 2011, 22:57
Сообщение #3


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Добрый день. У меня тоже вопрос по I2C, спрошу здесь, чтобы не плодить тем. Есть два stm32f103, которые общаются между собой по I2C. Первый, мастер, выдает слейву два байта команды, получает ACK на каждый из них и генерирует повторный старт. Затем выдает адрес на прием и тут же получает в приемник последний байт команды, который он перед этим передал! При этом слейв ничего не передает. Он даже не загружает в регистр DR никаких данных! Что я делаю не так? Заранее благодарен.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Oct 19 2011, 09:31
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



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

Вопрос к "и тут же получает в приемник последний байт команды, который он перед этим передал": срабатывает прерывание/готовность приема или просто содержимое DR "предыдущее" в отладчике?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Oct 19 2011, 11:19
Сообщение #5


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Вот именно, что прерывание срабатывает (типа получены данные)! Причем флаг BTF тоже устанавливается. Но почему в сдвиговом регистре мастера остается это значение? Ведь слейв его благополучно получил и подтвердил ACK-битом.
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Oct 21 2011, 06:42
Сообщение #6


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Совсем забыл. На этой же шине I2C еще висит акселерометр. Адрес у него, конечно, другой, не такой как у МК, но CS-пин всегда на земле (т.е. он как-бы всегда готов). Может ли такое быть, что он привносит свою "лепту" в обмен между МК?
Go to the top of the page
 
+Quote Post
zksystem
сообщение Oct 21 2011, 11:28
Сообщение #7


embedder
***

Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911



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

Не должен отвечать, так как не его адрес.


--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Oct 22 2011, 14:18
Сообщение #8


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Мда. Просто чертовщина какая-то! 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.: Естественно, присутствие акселерометра на шине никоим образом не влияло на эту ситуацию (он был выпаян, ничего не изменилось).
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 02:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01389 секунд с 7
ELECTRONIX ©2004-2016