Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: XMEGA - воспроизведение речи с DataFlash
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
prottoss
Все доброго времени суток!

Встала задача воспроизводить (заранее записанную на внешнюю МС памяти с SPI-интерфейсом) речь на МК XMEGA. Оцифровка 16 бит Х 16 кГц Х моно.
Решил воплотить задачу используя DMA. Накидал программку, прогнал в AVRStudio 4 - вроде все работает... Но, блин что то не очень нравится собственное решение. Опишу алгоритм.

1. В качестве последовательного интерфейса для DataFlash используется один из USART в режиме MASTER SPI. Перед началом воспроизведения программно пишется команда чтения со всеми нужными атрибутами.
2. Для чтения сэмпла использую таймер с частотой переполнения 32 кГц.
3. Для инициализации передачи по SPI использую канал DMA (назовем его A). Канал стартует по переполнению таймера в режиме SIngleShort. Т.е. одно переполнение - трансфер одного байта в DATA регистр USART.
В счетчик канала, перед началом воспроизведения, пишется количество байт воспроизводимого файла. В качестве источника данных используется байт в памяти данных, в который записано нулевое значение. Прерывание окончания передачи разрешено.
4. Для передачи байта из регистра DATA USART в регистр данных DAC использую второй канал DMA (Назовем его В). В счетчике данных канала всегда 2, включен режим повтора, счетчик повторов равен 0, т.е. неограниченное число повторов. Адрес источника - регистра DATA USART - фиксированый, Адрес приемника - регистр DATA канала DAC, адрес инкрементируется, обновляется после передачи блока данных (2 байт). Прерывание окончания передачи запрещено.

Прерывания:
1. По переполнению таймера - только для того, чтобы снять флаг прерывания. Если это прерывание не разрешить, то канал DMA А пуляет ноль в USART без остановки! Это и понятно - флаг прерывания по переполнению не обнуляется.

2. Прерывание по окончанию передачи по каналу DMA A - нужно, чтобы разрешить прерывание от последней передачи канала DMA B.

3. Прерывание по окончанию передачи канала DMA B. Останавливает таймер, запрещает работу обеих каналов DMA, вызывает CallBack-функцию, которая генерирует команду чтения следующего файла либо останавливает полностью воспроизведение.

Во всей этой схеме не нравится три прерывания, особенно первое - от таймера. Может есть более изящные способы, чем мой?
Рад любым высказываниям. Спасибо!
bob1
Цитата(prottoss @ Apr 1 2013, 21:45) *
Во всей этой схеме не нравится три прерывания, особенно первое - от таймера. Может есть более изящные способы, чем мой?
Рад любым высказываниям. Спасибо!

Между таймером и DMA воткните канал событий. Переполнение таймера через канал событий будет запускать передачу по DMA.
prottoss
Цитата(bob1 @ Apr 6 2013, 08:13) *
Между таймером и DMA воткните канал событий.
Я думал об этом, но не стал пробовать, потому что не нашел описания поведения канала событий - флаг переполнения таймера сбрасывается только по прерыванию либо вручную. Завтра попробую и отпишусь.
bob1
Цитата(prottoss @ Apr 6 2013, 20:04) *
Я думал об этом, но не стал пробовать, потому что не нашел описания поведения канала событий - флаг переполнения таймера сбрасывается только по прерыванию либо вручную. Завтра попробую и отпишусь.

Использую подобный алгоритм . Работает. Канал событий срабатывает когда счетчик переполняется. На флаг не смотрите...он вроде все время установлен.
prottoss
Цитата(bob1 @ Apr 6 2013, 23:15) *
Использую подобный алгоритм
Сделал. Проверил в AVRStudio - работает. Спасибо за совет. На железе проверю позже.
prottoss
Цитата(prottoss @ Apr 7 2013, 18:23) *
Сделал. Проверил в AVRStudio - работает. Спасибо за совет. На железе проверю позже.
Сегодня проверил на железе - работает. Выводит WAV-файл на динамик. Но, блин, шум фоновый просто страшный.
По схеме - с выхода DAC сигнал подается на транзистор, включенный по схеме ОЭ. В цепи коллектора - 8 Ом динамик последовательно с резистором 330 Ом. Понятно, что необходим ФНЧ, но все же я ожидал более приемлемого звучания. Осциллографа, к сожалению, под рукой не будет все выходные. Может кто нибудь подскажет, в чем может быть проблема? Я задаю вопрос с упором на программную часть и с надеждой на тех, кто уже это проделывал.
bob1
Тут посмотрите.
zombi
Цитата(prottoss @ Apr 26 2013, 16:40) *
шум фоновый просто страшный ... я ожидал более приемлемого звучания.

