Перейти к содержанию
    

HAL STM32 Как принять неизвестное число байт по I2C ?

Друзья,

не могу понять, вот есть эти замечательные функции приема данных по I2C:

HAL_I2C_Slave_Receive(&hi2c, &Buffer,  NumBytes, Timeout )

HAL_I2C_Slave_Receive_IT(&hi2c, &Buffer,  NumBytes)

HAL_I2C_Slave_Receive_DMA(&hi2c, &Buffer,  NumBytes)

Но как мне быть если неизвестно сколько байт нам пришлют ? Кучу примеров просмотрел, не понимаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 minutes ago, TOG said:

Но как мне быть если неизвестно сколько байт нам пришлют ?

Наверно скажу сейчас очевидную вещь... но... написать свои функции? не?

С другой стороны, а как будем выставлять STOP на шине, не зная, сколько пришлют? Ведь мастер (у вас же мастер???) должен владеть этой информацией.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 минуту назад, TOG сказал:

Но как мне быть если неизвестно сколько байт нам пришлют ?

А по какому признаку вы любыми другими замечательными функциями поняли бы, что вам перестали посылать байты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 minutes ago, Сергей Борщ said:

А по какому признаку вы любыми другими замечательными функциями поняли бы, что вам перестали посылать байты?

Я думаю в режиме IT или DMA как-то так:

while ( (HAL_I2C_GetState(&hi2c) != HAL_I2C_STATE_READY) )
{    
}

а как в режиме опроса не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, TOG said:

Я думаю в режиме IT или DMA как-то так:

Кстати, может быть вам анализировать ACK/NOT ACK от вашего устройства?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, haker_fox said:

Кстати, может быть вам анализировать ACK/NOT ACK от вашего устройства?

я пишу программу для slave устройства. Master всегда ACK

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, haker_fox said:

(у вас же мастер???

HAL_I2C_Slave_Receive

Пожалуйста, читайте сообщения, на которые отвечаете. Авось, и смысл в ваших ответах появится...

 

26 minutes ago, Сергей Борщ said:

А по какому признаку вы любыми другими замечательными функциями поняли бы, что вам перестали посылать байты?

Очень часто из заголовка пакета можно понять, какой он длины. И очень часто писатели халов про это забывают... (ну оно и понятно - сразу низкоуровневый драйвер надо как-то "сцеплять" с протоколом).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, TOG сказал:

Я думаю в режиме IT или DMA как-то так:

Что должно произойти физически на шине, чтобы ведомый понял: байтов больше нет?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 minutes ago, Сергей Борщ said:

Что должно произойти физически на шине, чтобы ведомый понял: байтов больше нет?

 

Как я понял когда у мастера больше нечего передавать, он посылает STOP, т.е. при высоком уровне SCL линия SDA переходит с нуля в единицу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, TOG сказал:

Как я понял когда у мастера больше нечего передавать, он посылает STOP,

Верно. А эта "библиотека" ждет флаг STOP только после приема указанного числа байтов. Это еще один аргумент отказаться от нее и написать свою функцию, которая будет ожидать этот флаг одновременно с ожиданием флага прихода нового байта.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25 minutes ago, Сергей Борщ said:

Верно. А эта "библиотека" ждет флаг STOP только после приема указанного числа байтов. Это еще один аргумент отказаться от нее и написать свою функцию, которая будет ожидать этот флаг одновременно с ожиданием флага прихода нового байта.

Да именно так.  Спасибо Сергей.

Придумал вот такие костыли. Это наверно моя самая корявая программа и работает она коряво. Но работает ;) Буду пытаться сделать без этого HAL.

while ( HAL_I2C_Slave_Receive(&hi2c, (uint8_t *)tmp, 255, TIMEOUT) != HAL_OK)
        {
            if (hi2c.XferSize == 255)    // Если за время таймаута ничего не приняли,  запускаем прием по новой
            {
                break;
            }
            else if (hi2c.XferSize == 255 - 1)  // Если приняли 1 байт
            {

            }

            else if (hi2c.XferSize == 255 - 2)  // Если приняли 2 байта
            {

            }

            else if (hi2c.XferSize == 255 - 3)  // Если приняли 3 байта
            {

            }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, esaulenka said:

Авось, и смысл в ваших ответах появится...

Простите, я вас чем-то задел в этой жизни?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...