Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32, I2C, HAL
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Метценгерштейн
Не могу понять- если я в слейве хочу принимать данные на прерываниях, то эта ф-я сама будет вызываться что-ли? Или мне ее крутить самому надо в вечном цикле? Почему тогда она к прерываниям относится? Если это просто опрос ф-ии?
Просто логику не понять.
Neo_Matrix
Цитата(Метценгерштейн @ Apr 1 2016, 09:06) *
Не могу понять- если я в слейве хочу принимать данные на прерываниях, то эта ф-я сама будет вызываться что-ли? Или мне ее крутить самому надо в вечном цикле? Почему тогда она к прерываниям относится? Если это просто опрос ф-ии?
Просто логику не понять.

Как я понял Вам нужна колбэк функция. Которая вызовется после окончания приема. Если проэкт генерился в КубеМХ.
At reception end of transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can
add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback()

HAL_I2C_Slave_Receive_IT должна вызываться сама, цикл не нужен.
Метценгерштейн
Спасибо.
Итак,
HAL_I2C_Slave_Receive_IT
вызывается сама по окончании приема, без цикла опроса.

HAL_I2C_SlaveRxCpltCallback()
это откуда взялось? Её мне как-то надо использовать? Или достаточно первой?
Да, проект в кубе сгенерён.



Tanya
Цитата(Метценгерштейн @ Apr 14 2016, 17:34) *
HAL_I2C_SlaveRxCpltCallback()
это откуда взялось? Её мне как-то надо использовать? Или достаточно первой?

Там есть затычка-пустышка с атрибутом __weak.
А Вам нужно написать нужное Вам без этого атрибута.
Метценгерштейн
т.е. я переписываю у себя ф-ю
HAL_I2C_SlaveRxCpltCallback()
куда происходит вызов при получении данных в прерывании?

А HAL_I2C_Slave_Receive_IT
как-то использую?

x893
Как то придется использовать
I2C_TwoBoards_ComIT
Метценгерштейн
раньше была кнопка dowload zip, теперь нет её.
git-clone
выдает ошибку на ссылку. Только в браузере могу просмотреть.
Выкачать можно от туда? И как?
Kabdim
Надо перейти в корень хранилища и там всё есть.
x893
а так ?
STM32Cube_FW_F4
Хотя все эти примеры есть локально в хранилище Куба (путь есть в настройках Куба)
Метценгерштейн
Это не принципиально- как с гита скачать. Можно и просто текст скопировать было.
Тем не менее, вопрос остается.

Попробую еще раз переформулировать его.
есть ф-я weak, которая была переписана.
Код
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
  /* Turn LED6 on: Transfer in reception process is correct */
  BSP_LED_On(LED6);
}

Я так понимаю, что если нам при приеме надо что-то делать, то это именно она. Тут она зажигает LED. Можно обойтись без нее? Думаю, да. Судя по коду.


Дальше, есть вызов ф-и в main() ,но до вечного цикла
Код
  if(HAL_I2C_Slave_Receive_IT(&I2cHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
  {
    /* Transfer error in reception process */
    Error_Handler();        
  }


Получается, надо единожды передать ей массив и размер и структуру?
Дальше само на прерываниях будут приниматься значения в массив?

дополню вопрос- чтобы еще раз получить сообщение в режиме слейва мне что надо сделать? Ждать, пока массив обновится или вызывать повторно эту ф-ю?
Вот что не ясно.
x893
Конечно надо её вызывать. По коду видно что после приема нужного кол-ва байт прерывания запрещаются.
Метценгерштейн
т.е. чтобы получить новую порцию байт- вызываю ф-ю
HAL_I2C_Slave_Receive_IT
я ее вызываю, она активна, как только там данные пришли, на их получила? Или вызвав ее, если нету данных, то ничего потом не будет принято? Если данные позже придут.

Подглядел на ютубе- вызывание делается в ф-ии
HAL_I2C_SlaveRxCpltCallback



Это оптимальное решение, наверное?
Метценгерштейн
Вот честно, так и нет ясности- для приема в режиме мастера или слейва на прерываниях, надо как вызывать ф-ю?
Чтобы при приходе адреса данного I2C устройства, происходили прерывания и выполнялась ф-я?
Не крутить же ее все время? Что это за прерывания тогда такие?
Метценгерштейн
Разобрался немного.
Чтобы принять данные на прерываниях в режиме слейва, надо делать так:
До входа в основную петлю вызываем ф-ю
Код
HAL_I2C_Slave_Receive_IT(&hi2c2, slave_rx_buff, 10);


и теперь проц будет ждать пока не придут данные. После этого, массив slave_rx_buff заполнится данными и на этом прием закончится. Ничего больше не будет приниматься.
Чтобы продолжить прием, надо написать ф-ю
Код
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle)
{
    if(I2cHandle->Instance==hi2c2.Instance)
    {
        HAL_I2C_Slave_Receive_IT(&hi2c2, slave_rx_buff, 10);
    }
}

где при каждом прерывании будет выполнятся код в теле. И запускаться вновь на ожидание прерываний. Причина- как писали выше- после приема данных, прерывания по i2c запрещаются. Мы т.о. снова их разрешаем.
Метценгерштейн
еще вопрос- как при приеме в ф-ю
HAL_I2C_Slave_Receive_IT
данных из вне от мастера, узнать, сколько байт было передано и реально принято?
Не нашел в I2C счетчика принятых байт.
Метценгерштейн
ерунда какая- то творится с I2C.
Принимает на прерываниях один пакет, дальше ничего не принимает и виснет.
Заметил, что
Код
while (HAL_I2C_Slave_Receive_IT( &hi2c1, RxBuf, (sizeof(RxBuf)/sizeof(RxBuf[0])) ) != HAL_OK);
while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);

вторая строчка выдает
Код
HAL_I2C_STATE_BUSY


Кто-то сталкивался? Как корректно вообще работать с I2C на прерываниях и HAL?
Метценгерштейн
при работе с другим МК STM32 в качестве мастера, все ок.
Как только подключаюсь к другой железке, она мастер, принимаю один пакет, а после второго пакета висну, в регистре ISR висит бит BUSY.
Из-за чего может быть?
delamoure
Удалось побороть?
k155la3
Цитата(Метценгерштейн @ May 31 2016, 17:20) *
при работе с другим МК STM32 в качестве мастера, все ок.
Как только подключаюсь к другой железке, она мастер, принимаю один пакет, а после второго пакета висну, в регистре ISR висит бит BUSY.
Из-за чего может быть?

Проверяйте отработку слейва по ACK-NACK.
Возможно также, что в этом случае "залип" мастер, ожидающий готовности slave.
Посмотрите осцилографом, что твроится на шине. А лучше лог. анализатором.

Кроме того ожидание в стиле
while( GetState() ) { forever} не феншуй, по причине возможного зависания и постоянного дергания опрашиваемой периферии.
(если это не опрос флага-переменной, которая устанавливается в векторе прерывания)
Метценгерштейн
Цитата(Метценгерштейн @ May 31 2016, 17:20) *
при работе с другим МК STM32 в качестве мастера, все ок.
Как только подключаюсь к другой железке, она мастер, принимаю один пакет, а после второго пакета висну, в регистре ISR висит бит BUSY.
Из-за чего может быть?

Побороть не удалось. HAL на кубе, применительно к I2C глючный. Замечено, что тот же код работает на разных МК совершенно по разному.
Пришлось на регистрах писать.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.