Easyelectronics.ru

Электроника для всех
Текущее время: 20 июл 2018, 03:59

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 09 июл 2018, 17:50 
Только пришел

Зарегистрирован: 30 окт 2017, 18:12
Сообщения: 25
Добрый день, уважаемы форумчане!

Имеется камень из темы, который работает по шине I2C в режиме ведомого (slave). Процесс чтения работает без проблем, но при запросе от мастера данных происходит зависание интерфейса, а именно установка флагов TRA и BUSY (по идеи флаги сбрасываются при отправке данных), в результате чего линия тактирования SDL оказывается подтянута к земле. Выручает программный сброс модуля, но хотелось бы избавиться от этого костыля.

Инициализация модуля:
Код:
/**************Инициализация I2C***********/
void I2C_Setup(void)
{
 
  __HAL_RCC_I2C1_CLK_ENABLE();          //тактирование
 
   
    I2C1->CCR |= 0x2EE;
    I2C1->CR1=0;                                                        //обновим после сброса
    I2C1->CR1 |= I2C_CR1_PE | I2C_CR1_ACK;                              //вкл + АСК 
    I2C1->CR2 |= I2C_CR2_ITEVTEN |I2C_CR2_ITBUFEN |I2C_CR2_ITERREN | 30; //Прерывания + скорость
    I2C1->OAR1 |= I2C_OAR1_ADD2 ;                                       //адрес устройства (2)
   
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);                                   //разрешим прерывания
    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
}



Работа с модулем:
Код:
void I2C1_EV_IRQHandler(void)
{
uint32_t temp1,temp2;
if((I2C1->SR1 >>I2C_SR1_ADDR_Pos)&1)    //если получили адрес 
{
  temp1 = I2C1->SR1;    //прочитаем 1 регистр
  temp2 = I2C1->SR2;    //прочитаем 2 регистр
}
if((I2C1->SR1 >>I2C_SR1_RXNE_Pos)&1)    //что-то в буфере на прием
{
  data1[cntt++]=I2C1->DR;               //пишем в кольцевой
 
  if(cntt==999)
    cntt=0;
}
if((I2C1->SR1 >>I2C_SR1_TXE_Pos)&1)    //запрос на отправку
{
  I2C1->DR=0;  //отправим бит   
  //и тут устанавливаются флаги
  //и происходит зависание
}
if((I2C1->SR1 >>I2C_SR1_STOPF_Pos)&1)   //стоп бит
{
  temp1 = I2C1->SR1;
  I2C1->CR1 |= I2C_CR1_PE | I2C_CR1_ACK;
}


}



Корявый костыль, который хочется удалить. Крутится в основном цикле.
Код:
//Костыль от зависания I2C
    if((I2C1->SR2 >>I2C_SR2_BUSY_Pos)&1 && (I2C1->SR2 >>I2C_SR2_TRA_Pos)&1)     //если установлены оба флага, ждем отправки
    {
      while((I2C1->SR1 >>I2C_SR1_TXE_Pos)&1);  //ждем пока не отправятся данные
      I2C1->CR1 |= I2C_CR1_SWRST;              //перезагрузим I2C
      I2C_Setup();
    }



PS (I2C1->SR2 >>I2C_SR2_BUSY_Pos)&1 - мне кажется, что эта конструкция не очень красивый способ опроса одного бита. Как сделать более корректно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 09 июл 2018, 19:21 
Заглядывает иногда

Зарегистрирован: 22 авг 2014, 12:29
Сообщения: 85
((I2C1->SR2 & I2C_SR2_BUSY) == 0) или ((I2C1->SR2 & I2C_SR2_BUSY) != 0) или ((I2C1->SR2 & I2C_SR2_BUSY) == I2C_SR2_BUSY) проверь в stm32F207xx.h описание бит в первых версиях были ошибки . Не вижу в прерывание его сброса .


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 10 июл 2018, 12:39 
Только пришел

Зарегистрирован: 30 окт 2017, 18:12
Сообщения: 25
Цитата:
Не вижу в прерывание его сброса


Сброса какого бита? BUSY и TXE вроде же аппаратно должен сбрасываться? Или я ошибаюсь?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 11 июл 2018, 00:36 
Заглядывает иногда

Зарегистрирован: 22 авг 2014, 12:29
Сообщения: 85
Вы включили во сколько источников прерывания . часть из них сбрасываются в ручную у вас нету сбросов если на столе заработает то в жизни прога будет висеть . Плюс надо смотреть уровни оптимизации. Там половина будет выкинута компилятором . например вот это будет оптимизировано .
if((I2C1->SR1 >>I2C_SR1_ADDR_Pos)&1) //если получили адрес
{
temp1 = I2C1->SR1; //прочитаем 1 регистр
temp2 = I2C1->SR2; //прочитаем 2 регистр
}
Это возможно будет оптимизировано
не знаю ставили вы модификаторы или нет при инициализации .

data1[cntt++]=I2C1->DR; //пишем в кольцевой
if(cntt==999)
cntt=0;

в конце я бы поставил барьер на выполнение команд .



Bit 10 ITBUFEN: Buffer interrupt enable
0: TxE = 1 or RxNE = 1 does not generate any interrupt.
1: TxE = 1 or RxNE = 1 generates Event Interrupt (whatever the state of DMAEN)Inter-integrated circuit (I2C) interface RM0033

Bit 9 ITEVTEN: Event interrupt enable
0: Event interrupt disabled
1: Event interrupt enabled
This interrupt is generated when:
– SB = 1 (Master)
– ADDR = 1 (Master/Slave)
– ADD10= 1 (Master)
– STOPF = 1 (Slave)
– BTF = 1 with no TxE or RxNE event
– TxE event to 1 if ITBUFEN = 1
– RxNE event to 1if ITBUFEN = 1
ITERREN: Error interrupt enable
0: Error interrupt disabled
1: Error interrupt enabled
This interrupt is generated when:
– BERR = 1
– ARLO = 1
– AF = 1
– OVR = 1
– PECERR = 1
– TIMEOUT = 1
– SMBALERT = 1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 11 июл 2018, 21:23 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 1333
При любой оптимизации можно посмотреть код и понять, что выкинули.
И вообще полезно смотреть код, что бы он получался оптимальным.
Это я про
if ((...->SR >> n) & 1)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: STM32F207. I2C модуль. Зависание при отправке
СообщениеДобавлено: 11 июл 2018, 21:47 
Старожил

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 201
x893 писал(а):
И вообще полезно смотреть код, что бы он получался оптимальным.
Мне кажется для начала надо просто перестать мудрить. Если хочется проверить бит, то просто проверяй его и компилятор сам всё сделает.

x893 писал(а):
Это я про
if ((...->SR >> n) & 1)
Задумка то хорошая, а вот реализация... Если не мудрить, то компилятор сам почти так и сделает, только влево.
Код:
while(!(TIM6->SR & TIM_SR_UIF));
===============================
        LDR.N    R0,??DataTable2_1  ;; 0x40001010
??XXX:
        LDR      R1,[R0, #+0]
        LSLS     R2,R1,#+31
        BPL.N    ??XXX


Так что, для начала надо научиться просто не мешать компилятору.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB