|
STM32, I2C, HAL, HAL_I2C_Slave_Receive_IT |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 19)
|
Apr 6 2016, 11:31
|
Участник

Группа: Участник
Сообщений: 27
Регистрация: 11-04-06
Пользователь №: 16 029

|
Цитата(Метценгерштейн @ 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 должна вызываться сама, цикл не нужен.
Сообщение отредактировал Neo_Matrix - Apr 6 2016, 12:46
|
|
|
|
|
Apr 15 2016, 11:46
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Это не принципиально- как с гита скачать. Можно и просто текст скопировать было. Тем не менее, вопрос остается. Попробую еще раз переформулировать его. есть ф-я 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(); } Получается, надо единожды передать ей массив и размер и структуру? Дальше само на прерываниях будут приниматься значения в массив? дополню вопрос- чтобы еще раз получить сообщение в режиме слейва мне что надо сделать? Ждать, пока массив обновится или вызывать повторно эту ф-ю? Вот что не ясно.
|
|
|
|
|
Apr 16 2016, 09:33
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
т.е. чтобы получить новую порцию байт- вызываю ф-ю HAL_I2C_Slave_Receive_IT я ее вызываю, она активна, как только там данные пришли, на их получила? Или вызвав ее, если нету данных, то ничего потом не будет принято? Если данные позже придут. Подглядел на ютубе- вызывание делается в ф-ии HAL_I2C_SlaveRxCpltCallback  Это оптимальное решение, наверное?
|
|
|
|
|
Apr 29 2016, 12:59
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
Разобрался немного. Чтобы принять данные на прерываниях в режиме слейва, надо делать так: До входа в основную петлю вызываем ф-ю Код 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 запрещаются. Мы т.о. снова их разрешаем.
|
|
|
|
|
May 30 2016, 08:18
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
ерунда какая- то творится с 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?
|
|
|
|
|
Sep 21 2016, 10:35
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

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