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

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> залипает шина I2C в STM32, на МК режим slave
Метценгерштейн
сообщение Oct 11 2016, 18:30
Сообщение #46


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Цитата(Jury093 @ Oct 11 2016, 19:12) *
как минимум, смените адрес слейва на допустимый.. i2cdetect вам в помощь..

по стандарту от 0х03 должен быть.
Но с адресом 0х01 работает. И соседнее устройство аналогичное, но на AVR имеет адрес 0х02. Все работает. Возможно, допустима работа в этом диапазоне.

Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Oct 12 2016, 14:23
Сообщение #47


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



Вроде локализовали проблему.
Прога на Линуксе не всегда отправляла пакеты моему устройству. Допустим, из параллельной консоли сделать i2cset... и команда на STM приходит нормально.

Вопрос по корректной реализации I2C прерывания.
Я вхожу в прерывание
Код
void I2C1_IRQHandler(void){


корректно ли делать внутри цикл for(;;) , чтобы он не выходил из прерывания, а крутился там пока флаги все не обработал? Или так не очень правильно?

Как получается вход в прерывание? Выскочило несколько флагов, он вошел в прерывание? И все там пачкой обработал?
Go to the top of the page
 
+Quote Post
Nixon
сообщение Oct 12 2016, 16:22
Сообщение #48


Гуру
******

Группа: Админы
Сообщений: 2 736
Регистрация: 17-06-04
Из: Киев
Пользователь №: 48



C этого и начинать нужно было. Не стоит нагружать прерывание сверх необходимого. Приняли/передали и выскочили. Для примера:
Код
void handler ( void ) {
    uint8_t  byte;
    
    if (_i2c->ISR & I2C_ISR_ADDR) {  // пришел ADDR
      _i2c->ICR = I2C_ISR_ADDR;                                        
    } else if (_i2c->ISR & I2C_ISR_RXNE) {  // прием байта
      byte = _i2c->RXDR;
      _buf_rx.push(byte);
    } else if (_i2c->ISR & I2C_ISR_TXIS) {  // запрос байта
      _buf_tx.pop(byte);
      _i2c->TXDR = byte;
    } else if (_i2c->ISR & I2C_ISR_NACKF) { // трансфер закончен, пришел NACK
      _i2c->ICR = I2C_ISR_NACKF;
    } else if (_i2c->ISR & I2C_ISR_STOPF) { // пришел STOP
      _i2c->ISR |= I2C_ISR_TXE;
      _i2c->ICR = I2C_ISR_STOPF;
    } else if (_i2c->ISR & I2C_ISR_BERR) {  // I2C Bus Error
      _i2c->ICR = I2C_ISR_BERR;
    } else if (_i2c->ISR & I2C_ISR_OVR) {  // I2C Over-Run/Under-Run
      _i2c->ICR = I2C_ISR_OVR;
    } else if (_i2c->ISR & I2C_ISR_ARLO) {  // I2C Arbitration Loss
      _i2c->ICR = I2C_ISR_ARLO;
    }    
  }


P.S. Это для STM32L0


--------------------
Вам помочь или не мешать?
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Oct 13 2016, 07:53
Сообщение #49


Профессионал
*****

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



у вас код if else if
другими словами, в прерывании только одно событие обработается.
А не может придти два события сразу?

т.е. нет смысла делать
if
if
if
...
?

и еще - насчет по быстрому обработали прерывание и выскочили-
Код
else if (_i2c->ISR & I2C_ISR_RXNE) {  // прием байта
      byte = _i2c->RXDR;
      _buf_rx.push(byte);
    }

мы тут не сразу выскакиваем, идем сначала в _buf_rx.push(), там что-то делаем, потом только выскакиваем.
Так что можно и в самом прерывание тогда это же делать.
Go to the top of the page
 
+Quote Post
Timmy
сообщение Oct 13 2016, 09:20
Сообщение #50


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(Метценгерштейн @ Oct 13 2016, 10:53) *
у вас код if else if
другими словами, в прерывании только одно событие обработается.
А не может придти два события сразу?

Если придут два события сразу, они обработаются в двух последовательных входах в обработчик прерывания. Вообще, вариант от Nixon является наилучшим универсальным и имеет смысл при использовании подгрупп приоритетов прерываний, и принадлежности прерывания I2C не к самой приоритетной подгруппе. В этом случае может быть целесообразно выскочить из обработчика прерывания как можно скорее, чтобы передать управление обработчику более привилегированной подгруппы, если возникнет запрос на него. Во всех прочих случаях вариант Nixon, как и большинство универсальных решений sm.gif , создаёт более длинный код и большее время выполнения при одновременной обработке нескольких событий.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 31st August 2025 - 00:47
Рейтинг@Mail.ru


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