User_1

I2C в STM32F030

20 posts in this topic

User_1    4

Всем доброго времени суток!

Кто-нибудь может поделиться рабочим примером инициализации I2C в STM32F030? Ну или может увидите в моём коде ошибку


    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, 	ENABLE);	// Включаем тактирование
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    I2C_InitTypeDef  I2C_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;		// Speed 50 MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			// Альтернативная функция
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;		// Без подтяжки
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;			// Открытый сток
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;				// Режим работы (I2C)
    I2C_InitStructure.I2C_OwnAddress1 = 0x11;				// Адрес (не важен, если устройство - мастер)
    I2C_InitStructure.I2C_Timing = 0x00300619;				// Значение для записи в регистр I2C_TIMINGR
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Cmd(I2C1, ENABLE);
    I2C_Init(I2C1, &I2C_InitStructure);

Полдня уже вожусь, никак не заводится. Компилится без ошибок, светодиод мигает (ну в основном цикле написана простая светодиодная мигалка и раз в секунду - отправка сообщения в I2C), но смотрю логическим анализатором - на ножках тишина (ну в смысле единичка всегда, они же подтянуты резисторами к плюсу)

I2C_Timing рассчитывается калькулятором от ST (I2C Timing Configuration) на основе частоты тактирования модуля I2C,  желаемой скорости шины и ещё пары параметров, калькулятор прикрепил к сообщению

I2C_Timing_Configuration_V1.0.1.xls

Edited by User_1

Share this post


Link to post
Share on other sites
snn_krs    58

Надо выбрать какая альтернативная функция используется

  GPIO_PinAFConfig( GPIOA, GPIO_PinSource9, GPIO_AF_4 );
  GPIO_PinAFConfig( GPIOA, GPIO_PinSource10, GPIO_AF_4 );

 

Share this post


Link to post
Share on other sites
User_1    4
10 минут назад, snn_krs сказал:

Надо выбрать какая альтернативная функция используется

Тоже пробовал, не помогло

Share this post


Link to post
Share on other sites

Старт складской программы по Wi-Fi/ Bluetooth-чипам от Espressif

На склад КОМПЭЛ поступили чипы, модули и отладочные платы от компании Espressif Systems на базе ESP8266 и ESP32. Стоимость всех изделий данной линейки – в 2-3 раза ниже ближайших аналогов, чипы занимают минимальное место на плате, энергоэффективны и универсальны в применении

Подробнее...

User_1    4

Запаял новый мк - заработало)

Вот рабочий код инициализации, если кому понадобится. Проверен на МК STM32F030F4P6. При частоте системной шины 8 МГц, модуль I2C работает на 400 кГц

void Init_I2C1(void)
{


    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, 	ENABLE);	// Включаем тактирование
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    I2C_InitTypeDef  I2C_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;		// Speed 50 MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;			// Альтернативная функция
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;		// Без подтяжки
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;			// Открытый сток
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;				// Режим работы (I2C)
    I2C_InitStructure.I2C_OwnAddress1 = 0x11;				// Адрес (не важен, если устройство - мастер)
    I2C_InitStructure.I2C_Timing = 0x0010020A;				// Значение для записи в регистр I2C_TIMINGR
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    GPIO_PinAFConfig( GPIOA, GPIO_PinSource9, GPIO_AF_4 );
    GPIO_PinAFConfig( GPIOA, GPIO_PinSource10, GPIO_AF_4 );

    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
}

2018-06-08_19-33-56.thumb.png.765ca2e332871b25b74e2c331ef21f2f.png

15 минут назад, snn_krs сказал:

Поменяйте местами

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

Edited by User_1
Подкорректировал код

Share this post


Link to post
Share on other sites

Вебинар Литиевые ХИТы FANSO или что нужно знать инженеру о батарейках»

20 июня компания Компэл приглашает всех желающих принять участие в вебинаре, посвященном литиевым батарейкам FANSO. На вебинаре будет рассказано о параметрах батареек, их зависимости от режима работы и эксплуатации. Будет дана информация о том, на какие параметры следует обращать внимание, выбирая литиевый ХИТ, и как избежать некоторых проблем.

Подробнее...

snn_krs    58

В самом начале файла stm32f0xx_i2c.c описана процедура инициализации. Некоторые регистры нельзя изменять при включенном устройстве.

Share this post


Link to post
Share on other sites
User_1    4
4 минуты назад, snn_krs сказал:

В самом начале файла stm32f0xx_i2c.c описана процедура инициализации. Некоторые регистры нельзя изменять при включенном устройстве.

Спасибо, исправил в коде выше

Share this post


Link to post
Share on other sites
16 часов назад, User_1 сказал:

Но где-то читал (уже не вспомню где), что нужно инициализировать только уже включенный модуль, так что оставил как есть

Улыбнуло...

Share this post


Link to post
Share on other sites
LiVit    12

После танцев с бубном с м/к STM32F103 - там I2C вылетал постоянно  и беспричинно, перешел на библиотеку CPAL, тем паче, что STMовцы её сами и рекомендуют.

