Запись данных через PIN-код с определенной частотой
У меня есть Arduino UNO, подключенная к плате KLZ25, Arduino отправляет тактовый сигнал 1 МГц на контакт 9, и теперь я должен записать PDM-данные с частотой 1 МГц на контакте 8. Но я не знаю, как записать с такой скоростью, потому что если я пишу в Цикле:
loop{
digitalWrite(1);
digitalWrite(0);
}
Я получаю только частоту 36Khz, я знаю, что это зависит от количества команд в цикле, но я не знаю, как написать с определенной частотой в моем случае 1Mhz.
Я получаю данные PDM (импульсно-плотностная модуляция) в форме 1 и 0 из скрипта Python на хост-ПК, и теперь я хочу передать данные с частотой 1 МГц на другую плату разработчика, которая выполняет дальнейшие расчеты с помощью PDM-данные. Я храню PDM-данные в очередях, потому что у меня недостаточно памяти для хранения всех данных.
Кто-нибудь знает, как записать PDM-данные с частотой 1 МГц на выходной контакт?
@FoldFence, 👍0
Обсуждение1 ответ
Лучший ответ:
Если я правильно понимаю, вы хотите вывести синхронный последовательный бит поток на частоте 1 МГц. Что-то вроде этого:
___ ___ ___ __/ \___/ \___/ \___⋅⋅⋅ ____ _______ _______ ___ дата __D0__X___D1__X___D2__X___⋅⋅⋅
где биты данных поступают с ПК.
Если вы хотите, чтобы это был непрерывный битовый поток, будет непросто генерировать на Arduino Uno.
Получение данных
Поскольку данные поступают с ПК, предположительно они поступают через последовательный порт. связь. Вы должны учитывать тот факт, что эта ссылка добавляет стартовый бит и стоповый бит для каждого байта. Таким образом, у вас есть 10 бит на проводе за каждые 8 бит фактических данных. Поскольку вы должны поддерживать 1 Мбит/с в среднем фактических данных, это означает, что вы должны настроить последовательный порт на скорости не менее 1,25 Мбит/с. Однако единственная скорость передачи выше, чем 1 Мбит/с, поддерживаемая Arduino Uno, составляет 2 Мбит/с.
Поддерживает ли ваш компьютер эту скорость передачи данных? Надежна ли связь в эта скорость?
Если скорость слишком высока, я бы посоветовал вам попробовать отправить данные как PCM на более низкой скорости, и пусть Arduino обрабатывает Преобразование PCM → PDM.
Передача данных
Этот формат данных очень похож на передачу SPI. Затем СПИ. аппаратный порт кажется самым простым способом его создания. Однако Передатчик SPI на Uno не имеет двойную буферизацию. Это означает, что вы необходимо дождаться завершения передачи текущего байта, прежде чем предоставление следующего байта аппаратному обеспечению SPI. Это, в свою очередь, означает, что вы неизбежно будут небольшие задержки между последовательными байтами, и один выход из каждых 8 тактов будет растягиваться сверх ожидаемого 1 мкс. Если эта неустойчивость приемлема для вашего приложения, то используйте передатчик SPI. Если нет, то придется искать другого решение.
Последовательный порт Uno работает в особом режиме. ведет себя как основной порт SPI. В отличие от фактического порта SPI, этот порт с двойной буферизацией, что позволяет отправлять непрерывный битовый поток со стабильными часами. Проблема в том, что вы не можете использовать этот режим для передачи и в то же время использовать приемник последовательного порта в его обычный асинхронный режим. Таким образом, вы не сможете получить данные с ПК при использовании этого режима. Если вам удастся направить Связь ПК→ Arduino через SPI, этот режим работы последовательного порта может быть хорошим выбором.
Если ни один из вышеперечисленных вариантов вам не подходит, я предлагаю, в крайнем случае, генерировать битовый поток полностью с помощью программного обеспечения. Сроки сжатые, т.к. каждый уровень тактового сигнала должен поддерживаться только в течение 8 циклов процессора. Но это, вероятно, выполнимо в рукописном ассемблере, при условии, что прерывания отключены. Вот примерно как я могу попытаться это сделать:
___ ___ ___
clk __/ \___/ \___/ \___⋅⋅⋅
______ _______ _______ ___
dat __D0__X___D1__X___D2__X___⋅⋅⋅
Приведенный выше код предполагает, что UART синхронизирован с выходным потоком. что, скорее всего, не будет иметь место в реальности. Ваше реальное приложение может тогда будьте более сложными, и вам придется сделать эту дополнительную сложность помещаются в слоты задержки выше.
Обратите внимание, что если вы выполняете преобразование PCM → PDM на Arduino полученный код может оказаться проще, так как вы сможете читать UART на каждой итерации цикла, не беспокоясь о синхронизация. Я написал программу, которая делает что-то очень подобное некоторое время назад, и я только что отправил его на GitHub, чтобы вы могли посмотрите: avr-dac: превратите AVR в 1-битный цифро-аналоговый преобразователь. Примечание что эта программа предназначена для использования на AVR без аппаратного UART. Ожидается, что данные PCM будут передаваться в виде сдвигового регистра. Использование UART упростило бы программу.
- Максимальная частота цифрового сигнала в Arduino Uno?
- Как подключить ардуино к разъему для наушников?
- Как использовать звуковой датчик LM393 + динамик в Arduino
- Генерировать 1,7 МГц с PWM в Uno?
- Можно ли сгенерировать точный тактовый импульс 15 кГц с помощью ардуино?
- Изменение частоты вывода ШИМ на Arduino Uno
- Распознавание звука
- Статус выхода 1 ошибка компиляции для платы arduino/genuino uno при использовании кода тона
Что означает аббревиатура ДПМ? Было бы полезно указать это в вашем вопросе., @MichaelT
Используйте один из таймеров на UNO. Это те, которые используются для PWM. Установите прескалер на /8. Установите режим на быстрый ШИМ. Установите выходной контакт в режим без инвертирования. Установите OCxA/OCxB на 2 (поскольку таймер работает на частоте 2 МГц). Затем измените значение TOP на основе значения PDM, которое вы хотите отправить., @Gerben
PDM означает модуляцию плотности импульсов, в основном я пишу 1 или 0 с частотой 1 МГц. @Gerben Что вы подразумеваете под ТОП значением? Изменяет ли изменение таймера также скорость цикла, потому что я не понимаю, как писать в 1 МГц, если цикл медленнее., @FoldFence
DigitalWrite сама по себе очень медленная. Это занимает много циклов. Сам
loop
также требует несколько циклов для вызова. Вместо этого вы можете использовать прямое управление портом, что намного быстрее. Но для работы на частоте 1 МГц у вас есть только 16 циклов для переключения вывода и запуска цикла, и у вас почти не остается времени на что-либо еще. Также могут возникать другие прерывания, которые замедляют вашу петлю через «случайные» интервалы, давая вам нестабильный сигнал 1 МГц. Вот почему я предлагаю использовать таймеры, так как они работают параллельно., @GerbenТаймер, например, используется для ШИМ светодиода. Этот таймер работает параллельно вашему коду. Таймер имеет счетчик, который увеличивается каждый такт. Вы можете выбрать значение TOP, чтобы при достижении этого значения счетчик сбрасывался на ноль. Он также имеет регистры сравнения. Вы можете указать таймеру, что, как только счетчик достигнет значения в регистре сравнения, он должен установить один из выходных контактов в НИЗКИЙ уровень. Вы также можете настроить его на установку ВЫСОКОГО уровня на выходной контакт, когда он снова установлен на ноль. Таким образом, комбинируя это, выход будет ВЫСОКИМ в течение 1 мкс, а затем НИЗКИМ на несколько мкс, в зависимости от значения TOP., @Gerben
Вы также можете эмулировать желаемое поведение с помощью одного из интерфейсов atmegas (например, мастер SPI). Суть того, что упомянул Гербен, заключается в том, что вы должны использовать доступное оборудование, потому что, как вы уже выяснили, обработка этого материала в
loop()
не будет работать на частоте 1 МГц., @Sim Son16 циклов процессора — это _очень короткое время_. Вы не сможете сделать ничего, кроме алгоритма дельта-сигма для генерации выходных данных PDM. Некоторое время назад я написал программу, которая делает почти то, о чем вы просите. Он считывает данные в режиме «сдвигового регистра» и выводит их в виде PDM с частотой 615 кГц при частоте ЦП, работающей на частоте 8 МГц. Это 13 циклов ЦП на цикл PDM. Он предназначен для работы на ATtiny13A и должен быть легко адаптирован к Uno. Он основан на точно синхронизированном цикле сборки без прерываний. Скажите, если вы заинтересованы в том, чтобы я его опубликовал., @Edgar Bonet
А, хорошо понял, спасибо за ответы! @EdgarBonet, было бы неплохо, если бы вы опубликовали это. Я не знаю, будет ли решение SPI работать с платой frdm-klz25, но я попытаюсь использовать решение для прерывания по таймеру, и если это не подходит, я попробую, спасибо! И я не должен выполнять сигма-дельта-модуляцию, я сделал это на питоне на хост-компьютере и использую Arduino для отправки данных на KLZ25, в основном Arduino и хост-компьютер вместе имитируют микрофон и на KLZ25 Я проведу расчет MFCC после того, как передам данные PDM с ПК на Arduino., @FoldFence