![](images/chestnut/misc/left.gif) |
Микроэлектроника Программирование под Arduino, AVR и другие МК. Вопросы конструирования. |
01.02.2017, 03:01
|
#1
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
MCP4725: максимальный сэмплрейт
Какой максимальной реальной скорости можно достичь при использовании этого цифро-аналогового преобразователя?
Реально ли вывести одноканальный звук 12bit/44100Hz?
В даташите сказано, что чип поддерживает работу через I2C на скорости 3.4Mbps. AVR столько не осилит. Даже если к нему припаять резонатор на 25MHz. Я почти не работал с I2C, и когда работал, использовал чужую библиотеку, поэтому не особо представляю какие там накладные расходы на передачу (протокол посложнее, чем UART или SPI). Если у чипа заявлена поддержка скорости 3.4Mbps, то заработает ли он на меньшей скорости, например, 800kbps?
Зачем все эти извращения? Если этот ЦАП даст звук лучше, чем даёт 8-битный ШИМ в AVR, то я считаю стоит попробовать. Настоящие звуковые ЦАПы стоят чо-то сильно много. Может кто-то посоветует недорогой звуковой ЦАП? Мне достаточно одноканального, обязательно, чтобы поддерживал 16-битный режим, потому что затолкнуть 24 бита с AVR будет тяжело.
|
(Offline)
|
|
01.02.2017, 05:12
|
#2
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
Провёл предварительные эксперименты. Получается отсылать почти 40 тысяч сэмплов в секунду на максимальной скорости I2C (регистр TWBR = 1), какую только позволяет ATmega328 со стандартным резонатором на 16MHz. Если перепаять резонатор на 20MHz (в общем-то у меня уже есть одна ардуина с перепаянным, специально заказывал в таком же формфакторе резонаторы с алиэкспресса), то без переделывания кода получится отправить почти 50 килосэмплов, что как раз перекрывает потребности в 44100. Но я думаю, что можно выжать ещё немного скорости, оптимизировав библиотеку для работы с I2C. Кроме того неплохо бы её переделать на работу в неблокирующем режиме, иначе отправлять-то на вывод данные я смогу, но их же ещё надо успевать откуда-то брать (с micro SD карты, например).
Что касается работы чипа MCP4725, то я точно вижу, что на выходе напряжение меняется, но пока не оценивал достаточно ли быстро согласно входным данным, чтобы можно было воспроизводить звук. Жаль нет ружья осциллографа. Опять придётся выдумывать какие-то убер костыли. ![Laught](images/smilies/DDD.gif)
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо Phantom за это полезное сообщение:
|
|
01.02.2017, 20:18
|
#3
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
Если кто-то будет пытаться повторять мои эксперименты, то оставляю ещё ссылку на другой мой пост, касающийся воспроизведения звука с AVR.
|
(Offline)
|
|
02.02.2017, 18:10
|
#4
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
В общем, совсем чутка не хватает скорости для отправки 44100 сэмплов в секунду. Пришлось взять Ардуино с 20 МГц резонатором. И приключилась другая странная проблема. После записи в регистр TWBR единицы (максимальная скорость I2C), I2C перестаёт работать. Стартовый бит отправляет, получаю подтверждение, но на последующие операции записи возвращает 0x00, константа и её описание вот:
#define TW_BUS_ERROR 0x00 illegal start or stop condition
На 16 МГц отлично работало с единицей в TWBR. Так и не удалось разобраться с этой проблемой. Если кто-то работал с TWI (I2C) и разбирается во всех нюансах, ваш опыт был бы полезен. Пришлось увеличить TWBR до значения 2. Судя по моим подсчётам, таким образом частота I2C получилась 1 МГц (при 16 МГц / TWBR = 1 было 0.888 МГц), так что по идее должно как раз хватить для отправки 44100 сэмплов. Нужно ещё экспериментировать.
|
(Offline)
|
|
02.02.2017, 21:22
|
#5
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
Разобрался, почему не работал высокоскоростной I2C. Нужно было активировать режим High Speed. Судя по всему на частотах I2C до 1МГц чип MCP4725 работает и в обычном режиме без проблем, но если увеличивать частоту выше, то нужно переводить его в режим High Speed. В общем-то всё логично, потому что обычная частота для I2C - это 0.4МГц и чип вообще не обязан был работать на более высокой частоте без перевода в High Speed. Для полноты упомяну, что High Speed в контексте I2C - это 3.4МГц.
Теперь у меня проблема в том, что на вызов прерывания по завершению записи каждого байта уходит слишком много тактов и я всё равно не вписываюсь в нужные рамки. Без прерываний реализовать что-то вменяемое будет тяжело, поэтому буду экспериментировать дальше. Возможно вместо прерывания TWI буду использовать прерывание по совпадению таймера. Но это будет работать только если чип MCP4725 стабильно отвечает на операцию записи по фиксированным таймингам.
|
(Offline)
|
|
04.02.2017, 07:09
|
#6
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
Я смог воспроизвести звук с частотой дискретизации 32000 герц. Думаю, получилось бы и больше (желанные 44100), да вот незадача, когда на ардуине стоит резонатор на 20МГц, то микросхема UART отказывается нормально работать на необходимой скорости (нужно передавать на скорости не менее samplerate * 2 * 10 бод). Подключать внешний UART адаптер на другой микухе было влом, ваять воспроизведение музыки с флешки тоже, поэтому я решил экспериментировать на обычной ардуине на 16МГц.
Сделал скрипт на node.js, которому на вход даю любой аудиофайл, скрипт его конвертирует через ffmpeg в raw файл (просто бинарник с сэмплами, почти как WAV, только без заголовков), после этого обнуляет последние четыре бита каждого сэмпла, снова при помощи ffmpeg конвертирует в файл WAV, чтобы можно было послушать результат на компе (WAV не поддерживает 12-битный звук, таким образом я его эмулирую).
Далее скрипт переходит к воспроизведению через UART. Пригодилась библиотека nanotimer, позволяющая создавать таймауты с точными таймингами. Буфер с сэмплами пакуется в придуманный на скорую руку формат, а именно: сэмпл отправляется двумя последовательными байтами, старшие шесть битов сэмпла в первом байте, а младшие шесть битов во втором. У первого байта старшие два бита всегда устанавливаются в 10, а у второго в 00. Вот так:
[1 0 H H H H H H] [0 0 L L L L L L]
Для чего это нужно: чтобы ардуина могла синхронизовать данные по приёму и отличить старший байт от младшего. Представьте, что вы выключили скрипт на компе, когда в UART улетел старший байт. А потом вы снова запускаете скрипт и опять первым летит старший байт. Ардуина во внутреннем буфере собъётся и начнёт воспроизводить исковерканные сэмплы. Никому не пожелаю этого услышать. Особенно внезапно, когда колонки стоят на большой громкости и подвоха не ждёшь. В общем теперь ардуина по старшему биту каждого байта может понимать его предназначение.
Да будет звук
На компе полученный файл через плеер звучит прилично. Несмотря на пониженные сэмплрейт и разрядность, слышны высокие частоты, таких шумов как при воспроизведении восьмибитного звука нет. Но это эталон, на который мне нужно равняться. А что же там с моей убийцей реалтека? Всё плохо. Звук говно. Есть шумы, и это не похоже на помехи. Кроме того, высоких частот не слышно совсем, звук глухой. Когда после этого запускаю эту же самую песню на компе, кажется, что я только что вылез из воды и слышал всё до этого со дна бассейна. Судя по всему чип MCP4725 не успевает так быстро менять напряжение на своём выходе, это всё объясняет. А ведь это даже не 44100 герц было.
Пойду и дальше воспроизводить 16-битный звук при помощи двух ШИМ выходов AVR. Несмотря на требуемую настройку по согласованию выходов, результат получается шикарным. А этот кусок говна можно использовать только для... А хрен его знает, даже на ум не приходит. Разве только синус на 50 герц генерировать.
Если кто-то добьётся лучших результатов (мало ли, вдруг я что-то делаю не так), милости прошу в тему, обсудим.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Phantom за это полезное сообщение:
|
|
04.02.2017, 16:50
|
#7
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: MCP4725: максимальный сэмплрейт
Звук не выводил никогда через мк, а вот функциональный генератор делал. И для него специально делал простейший ЦАП в виде цепочки резисторов. 8 бит вполне хватало чтобы на нормальной частоте аппроксимировать синусоиду. Наверно все же стоило взять внешний ЦАП.
__________________
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 06:43.
|