Easyelectronics.ru

Электроника для всех
Текущее время: 05 июн 2020, 15:55

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



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Проблемы с I2C на F303
СообщениеДобавлено: 01 апр 2020, 16:22 
Старожил
Аватара пользователя

Зарегистрирован: 28 сен 2012, 22:11
Сообщения: 389
Откуда: г.Таганрог/г.Геленджик/г.Одесса
Всем привет.
Итак. Есть проект часов на STM32F303CBT. Использую динамическую индикацию, что подразумевает постоянную работу таймера для реализации этой самой индикации. Прерывание таймера вызывается с периодом в 1 мс, выполнение кода занимает не более 5 мкс. Кроме работы индикации каждую секунду производится обмен данными с микросхемой RTC по I2C. Обмен короткий, всего лишь забрать 3 байта времени. А теперь самое интересное. Обмен идет какое-то время после чего I2C ломается. Точно установлено, что виной всему работа таймера динамической индикации. Очевидно, прерывание возникает во время работы I2C и происходит сбой работы, после чего вместо отправки всего, как положено, в линию уходит лишь это:

Изображение

Т.е. ни СТАРТ, ни СТОП последовательности, просто нулевой байт. Временами проскакивает вот такое:
Изображение

Причем проблема решается лишь перезапуском I2C. Настройки I2C вот такие:
Show I2C


Обмен данными сделан вот так:
Show I2C


Ну и сам запрос времени:

Код:
void I2C_RTC_Get_Time(uint8_t *H, uint8_t *M, uint8_t *S){
   uint8_t Data[4];

   I2C2_Write_Byte(0x00); // Time Register Address
   
   I2C2_Read_Mass(3, Data);
   
   *S = bcd(Data[0]);
   *M = bcd(Data[1]);
   *H = bcd(Data[2]);
}


Самое интересное, что есть другой проект, где таймер срабатывает в 60 раз чаще. И все работает отлично, никаких сбоев. Единственное отличие - номер используемого I2C. Тут второй, а там первый. Что я не учел и как избавиться от проблемы?

_________________
Количество полученного опыта прямо пропорционально выведенному из строя оборудованию....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 11 апр 2020, 13:33 
Старожил
Аватара пользователя

Зарегистрирован: 28 сен 2012, 22:11
Сообщения: 389
Откуда: г.Таганрог/г.Геленджик/г.Одесса
Есть тут кто?..

_________________
Количество полученного опыта прямо пропорционально выведенному из строя оборудованию....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 11 апр 2020, 14:18 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1477
Открыть RM и строго по спецификации КАЖДЫЙ доступ к регистрам I2C. К сожалению, он не терпит подобной отсебятины.

PS: А где обработка ошибок?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 11 апр 2020, 16:51 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1477
Подкину идей для затравки. Ожидание статусного бита может закончится ошибкой или таймаутом. Это надо обрабатывать. Это помимо правильной последовательности действий, которая первична.
Код:
//Ожидание бита это не только ожидание, но и выход по ошибке !!!
if(!WaitISRBitSet<I2C_ISR_TXIS>()) return false;

template<uint32_t Bit>
static inline bool WaitISRBitSet()
{
  uint32_t sr;
  uint32_t time_out=10000; // Значение от балды
  do
  {
    sr=base()->ISR;
    if((sr&( I2C_ISR_NACKF | I2C_ISR_ARLO | I2C_ISR_BERR)) || (time_out--==0))
    {
      base()->ICR = I2C_ICR_NACKCF | I2C_ICR_BERRCF | I2C_ICR_ARLOCF;
      return false;
    }
  }
  while( !(sr&Bit) );
  return true;
}
//Тут base() это I2C1 или I2C2


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 13 апр 2020, 16:55 
Старожил
Аватара пользователя

Зарегистрирован: 28 сен 2012, 22:11
Сообщения: 389
Откуда: г.Таганрог/г.Геленджик/г.Одесса
Ага. Почитаю еще раз RM, хотя пока не могу понять, где я неправильно обращаюсь к регистрам. А обработку ошибок не делал, т.к. микруха стоит в 10мм от МК и если она сдохла, то и всему остальному работать уже и не нужно. Исправлюсь =)

_________________
Количество полученного опыта прямо пропорционально выведенному из строя оборудованию....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 13 апр 2020, 18:10 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1477
BARS_ писал(а):
хотя пока не могу понять, где я неправильно обращаюсь к регистрам.

Вот смотри. Например, у меня в общем виде функция "записи".
Show Запись без ограничений по длине
С виду страшно, но там под if constexp спрятано несколько совершенно разных ситуаций. Если упростить до твоего случая короткой посылки, то получится что-от типа
Код:
bool MasterWrite_(const uint8_t hw_adr, uint8_t *data, uint8_t len)
{
  // while(base()->ISR & I2C_ISR_BUSY); // если надо
  base()->CR2 = _VAL2FLD(I2C_CR2_NBYTES,len) | hw_adr | I2C_CR2_AUTOEND | I2C_CR2_START;
  while(len--)
  {
    if(!waitISRBitSet<I2C_ISR_TXIS>()) return false;
    base()->TXDR = *data++;
  }   
  return true;
}
А если всего один байт, то вообще
Код:
bool MasterWrite_byte(const uint8_t hw_adr, uint8_t data)
{
  // while(base()->ISR & I2C_ISR_BUSY); // если надо
  base()->CR2 = _VAL2FLD(I2C_CR2_NBYTES,1) | hw_adr | I2C_CR2_AUTOEND | I2C_CR2_START;
  if(!waitISRBitSet<I2C_ISR_TXIS>()) return false;
  base()->TXDR = data;
  return true;
}
Сравни с твоим "судорогом". С чтением смысл примерно такой же.
BARS_ писал(а):
А обработку ошибок не делал, т.к. микруха стоит в 10мм
Это большое заблуждение. I2C всё равно когда-нибудь, но повиснет.


Последний раз редактировалось VladislavS 13 апр 2020, 20:30, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 13 апр 2020, 20:11 
Старожил
Аватара пользователя

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 1477
Собственно функция чтения произвольной длины
Show Чтение
Точно так же для коротких данных вырождается в
Код:
bool MasterRead_(const uint8_t hw_adr, uint8_t *data, uint8_t len)
{
  while(base()->ISR & I2C_ISR_BUSY);
  base()->CR2 = I2C_CR2_RD_WRN | _VAL2FLD(I2C_CR2_NBYTES,len) | hw_adr | I2C_CR2_AUTOEND | I2C_CR2_START;
  while(len--)
  {         
    if(!waitISRBitSet<I2C_ISR_RXNE>()) return false;
    *data++=base()->RXDR;
  }
  return true;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Проблемы с I2C на F303
СообщениеДобавлено: 15 апр 2020, 14:48 
Старожил
Аватара пользователя

Зарегистрирован: 28 сен 2012, 22:11
Сообщения: 389
Откуда: г.Таганрог/г.Геленджик/г.Одесса
Огромное спасибо, понял свою ошибку =) Вроде все делал так, но чуть по другому. Сутки непрерывной работы - полет нормальный. Ошибки периодически возникают, но к зависанию не приводят при следующем чтении все гуд.

_________________
Количество полученного опыта прямо пропорционально выведенному из строя оборудованию....


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


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


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

Сейчас этот форум просматривают: Glebiys, Google [Bot]


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

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

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