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

 
 
 
Reply to this topicStart new topic
> I2C STM32F103, Помогите тразобраться
MiklPolikov
сообщение Mar 16 2018, 22:18
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Интерфейс I2C МК STM32F103.
Пытаюсь подружить с пирометром MLX90614

Ни как не могу понять: После передачи адрес(W) + команда , нужно делать Stop Condition ? Или сразу ещё один Start Condition и дальше опять адрес( R ) ?
Эскизы прикрепленных изображений
Прикрепленное изображение
 

Прикрепленные файлы
Прикрепленный файл  MLX90614.pdf ( 2.04 мегабайт ) Кол-во скачиваний: 7
 


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 17 2018, 04:59
Сообщение #2


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Сразу старт и адрес. На картинке же показано. Всяко бывает.
Go to the top of the page
 
+Quote Post
gerber
сообщение Mar 17 2018, 05:03
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Stop не нужен, это так называемый Repeated Start Condition, часто используется для продолжения обмена без освобождения шины.


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 17 2018, 09:12
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



В однозадачной системе с одним ведущим (master) на шине - без разницы. Можно передавать stop, можно не передавать. Единственный случай, когда обязательно нужно передать stop - это при записи в память (там stop запускает процесс записи). Во всех остальных случаях вместо stop-start можно передавать start, это будет т.н. repeated start. В многозадачной системе или при наличии нескольких независимых ведущих в данном случае нужно обязательно передавать repeated start, который гарантирует, что между записью адреса и чтением никто не влезет на шину и не перепишет установленный адрес.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Mar 17 2018, 11:58
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(Сергей Борщ @ Mar 17 2018, 12:12) *
нужно обязательно передавать repeated start, который гарантирует, что между записью адреса и чтением никто не влезет на шину и не перепишет установленный адрес.

Полагаю, это мой случай. Т.к. передача команды это адрес в MLX90614 , а следующее за ним чтение - это чтение по этому адресу.
Так вот: если делать старт-стоп, то MLX90614 не работает.
А если пытаться передавать повторный старт из STM32F103 , то не работает он , а именно при последующей передаче адреса не выставляет бит "адрес передан". Да и в документации на МК написано, что "старт нужно передавать при сброшенном бите BUSY" , а когда обмен идёт, этот бит уже стоит. Хотя в STM32F429 этот же код работал, и там такой же I2C !

Может такое быть, что I2C в МК не умет передавать повторный старт ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 17 2018, 14:01
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (MiklPolikov @ Mar 17 2018, 13:58) *
Может такое быть, что I2C в МК не умет передавать повторный старт ?
Нет, не может. Для него что повторный, что обычный старт - без разницы.
QUOTE (MiklPolikov @ Mar 17 2018, 13:58) *
Хотя в STM32F429 этот же код работал, и там такой же I2C !
Буквально позавчера столкнулся с такой же фигней - код, работавший на 407, отказался работать на 107. Код на прерываниях, естественно, никакого ожидания сброса BUSY в цикле в нем нет. Посмотрел лог. анализатором - увидел посылки по 14 бит (?) с совершенно не теми данными, которые я запихивал в регистр, плюнул, написал за час I2C ногодрыгом (благо мне при старте программы надо один раз считать MAC из внешней памяти). Тратить время на поиски блох в данном проекте посчитал непродуктивным.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
gerber
сообщение Mar 17 2018, 14:49
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Цитата(MiklPolikov @ Mar 17 2018, 14:58) *
А если пытаться передавать повторный старт из STM32F103 , то не работает он , а именно при последующей передаче адреса не выставляет бит "адрес передан". Да и в документации на МК написано, что "старт нужно передавать при сброшенном бите BUSY" , а когда обмен идёт, этот бит уже стоит.

В 103 довольно капризный I2C, требующий точного соблюдения всей циклограммы, расписанной в даташите событийно (EV5-EV9), и правильной очистки статусных бит, как написано. Вот псевдо-код (псевдо - потому, что на бесконечных циклах ожидания), работающий на 103 в режиме мастера, с repeated start, без прерываний (чтение из регистра устройства с I2C адресом 0):

Код
void CI2C1::ReadByte(u8 nOffset, u8* pData)
{
  u8 data;
  u16 sr1, sr2;

  I2C1->CR1 |= I2C_CR1_START;
  while (!(I2C1->SR1 & I2C_SR1_SB));

  I2C1->DR = 0x00;
  while (!(I2C1->SR1 & I2C_SR1_ADDR));
  sr1 = I2C1->SR1;
  sr1 = sr1; // prevent warning
  sr2 = I2C1->SR2;
  sr2 = sr2; // prevent warning
  
  I2C1->DR = nOffset;
  while (!(I2C1->SR1 & I2C_SR1_BTF));

  I2C1->CR1 |= I2C_CR1_START; // repeated start
  while (!(I2C1->SR1 & I2C_SR1_SB));

  I2C1->DR = 0x01;
  while (!(I2C1->SR1 & I2C_SR1_ADDR));
  sr1 = I2C1->SR1;
  sr2 = I2C1->SR2;

  while (!(I2C1->SR1 & I2C_SR1_RXNE));
  data = I2C1->DR;  
  I2C1->CR1 |= I2C_CR1_STOP;
  *pData = data;
}


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th April 2024 - 20:11
Рейтинг@Mail.ru


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