PIC16F1503. Тачка на прокачку — 1. Звук
Думаю, у каждого родителя бывает такой момент, когда он в магазине на кассе обнаруживает ребенка с нечто, и ребенок утверждает что именно это нечто очень важно для всего мира на земле и для него в частности. Вот и у меня такое случилось в очередной раз. С ходу оценив стоимость этого нечта, родительская жаба махнула рукой и решила, что один раз живем и все равно всех денег не заработать. Разум же оценил скорость умирания этого нечта и тоже дал добро.В результате детский автопарк пополнился вот таким вот чудом китайской инженерии. Джип, с «люстрой» и лебедкой!
Чудо умело мигать «люстрой» и «фарами» и громко производить три записанных звука. Согласно всем канонам, машинка довольно быстро «умерла» и была принесена в ремонт. Я же машину в ремонт брать отказывался, мотивируя отказ невымытыми руками и недоеденным ужином. Плюс китайцы как-то смогли выжать из этой машинки пару лишних децибел на частоте, резонирующей с моим черепом (аж зубы заныли), поэтому мне совсем не улыбалось повторно испытать те же самые ощущения.
В результате долгих переговоров было решено, что простая смена батареек — это уже не модно. Ведь все настоящие водители тюнят свои машины в специальных студиях, после чего ездят на машинах, которых ни у кого нет. Вот и я взял машину в студию «Всё Моё» для тюнинга…Что первым делом необходимо сделать? Правильно, оценить, какой объем работ свалился на нас. Разбираем машину.
Внутри три светодиода (синих, ярких, дешевых), пищалка и неизвестный безкорпусный микроконтроллер класса «китайская сопля». Все это питается от 3х батареек LR4 (емкость в районе 20 мАч), поэтому не удивительно, что машина так быстро умерла. Все это великолепие запускается кнопкой, которая в лучших традициях китайского автопрома заедает и закусывает.
В общем, тут надо менять все. Ну или почти все. На что?
Конечно, я был бы не против воткнуть внутрь машинки STM32F4, но оценочная плата внутрь не залезет, а разводить под это печатную плату откровенно лень. Порывшись в ящиках, обнаружил демоплату на PIC16F1503. До 16 мегагерц, 3 килобайта флеша и аж 128 байт памяти. Самое оно для машинки!
Если вы пожелаете повторить мои упражнения, то искать надо по словам PIC-H1503 (это сам микроконтроллер) и PIC-KIT3 (это программатор) от Olimex. Так же будет необходимо скачать и установить MPLAB X Ide и XC8 с сайта microlab. В отличии ОТ, поддерживаются Windows, Linux и OS X.
С чего необходимо начать тюнинг? Правильно, начнем как все, с звука. Громче нам не надо, нам надо что бы пиликало «по-полицейски» и не громко.
Достаем из машинки «пищалку» и пытаемся понять, что это такое. Не найдя никаких опознавательных знаков, цепляем к омметру. Омметр показывает 15Ом. Значит, микродинамик: если бы омметр показал «обрыв», то это пьезопищалка.
Подключать динамик напрямую к ножке микропроцессора бессмысленно (15 ом на 3 вольтах дадут ток в 200 мА, что явно не понравится микроконтроллеру, которому 20 за глаза), поэтому делаем простую схему на первом попавшемся NPN транзисторе.
Номиналы практически не важны. Плюс-минус от схемы не принесет практически никаких изменений. Зачем конденсатор на схеме, я объясню позже (его в принципе можно воткнуть и параллельно транзистору). Вход подключаем к 9й ножке микроконтроллера.
Теперь осталось понять, как нам извлечь звук. Из школьного курса физики мы знаем, что звук — это колебания воздуха. А динамик переводит колебания электричества в колебания воздуха. Значит нам надо поколебать динамик. Но динамик у нас подключен напрямую к микроконтроллеру, а тот умеет выдавать только »1» (есть на ножке) и »0» (ничего нет). Да, даже (даже? да это редкость) у этого микроконтроллера есть аж 5ти битный ЦАП (аудиофилы тащатся от однобитных, если что. смаил), но это не спортивно.
Спасает нас опять физика: даже если подать »1» на динамик, магнит не мгновенно подтянет диффузор, как и после »0» он его отпустит не мгновенно.
Самое простое это написать код вроде такого
while (1) { dinamikON (); pause (1); dinamikOFF (); pause (1); } Если паузы считаются в миллисекундах, то в динамике мы получим «писк» в 500Гц. И меняя длительность пауз можно получить вполне себе приличный звук. В чем проблема? Проблема в том, что нам нужно будет постоянно отвлекаться на «ножкодрыганье».
Но в любом приличном микроконтроллере есть такая штука, как PWM, он же ШИМ (что это? легко ищется в той же википедии, с картинками и долгими объяснениями). Есть она и в пике. Открываем MPLAB, создаем новый проект и с помощью Code Configurator (Менюшка Tools-Embedded. Может потребоваться сначала поставить в Plugins) добавляем новый PWM.
Я взял PWM4 исключительно из-за удобства ножки. Так как PWM в пике не может без таймера, посмотрим и на его.
Так как пока ничего не понятно, просто нажмем «Generate Code» и попробуем запустить полученное. Как обычно, ничего не должно произойти — программы нет. Если у вас вылезла ошибка про VDD, то надо в Run-Project Configuration-PICKit3-Power поставить галочку напротив Power target Cirсuit. Просто можно программировать платы «в работе», а тока от программатора не всегда хватит для питания схемы.
Набираем первый код. Все делается в main.c, там я блоки разделил комментариями.
uint16_t count; for (count=0; count<1024; count++) { PWM4_LoadDutyValue(count); __delay_ms(10); } Закачиваем и подключаем осциллограф одним входом к выходу микроконтроллера (синяя линия) и другим к динамику (красная).
Итак, что же мы видим? Синяя линия — это результат работы ШИМа. Заполнение от 0 до 100% и скачком снова на ноль. А вот красная линия где-то на середине заполнения отдаленно похожа на синусоиду. Скажу честно, это отдаленность получена путем прицепления конденсатора в 0,47 мкФ параллельно транзистору, для красивой гифки. Реальную картину можно увидеть ниже.
Уберем конденсатор.Видите пики на красном? Это динамик на «обратном ходу» работает как генератор и легко накидывает целый вольт при питании от 3х. В принципе при соблюдении некоторых условий легко можно спалить схему. Но у нас эти пики никому не мешают, поэтому ставить кондер или нет — ваше дело. Я поставил ради красоты.
Снова поставим. Оно уже было, но эта картинка в статике.Сменим на 0,1 мкф. Просто для сравнения и отображения влияния емкости на звук:)
В принципе мы уже получили писк в 15 килогерц, но кому он нужен, кроме комаров? Значит надо крутить частоту. Частота у ШИМа зависит от таймера, а как часто будет «тикать» таймер, зависит от счетчика, который устанавливается при каждом запуске таймера.
То есть алгоритм работы таймера выглядит примерно так— Запускаем таймер.— Таймер тикнул и уменьшил счетчик.— Счетчик в ноле? Если нет, то снова тикаем. Если да — генерируем прерывание.
Обработчик прерывания: — ОЙ! Таймер тикнул! — Сбросить таймер заново
И вот запуск ШИМа как раз у нас подцеплен к прерыванию таймера. А мы можем крутить как частоту «входа тиканья» (prescaler в настройках), так и величину счетчика.
Меняем код (оно же stage2)
uint8_t count;
for (count=0; count<256;count++) { PWM4_LoadDutyValue(count*2); TMR2_LoadPeriodRegister(count); __delay_ms(100); } Смотрим на красивую красную линию и видим, что получается нечто отдаленное на синусоиду, причем изменяющуюся по частоте. Да и ухо подтверждает. То, что нам надо!
Зачем я меняю заполнение ШИМа, предлагаю подумать самостоятельно. Но в принципе если мысленно продолжить график и затормозить изменение одного параметра, то все становится ясно. Особо продвинутые могут увидеть аналогичную картинку в каком-нибудь эмуляторе, например proteus
Давайте теперь определим, какой частотный диапазон мы получили
Прибиваем count в 255А теперь ставим в 10
Обратите внимание на правый верхний угол, где указывается шаг сетки. У меня «на глаз» получился диапазон примерно 300–5000Гц. Вполне. И по черепу «ездить» не будет. Перфекционисты могут воспользоваться частотомером, или подсчитать реальное значение из тактовой частоты и прескалеров.
А вот дальше у меня возникли проблемы. Какого-либо понимания, как должно оно звучать у меня нет. Грубо говоря, в музыке чукча читатель, но никак не писатель.
С трудом пополам нашел, какие частоты каким нотам соответствуют, нашел какую-то нотную запись «в лесу родилась елочка»…
Подсчитал задержки, написал
#define do 243 //523Hz #define re 239 //587 #define mi 236 //659 #define fa 231 //739 #define sol 229 //783 #define la 224 //880 #define si 218 //987 // and again +523Hz
const uint8_t elka[29]={do, la, la, sol, la, fa, do, do, do, la, la, si, sol, do, do, re, re, si, si, si, la, sol, fa, do, la, la, sol, la, fa};
void play (uint8_t p) { // 255 — 3ms period — 300Hz // 10 — 0,2ms — 5000Hz PWM4_LoadDutyValue (p*2); TMR2_LoadPeriodRegister (p); } … uint8_t count;
for (count = 0; count < 29; count++) { play(elka[count]); __delay_ms(300); PWM4_LoadDutyValue(0); TMR2_LoadPeriodRegister(0); __delay_ms(50); } Скомпилировал, запустил. Нет, мелодия угадывается без проблем, но все не так. Путем подбора резисторов и конденсаторов добился «почти синусоиды-пилы» на выходе, но ухо слышит разницу.
В итоге пока остановился на обычном двухтональном сигнале: «высокий-низкий». Классический полицейский «вау-вау», известный всем по голливудским фильмам, у меня не получился. И гугл в ответ на «police sirene tones code programm example» выдает что угодно, только не то что надо.
Помогите, плиз? В какой последовательности там пиликанье идет?
В принципе, мы уже подошли к тому, что бы следующим шагом взять и воспроизвести обычный wav. То есть не мучаться с тонами и прочим. Просто записать звук, перевести его в удобоваримую форму и проиграть. Как делали в свое время разные ScreamTracker’ы.
Проблема только одна: полсекунды звука в формате PCM, моно, с дискретизацией 8КГц занимает около килобайта. А у меня всего три с половиной килобайта. Не пойдет. Но ознакомиться с принципами и примерами можно просто введя гуглу «pic pcm sound». И прямо с первой ссылки будут и исходники и сами программы.
Поэтому утешаемся тем, что у нас будет настоящий, «теплый ламповый звук из тех времен», для которого не нужно внимание программиста: сказал какую частоту пиликать и пошел заниматься своими делами, а там железяки сами все сделают.
Но звук — это половина дела. Хороший свет — тоже отличительный признак настоящего тюнинга :) Но это чуть позже.
Как обычно, готовые проект для MPLAB со всеми штуками можно забрать тут