Удалось добиться приемлемого звука после :

1. замены просто A1 на A1U.
2. не использования регистра TIMCTRL.
3. подключения AVCC через BAT54C ( + электролитик и керамика на AVCC обязательно).
4. опора ЦАПа обязательно AVCC.

Работает 11 разрядов ЦАПа замечательно. Ну и на унч обатить внимание.
prottoss
Цитата(zombi @ Apr 27 2013, 02:43) *
Удалось добиться приемлемого звука после :

1. замены просто A1 на A1U.
2. не использования регистра TIMCTRL.
3. подключения AVCC через BAT54C ( + электролитик и керамика на AVCC обязательно).
4. опора ЦАПа обязательно AVCC.

Работает 11 разрядов ЦАПа замечательно. Ну и на унч обатить внимание.


1. Используется ATXmega64A3U;
2. Таковой в МК отсутствует;
3. Использую AVCC. Питание последовательно через дроссель. Зашунтировано двумя керамическими конденсаторами 2,2 мкФ и 0,1 мкФ. А куда диод приляпать?
4. Используется как раз AVCC в качестве опоры, хотя пробовал другие варианты.

Попробовал выкинуть DMA и пулять данные в прерывании таймера. Поигрался с откидыванием старших разрядов. Ничего не изменилось... Похоже надо ехать за осцилом на работу.

Может быть я не правильно данные готовлю sm.gif ? В качестве данных использую WAV 16 бит, 16 кГц, моно. DAC настраиваю с Left-adjust выравниванием...
adnega
Цитата(prottoss @ Apr 27 2013, 13:46) *
Может быть я не правильно данные готовлю sm.gif ? В качестве данных использую WAV 16 бит, 16 кГц, моно. DAC настраиваю с Left-adjust выравниванием...


Попробуйте типа такого
Код
DAC->DHR12L1 = ((WORD)(wav_data[i] + 0x8000));
prottoss
Померил осциллографом и офигел - сигнал на выходе DAC... прямоугольный blink.gif
Написал обработчик от таймера который делает пилу на выходе - пила есть. Вобщем пока в я шоке sm.gif Ищу косяки в программе.
zombi
Цитата(prottoss @ Apr 27 2013, 12:46) *
2. Таковой в МК отсутствует;

Ну да. Просто я программу для A1 запустил на A1U и хотя этого регистра уже и не стало но запись по этому адресу по прежнему влияет на качество звука.

Цитата(prottoss @ Apr 27 2013, 12:46) *
А куда диод приляпать?

У меня система с батарейкой и на диоде переключается источник.
Пробывал разные фильтры лепить после диода для AVCC.
Ничего не помогало до тех пор пока не поставил ещё одну диодную сборку именно для AVCC.
Т.е. для каждого питания VCC/AVCC свой BAT54.


Цитата(prottoss @ Apr 27 2013, 15:31) *
Ищу косяки в программе.

100%
У меня все звуки 22050Гц 8бит стерео.
Одновременно может звучать 8-мь звуков.
+ возможность цифровой регулировки громкости каждого канала каждого звука.
Таймер формирует событие для ЦАПа и прерывание для программы.
prottoss
Все, решил проблему. Перед загрузкой в ДатаФлэш, переконвертировал все файлы. Т.е. в сегменте данных WAV к каждому значению прибавил 0х8000, как и советовал выше adnega. Все стало петь чисто sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.