Для STM32F0xxx STM32F3xx есть своя библиотека - CPAL v2. Очень рекомендую.

Share this post


Link to post
Share on other sites

В случае i2c - нескольких строчек на CMSIS явно недостаточно. Там только один алгоритм обработки ошибок - целая портянка. А без него  i2c будет работать до первого зелёного свистка, что явно не добавит надёжности девайсу. И ещё, i2c - крайне тормозная периферия. Здесь нет смысла ждать моментального отклика после прямой записи в регистры. Отчего сам алгоритм обмена начинает смахивать на магию - когда улучшенный и вычищенный от мусора код просто перестаёт работать. Это результат слишком быстрого всплытия, когда лёд ещё не успел растаять... (образное выражение) 

Причём размер портянки обработки ошибок - почти константа, без малейшей зависимости от версии чипа. Размер одинаковый, смысл сходный, а код разный. Аминь.

Share this post


Link to post
Share on other sites
Oxford    37

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

Share this post


Link to post
Share on other sites

Есть, но я всё-ещё считаю его сырым. 

На данный момент я просто сбрасываю состояние и прокачиваю шину с нулевым адресом. Однако это не совсем правильно. Там масса флагов под конкретные виды ошибок, все они должны обрабатываться по разному. И конечно-же любой сбой должен аннулировать предыдущую операцию на шине i2c.

И вот тут возникает прикол, который я не могу побороть уже чёрт знает сколько времени. Внешнее ведомое устройство помнит о сбое. Естественно обработка ошибок в нём то-же есть, причём мне кажется обработка должна выполняться по всем правилам интерфейса i2c.

Дык вот, алгоритмы не совпадают. И при этом непонятно - какой из чёрных ящиков работает не по стандарту. А сам стандарт я уже вдоль и поперёк перекопал. Даже полностью программным вариантом нагружал - ошибки разные и не повторяющиеся. 

Share this post


Link to post
Share on other sites
Oxford    37

Это вы с какой микросхемой общаетесь по I2C? И какой микроконтроллер? I2C достаточно простая шина, странно что у вас с ним проблемы возникают.

Edited by Oxford

Share this post


Link to post
Share on other sites

С активными датчиками: в которых есть собственные таймеры, буферы данных - которые обязательно нужно читать под кривым углом, регистры состояний - с чёткой последовательностью в алгоритме доступа. Это когда простой сбой на линии данных вызывает очевидный сбой в алгоритме работы датчика. И тогда уже он начинает куралесить в шину i2c.

С пассивными компонентами проблем нет. Там обработку ошибок можно существенно сократить. Но если датчик умеет работать в режиме мастера - вот тогда начинаются пляски. 

Какие именно датчики?  всё новое и связанное с авионикой.

Share this post


Link to post
Share on other sites

Думаю что эта информация не принесёт пользы.

MPU9255, TSC2007, BME280, MCP3421, и ещё с десяток подобной мелочи. Далеко не все чипы будут работать в девайсе, но они все распаяны на макетке.

 

Share this post


Link to post
Share on other sites
Oxford    37

Да все там работает не надо придумывать. Ошибки у себя ищите. Абстрактно рассуждать не интересно. Если есть конкретный случай можно рассмотреть.

Edited by Oxford

Share this post


Link to post
Share on other sites

Your content will need to be approved by a moderator

