НАПРИМЕР
С целью увеличения интересности подпольно спаянного и в тайне запрограммированного робота использую проигрывание мелодий AVR-кой на пьезопищалку от китайских игрушек или будильников.
Пищалка подключается плюсиком через керамический конденсатор 0,47 мкФ к "+" питания (VCC) а минусовой лапкой - к ноге МК.
Этот традиционный способ, упомянтый еще в книге Предко, наверное обусловлен тем, что старые модели контроллеров могли выдерживать втекающие токи бОльшие, чем вытекающие.
В современных мегах, вроде бы одинаковые (не берусь утверждать на 100%), поэтому можно плюсом пищалки к ноге МК, а минусом через конденсатор - на землю.
Если использовать динамик, нужно будет юзать транзистор.
Частоты нот первой октавы в герцах:
до - 130,8
до# - 138,6
ре - 146,8
ре# - 155,6
ми - 164,8
фа - 174,6
фа# - 185,0
соль - 196,0
соль# - 207,7
ля - 220,0
ля# - 233,1
си - 246,9
Частоты одинаковых нот соседних октав отличаются в два раза. На слух на пищалке более приятно звучат ноты второй и третьей октав.
Генерацию можно осуществить в цикле for (cvarv):
- Код: Выделить всё • Развернуть
...
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1911);}; //до
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1702);}; //ре
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1517);}; //ми
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1432);}; //фа
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1276);}; //соль
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1136);}; //ля
for (i=1;i<100;i++) {PORTD.7=~PIND.7; delay_us(1012);}; //си
...
При этом частоты нужно пересчитать в периоды задержек между инвертированием сигнала на лапке контроллера.
Например для ноты до второй октавы частота равна 130,8*2=261,6 Гц. Период колебаний равен 1/261,6=3,8227 миллисекунд.
Сигнал на ножке МК нужно изменять через промежуток времени в 2 раза меньший, т.е. 3,8227/2=1,911 миллисекунд или
1911 микросекунд.
Выражение в условии выполнения цикла i<100 определяет длительность проигрывания ноты, т.е. число полупериодов колебаний.
Для звучания ноты до 0,5 секунды нужно примерно 0,5/0,001911=262 раза изменить сигнал на лапе, что и следует указать в операторе цикла.
Разработчики cvarv рекомендуют отключать прерывания перед использованием функций задержек delay_us и delay_ms (они используют сторожевой таймер).
Последняя, по-моему, реализована кривовато, т.к. задержи больше, чем задаются, а первая - потому что длительность нельзя передавать как параметр в процедуру (должна быть постоянной), а очень хочется.
Для подачи звуковых сигналов можно использовать и ШИМ, чтобы разгрузить контроллер.
PS. Звук очень удобно юзать для отладки и диагностики.