Скорость выборки I2C

У меня возникают проблемы при попытке попробовать подчиненные устройства I2C с помощью микроконтроллера dsPIC33f.

Я использую внутренний таймер timer1 PIC, чтобы "тикать" с определенной частотой дискретизации и получать необходимые данные. К сожалению, результаты не достигаются достаточно быстро, и я не уверен, почему. Одним из моих ведомых устройств является акселерометр ADXL345, который имеет максимальную скорость передачи данных 3600 Гц. Мне не нужно почти такое высокое значение, но я, похоже, не могу успешно сэмплировать где-то выше 50 Гц.

I2C настроен на "быстрый режим" 400 кГц. Абсолютный максимум, на котором я хотел бы попробовать акселерометр, составляет 1 кГц, хотя это было бы излишним, меня больше интересует частота около 128 Гц. Параметры для акселерометра, который я установил:

  • Формат данных (0x31) - самопроверка отключена, прерывание инвертировано, полное разрешение включено, бит выравнивания выключен, бит диапазона +/-16g.
  • Скорость передачи данных (0x2C) - режим пониженного энергопотребления выключен (нормальный режим), режим скорости передачи данных 400 Гц (я прочитал в спецификации, что 400 кГц I2C будет поддерживать только до 800 Гц, поэтому я безопасен с 400 Гц).
  • Управление питанием (0x2D) - автоматическое отключение, режим измерения включен, бит ожидания выключен, частота дискретизации в режиме ожидания 8 Гц (хотя не используется, поэтому может игнорироваться).
  • Прерывания (0x2E) - прерывание готовности к данным включено, все остальное отключено.

Я использую таймер1 для выборки с указанной частотой дискретизации, я знаю, что частота дискретизации работает достаточно, поскольку у меня есть счетчик, который выводит сообщение после того, как счетчик достигнет одной минуты; Я использую секундомер, чтобы убедиться, что это правильно. Например, при частоте дискретизации 100 Гц я жду, пока счетчик не подсчитает до 6000 (100 * 60), и покажу сообщение, если секундомер находится на 1 минуте, когда я вижу это сообщение, я знаю, что это выборка, по крайней мере, с некоторой точностью.

Когда я пытаюсь выполнить сэмплирование только с акселерометра (режим многобайтового чтения I2C, считывание всех шести байтов за один вызов), он работает недостаточно быстро. Используя мой метод секундомера, кажется, что для выполнения работы, которая должна занимать одну минуту (сэмплирование при 100 Гц), требуется около минуты и 15 секунд, то есть она недостаточно быстро обрабатывает команду I2C. Более высокая частота дискретизации увеличивает задержку.

У меня такое чувство, что это связано с тем, что часы I2C и таймер1 не синхронизированы, и поэтому в моем вызове для получения данных акселерометра возникает ненужное ожидание. Я не могу представить, что частоты 400 кГц для I2C недостаточно, но, пожалуйста, поправьте меня, если я ошибаюсь.

Как правильно читать данные с ведомых устройств I2C? У меня также есть гироскоп и магнитометр, которые я хочу читать с достаточно высокой частотой дискретизации, магнитометр имеет предел 160 Гц, так что, как я уже сказал, частота дискретизации 128 Гц подойдет для всех трех устройств. Попытка считывания сразу со всех трех устройств, очевидно, увеличивает скорость дискретизации, чем ожидалось.

Я также буду собирать аналоговые данные с 4 контактов одновременно (АЦП 10 бит). Этот код уже реализован, и я могу читать аналоговые данные с частотой 1 кГц с частотой дискретизации, работающей, как и ожидалось, только устройства I2C работают медленно!

Я ожидаю, что акселерометр будет в порядке при попытке дискретизации на частоте 100 Гц, когда я могу вывести на частоте 3600 Гц (макс. 800 Гц для I2C), но это действительно сложно, и я не знаю, что еще можно попробовать.

Ура!

1 ответ

Решение

ОК, это может быть много вещей:

  • Самое простое объяснение в вашем случае - неверная конфигурация сома с тем таймером, который вы используете для запуска опросов. Мне нужно знать, как вы используете это, запускает ли оно прерывание, когда вы устанавливаете флаг для запуска опроса акселерометра? Вы опрашиваете таймер вручную, чтобы вызвать опрос акселерометра. В любом случае, переключение выходного вывода на высокий и низкий уровень, когда это происходит, и просмотр его с помощью осциллографа даст вам ценную информацию. Все ли периоды голосования длиннее, или есть только некоторые из них, которые принимают намного больше, чем ожидалось?

  • Один из тех, что я видел чаще всего, - это медленные процедуры обработки I2C. Ваш I2C может быть настроен на 400 кГц, и это действительно скорость чтения и записи битов байта, но между байтами существует некоторое время обработки, которое очень сильно зависит от сложности вашего кода. В вашем случае, так как вы используете режим многобайтового чтения, это время фактически не между байтами, а между циклами опроса. Но странно, что это будет вашей проблемой, это не такой частый опрос или чтение больших данных.

  • Что бы я сделал в вашем случае (имея какое-то измерительное оборудование, которое у вас, кажется, есть), чтобы убедиться, что все время соответствует вашим ожиданиям. Не предполагайте ничего, измерьте это и убедитесь, что он делает то, что вы ожидаете. В связи с этим я бы начал с самых простых вещей. Часы работают на частоте 400 кГц? Шесть байтов читаются без задержек между ними? Есть ли ожидаемые промежутки между опросами? Застревает ли шина I2C (низкий уровень SDA и / или SCL в течение длительного периода времени) между опросами? Есть ли какие-либо неожиданные сообщения или активность на шине, кроме тех, которые с акселерометром? Вот некоторые из вещей, которые я бы проверил, чтобы понять, что может пойти не так. Золотое правило здесь: не спекулируйте, измерьте его!

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

Попробуйте это, и дайте мне знать, если это помогло.

Ура и удачи!

Другие вопросы по тегам