Продолжение урока затянулось, оно и понятно, пришлось освоить работу с картами памяти и файловой системой FAT. Но все таки, оно свершилось, урок готов — фактически новогоднее чудо.
Дабы не перегружать статью информацией, я не буду описывать структуру формата wav файла, информации в поисковиках более чем предостаточно. Достаточно сказать, что если открыть файл, каким либо Hex редактором, то в первых 44 байтах содержится вся информация о типе файла, частоте дискретизации, количестве каналов и пр. Если нужно анализировать файл, читайте этот заголовок и будет вам счастье.
Полезные данные начинаются с 44 байта, по сути они содержат уровни напряжений, из которых формируется звук. Мы уже говорили про ступени напряжения, в прошлой части урока. Таким образом, все просто, нужно эти ступеньки вывести на динамик с частотой дискретизации файла.
Как физически заставить динамик дрыгаться? Нужно выводить эти уровни напряжения, при помощи ШИМ, либо использовать R2R. В любом случае, использовать очень просто, прочитал число, засунул его либо в OCR, либо в PORTx. Далее через определенное время, подставил следующее значение и так до конца файла.
Пример, некий wav файл, данные идут с 44=0х2С байта, там записано число 0х80, воспроизводим звук например ШИМом первого таймера, пишем OCR1A=0х80; Допустим, частота дискретизации вавки 8кГц, соответственно прерывание должно быть настроено на эту же частоту. В прерывании, подставляем следующее значение 0x85 через 1/8000=125мкс.
Как настроить прерывание на 8кГц? Вспоминаем, если таймер работает на частоте 250кГц, то регистр сравнения прерывания нужно подставить (250/8)-1=31-1 или 0x1E. С ШИМом тоже все просто, чем выше частота на которой он работает тем лучше.
Чтобы прошивка работала, условимся, что флешка отформатирована в FAT32, используется либа PetitFat из урока 23.2. Файл в формате wav либо 8кГц, либо 22,050кГц, моно. Название файла 1.wav. Анализируем прошивку.
#include <mega8.h> #include "diskio.h" #include "pff.h" unsigned char buffer[512]; /* буфер в который копируется инфа с флешки */ volatile unsigned int count; //счетчик скопированных данных interrupt [TIM2_COMP] void timer2_comp_isr(void) //прерывание в котором подставляются значения { OCR1A = buffer[count]; //выводим звук на динамик if (++count >= 512) //увеличиваем счетчик count = 0; //если 512 обнуляем } void main(void) { unsigned int br; /* счетчик чтения/записи файла */ unsigned char buf = 0; //переменная определяющая какая часть буфера читается FATFS fs; /* Рабочая область (file system object) для логических дисков */ PORTB=0x00; DDRB=0x02; //дрыгаем шимом ocr1a // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 8000,000 kHz // Mode: Fast PWM top=0x00FF // OC1A output: Non-Inv. TCCR1A=0x81; TCCR1B=0x09; TCNT1=0x00; OCR1A=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: 250,000 kHz // Mode: CTC top=OCR2 TCCR2=0x0B; TCNT2=0x00; //OCR2=0x1E; //настройка регистра сравнения для 8кГц OCR2=0xA; //для 22кГц #asm("sei") // Timer(s)/Counter(s) Interrupt(s) initialization if(disk_initialize()==0) //инициализируем флешку { pf_mount(&fs); //монтируем файловую систему pf_open("1.wav"); //открываем вавку pf_lseek(44); //перемещаем указатель на 44 pf_read(buffer, 512,&br); //в первый раз заглатываем сразу 512байт TIMSK=0x80; //врубаем музон while(1) { if(!buf && count>255) //если воспроизвелось больше 255 байт, { pf_read(&buffer[0], 256,&br);//то читаем в первую половину буфера инфу с флешки buf=1; if (br < 256) //если буфер не содержит 256 значений значит конец файла break; } if(buf && count<256) { pf_read(&buffer[256], 256,&br); // читаем во вторую часть буфера с флешки buf = 0; if (br < 256) break; } } TIMSK = 0x00; //глушим все pf_mount(0x00); //демонтируем фат } while (1) { } } |
Для проверки, на ножку OCR1A подключаем динамик через конденсатор 100мкФ, «+» на ножку микроконтроллера, «-» на динамик. «-» динамика на землю, «+» на конденсатор.
Не ждите громкого сигнала на выходе, чтобы звучало громко, необходим усилитель. На видео это хорошо видно. Для теста залил петуха 8кГц и трек 22кГц.
Желающие могут смело увеличить частоту таймера2, чтобы проигрывать файлы 44кГц, опыты показывают, что можно добиться вполне неплохого качества звучания. На видео звук слабый и качество плохое, но на самом деле это из-за того, что снимал на фотоаппарат.
Также выкладываю материалы любезно предоставленные Аппаратчиком — исходник для GCC, с которого была написана прошивка под CAVR.
И видео с воспроизведением 44кГц.
Пользуясь случаем поздравляю Всех с Наступающим, желаю чтобы все прошивки и девайсы у вас работали 🙂
Проект wav плеера на Atmega8
Какой-то фоновый ВЧ шум идет..
sprintf(buf[], «%c.wav», hour) — можно ли сделать проще, т.к. эта функция много памяти ест ?
Не могу понять. Заливаю wav_player.hex в МК. Фьзы настроены на внутренний генератор на 8МГц. Запускаю на макетке от 3.3В. Контакты CS, DI, CLK от карты памяти подтянул через резисторы по 10 кОм на +3.3В. Вывел контакты кнопки запуска плеера. И ничего не работает. В чём может быть проблема? Может кто-нибудь в paint’e или SprintLayOut’e нарисовать схему развода всех контактов?
зачем подтягивать резисторами?
Тут Юрий писал: как только поставил резисторы подтяжки с +3.3в по 10кОм на линии CS, DI, CLK так всё и заработало! А МК и MIcroSD питаются от 3.3В вместе?
А кондер обязателено на динамик ставить? Он электролитический, как я понимаю?
Кондер ставить обязательно, по поводу подтяжки — почитайте про то, как работает spi, тогда поймете нужна ли там подтяжка или нет.
Чтобы запустить плеер нужно PIND.0 замкнуть с землей?
Я правильно понимаю распиновку адаптера MicroSD ?
Я правильно понимаю распиновку адаптера MicroSD ?
нет, не правильно http://avr-start.ru/?p=1781
Спасибо! Но всёровно не работает. Вот так у меня соединяются контакты на макетке: Где может быть ошибка?
у Вас gnd 21 не подсоединен
Подсоеденил 21. Все также. MicroSD на 2 Гб. Это ж норм флешка будет?
Попробуйте другую, проверьте что отформатировано в FAT32
Размер кластера какой желательно выставить?
Предпочтительнее какой размер кластера выставлять при форматировании флешки? Или это не имеет значения?
стандартный
Для чтения и вывода текста так же буде? Спасибо.
Да
Нигде не могу найти структуру текстового файла, например *txt.
у txt нет структуры, что запишешь то и будет. естественно нужно учитывать кодировку
Здравствуйте.
Залил прошивку для wav плеера, которая в конце статьи, в ATMEGA8-16PU.
Фьюзы выставлены на int RC 8 MHz + 4 мс, питается схема от стабилизатора 1117 на 3.3 вольта. При подаче питания происходит прерывающийся 2 раза в секунду звук как из севшей китайской игрушки (очень тихий зацикленный скрежет, точно не сигнал). Без флешки молчит. Если флешку при этом звуке отключить (при этом контроллер замолкает), а потом подключить снова, то на долю секунды слышно цифровой сигнал обмена информацией (тихое шипение) и опять звук. Причем если нажать на кнопку Play, звук прекращается, ещё раз нажать, появляется снова. На кнопки BACK и FRW реакции нет. С прошивкой воспроизводящей «1.wav» проблем не было.
Пробовал скопировать настройки таймера с первого кода, результат тот же.
Не подскажете в чем может быть проблема?
файлы называются 01.wav, 02.wav…?
а что насчет драйвера динамика? можно схему?
динамик подключен напрямую, через кондер 100мкФ
Добрый день, а можно ли сделать, чтобы считывалось изображение с карты и представить его в виде сигнала ?
Спасибо, статья супер, помогла разобраться))))) Все заработало с пол дрыка)
Доброго времени суток! Случился затык, помогите пожалуйста.
Скачал проект в архиве BonPetit.7z и запустил файл протеуса. Моделирую. Что должно заиграть? У меня слышен импульсный сигнал. Пробовал смонтировать образ флешки через программу WinImage, FAT32,заливал файлик «1.wav» и ничего существенного не менялось.
Вавку готовил по уроку22.1. Флешку в самом проекте дёргать пробовал, тоже никакой реакции. В чём может быть дело?
в протеусе не работает, там нет поддержки sd карт памяти
Доброго времени суток. Подскажите пожалуйста как переназначить подключение SD. Я меняю значение вывода в — SD_CS
// Definitions for MMC/SDC connection
#define SD_DI 3
#define SD_DO 4
#define SD_CLK 5
#define SD_CS 2
//#define SD_INS 6
//#define SD_WP 7
если меняю например на ноль то ничего не работает. Делаю стерео и надо выход OC1B,
а он занят. За ранее спасибо)
Должно работать.
Здравствуйте. Выполнил схему на макетной плате.
Сразу после прошивки появляется писк. Флешка в этот момент не подключена.
Флешку(2 Гб) отформатировал в FAT32 со стандартным размером кластера, wav приготовил через аимп-конвертер(кажется тут может быть грешок, попробую ещё через другую программу) (8кГц, 8бит,моно).Вставляю флешку, подаю питание, МК определяет ее, но писк по-прежнему остаётся и через секунду становится громче, а через некоторое время снова тише (я так понимаю что-то проиграл и затих).
Дальше уже просто алхимичил, снова эту же вавку переформатировал по тем же параметрам, получилась ускоренная какофония, шум. Засунул в МК, и как не удивительно, динамик начал выдавать похожие звуки шума вместо писка.
Питание 3 вольта сделал на LD1085V33, работает как часы. МК — ATmega8A-PU.
Внешний тактовый генератор 8МГц. Правда, нужно с фьюзами разобраться, не проверял и не трогал. Это может играть роль?
Прилепил светодиод для проверки подключения флешки и добавил код в этом месте:
if(disk_initialize()==0) //инициализируем флешку
{
PORTD = 0b00000010;
DDRD = 0b00000010;
pf_mount(&fs); //монтируем файловую систему
Динамик взял 2ГДШ-9 (8Ом).
Неиспользуемые ноги флешки нужно на землю пускать или это неважно?
Еще заметил разногласия в схемах. На сайте динамик подключен через 100u, а в протеусе 100p.
Почему может писк без подключения флешки появляться?
Всё, разобрался. Нужно было прошить фьюзы на внешний кварц 8МГц. Спасибо!
для атмеги в работе с флешками/SD категорически не нужна файловая система. всё пишется побитно-монолитно)) а ищется смещением от начала, это короче имени файла
экономятся и ресурсы и память
ФС используют когда встаёт проблема места, ну и фрагментации при многократных записал-стёр и, собстно совместимости)
Подскажите сколько файлов можно проиграть одновременно на разных ногах микроконтроллера? Отчего зависит количество?
К примеру Atmega328p потянет пять каналов?
много от чего зависит, главным ограничителем будет оперативная память
Тоже долго мучился…
В итоге: Программная часть работоспособна, проблемы были в неправильном подключении… Всем у кого не работает, проверьте ВСЕ подключения, от начала до конца!!!
Автору ОГРОМНОЕ СПАСИБО!!!!
И вопрос, можно ли реализовать регулировку громкости?
можно
Подскажите принцип регулировки громкости
ставите переменный резистор, 1 контакт на выход ножки, 3 на землю, со среднего снимаете свой сигнал