Guest
You are commenting as a guest. If you have an account, please sign in.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoticons maximum are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By Arvalon
      Здравствуйте.
      Есть камера с шиной I2C и интерфейсом "Camera Port on 21 pin ZIF connector". Информация по сигналам в наличии.
      Есть ли возможность подключить её к ПК под управлением Linux/Window (не считая физического переходника 21 пин ZIF - ножки микросхемы)? Поиск по сети выдал следующий способ. В нём используется I2C-USB переходник из USBasp программатора и микросхема MCP23017 (I2C расширитель портов). Написано что микросхема MCP23017 имеет 16 I/O портов (из 28). Далее напрашивается вопрос, хватит ли выводов микросхемы что бы подключить камеру? Читаю спецификацию на микросхему и не донца понимаю, кажется хватает.
      Опционально, можно ли избавиться от самостоятельного изготовления связки I2C-USB переходник + MCP23017 а воспользоваться готовым? Есть ли в продаже адаптер I2C-USB с достаточным количеством портов? На AliExpress'е что-то не нашлось подходящего.

      MCP23017.pdf
    • By LiVit
      Привет коллеги! Данная публикация - для тех, кто еще не все плюшки UARTA попробовал ))
      USART1 (и только он) микроконтроллеров серии STM32F030 предоставляет возможность принимать пакеты данных с неизвестной заранее длиной пакета.
      Для этого можно использовать овертаймер.
      Работает это так:
      Если в течение заданного времени не будет принят старт-бит очередного байта, генерируется прерывание.
      Время ожидания задается не физически (в секундах), а в количестве бит, которые могли бы быть приняты на данной скорости.
      т.е., если мы зададим число 16, то прерывание возникнет, если в течение времени эквивалентному приему 16 бит, на вход USART не поступит старт-бит.

      Как включить.
      1 разрешим прерывание - бит RTOIE регистра CR1
      2 зададим время (количество бит) в регистре RTOR
      3 разрешим работу овертаймера - бит RTOEN регистра CR2
      4 при возникновении прерывания от USART1, смотрим флаг RTOF в регистре ISR, - если есть флаг, значит это оно
      5 сбросим флаг прерывания - бит RTOCF в регистре ICR.
      Как я это использую.
      Включаю прерывание при инициализации порта и задаю количество бит для счетчика.
      Как только приходит первый байт сообщения - в прерывании разрешаю работу овертаймера.
      Все принятые байты сохраняю в буфер.
      Когда возникнет прерывание по овертайму - запрещаю овертаймер, и передаю пакет на парсинг.
    • By LiVit
      Приветствую, коллеги!
      Ситуация такая: есть серия устройств на STM32F030R8, на некоторых время от времени начинает греться микроконтроллер. 
      Вся логика работает, всё вроде в порядке, кроме потребления в 250мА. И перегретого корпуса микроконтроллера.
      В прошивке изначально отсутствовала инициализация неиспользуемых ног, кроме того, проц сначала старается завести внешний кварц, и только потом переходит на внутренний генератор.
      Нога BOOT0 притянута к земле напрямую, без резистора.
      На проце который уже начал перегреваться, я сделал инициализацию всех ног на вход, с подтяжкой ног к земле. Сразу завожу внутренний тактовый генератор.
      К сожалению, ему уже ничего не помогает, - даже будучи стертым, он жрет 200 мА. Как я понимаю, тут мои полномочия всё.
      Хотелось бы услышать от коллег, что именно могло вызвать такую странную неисправность проца? Может кто сталкивался? В Errata ничего подобного не нашел.
    • By AronIIStone
      Добрый день
      Возникла ситуация: имеется ноутбук IBM ThinkPad t20 с запароленым Bios. Пароль никто не помнит, но он зашит в 24rf08. Его можно прочитать програмкой для считывания данной микросхемы, но для этого нужен программатор. Можно ли использовать в качестве такого программатора Ардуино, чтобы он вопринимался этой программой как надо, и если можно, то как нужно подключить их и какой скетч залить в ардуинку? 
      Саму программу выложу чуть позже, если необходимо - с мобильника сижу. 
      Спасибо 
    • By User_1
      Всем привет!
      Почему-то этот код работает: 
      void Send_to_UART(char* string) { char data = 0; while(*string) { while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); data = *string; USART1->TDR = data; string++; } while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); USART_SendData(USART1, 0x0D); while(!(USART_GetFlagStatus(USART1, USART_FLAG_TXE))); USART_SendData(USART1, 0x0A); while(!(USART_GetFlagStatus(USART1, USART_FLAG_TC))); } char hello[13] = {'H','e','l','l','o',' ','W','o','r','l','d','!'}; int main (void) { Init_Clock(); Init_USART1(); Send_to_UART(hello); while(1); } А если написать вот так:
      int main (void) { Init_Clock(); Init_USART1(); Send_to_UART("Hello World!"); while(1); } то не просто не работает - микроконтролер зависает даже до входа в main().
      В Си ведь, насколько я понимаю, строка - это тот же массив символов
      Объясните, пожалуйста, что я делаю не так?
      Камень stm32f030, среда CooCox CoIDE
  • Сообщения

    • Поэт велик. Стихи крутые. Жаль, что читатели тупые...
    • Очень много сообщений, что не сами все одновременно 900 человек покинули Чемодановку, а принудительно увезли на автобусах.
    • Он же регулируемый от 0 до 30 Вольт как оптапара будет в таких пределах работать. Вам надо два транзистора и теристор. Теристор будет выполнять роль защёлки на 4 ноге tl494
    • Ну что вы, дорогой FonSchtirlitz,
      ПоШто так неуверены в стихах?
      Конечно надо приложить усилие,
      И не ответишь в тему в попыхах. Но всё же описать возможно,
      И суть и графики и формулы,
      Поэтому вперед, сомнению в сторону. Резонансную частоту динамической головки,
      Мы найдем по формуле без всякой уловки:
      И подвижной системы массу успешно,
      Мы перемножим на гибкость подвеса.
      Дальше возьмем из числа того корень
      И перемножим на 2 Пи без горя.
      Ну и вконце, чтоб число получить
      Надо 1 на итог разделить. Кто то возможно и  не поверит,
      но в Википедии можно проверить.
    • Клайд просил передать о снижении ценника на 2 недели до 30 тыс рублей, писать на почту ему klaid1971@inbox.ru
    • Около 900 цыган, проживавших в селах Чемодановка и Лопатки Пензенской области, покинули село после массовой драки с местными жителями, один из участников которой скончался в больнице.