MiklPolikov 0 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба Интерфейс I2C МК STM32F103. Пытаюсь подружить с пирометром MLX90614 Ни как не могу понять: После передачи адрес(W) + команда , нужно делать Stop Condition ? Или сразу ещё один Start Condition и дальше опять адрес( R ) ? MLX90614.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Сразу старт и адрес. На картинке же показано. Всяко бывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Stop не нужен, это так называемый Repeated Start Condition, часто используется для продолжения обмена без освобождения шины. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 135 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба В однозадачной системе с одним ведущим (master) на шине - без разницы. Можно передавать stop, можно не передавать. Единственный случай, когда обязательно нужно передать stop - это при записи в память (там stop запускает процесс записи). Во всех остальных случаях вместо stop-start можно передавать start, это будет т.н. repeated start. В многозадачной системе или при наличии нескольких независимых ведущих в данном случае нужно обязательно передавать repeated start, который гарантирует, что между записью адреса и чтением никто не влезет на шину и не перепишет установленный адрес. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MiklPolikov 0 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба нужно обязательно передавать repeated start, который гарантирует, что между записью адреса и чтением никто не влезет на шину и не перепишет установленный адрес. Полагаю, это мой случай. Т.к. передача команды это адрес в MLX90614 , а следующее за ним чтение - это чтение по этому адресу. Так вот: если делать старт-стоп, то MLX90614 не работает. А если пытаться передавать повторный старт из STM32F103 , то не работает он , а именно при последующей передаче адреса не выставляет бит "адрес передан". Да и в документации на МК написано, что "старт нужно передавать при сброшенном бите BUSY" , а когда обмен идёт, этот бит уже стоит. Хотя в STM32F429 этот же код работал, и там такой же I2C ! Может такое быть, что I2C в МК не умет передавать повторный старт ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 135 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Может такое быть, что I2C в МК не умет передавать повторный старт ?Нет, не может. Для него что повторный, что обычный старт - без разницы. Хотя в STM32F429 этот же код работал, и там такой же I2C !Буквально позавчера столкнулся с такой же фигней - код, работавший на 407, отказался работать на 107. Код на прерываниях, естественно, никакого ожидания сброса BUSY в цикле в нем нет. Посмотрел лог. анализатором - увидел посылки по 14 бит (?) с совершенно не теми данными, которые я запихивал в регистр, плюнул, написал за час I2C ногодрыгом (благо мне при старте программы надо один раз считать MAC из внешней памяти). Тратить время на поиски блох в данном проекте посчитал непродуктивным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба А если пытаться передавать повторный старт из 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться