Atmega8 мелодии. Едноставни звучни сирени на MK AVR. Користење на звучниот модул

Статијата ги опишува принципите на синтеза на музика на AVR. Вклучениот софтвер ви овозможува да конвертирате која било миди-датотека во изворво C за AVR микроконтролери за додавање репродукција на музички фрагменти на готови случувања. Се разгледува пример за користење софтвер во музичка кутија.

Прво, кратко видео за тоа како функционира сето тоа:

Што дозволува софтверот

Софтверот за компјутер ви овозможува да добиете извор C за CodeVision AVR, кој ја репродуцира избраната midi-датотека:

1. Поврзете заеднички\hxMidiPlayer.h, common\hxMidiPlayer.c со вашиот проект. Копирајте ги шаблоните ATMega8Example\melody.h, ATMega8Example\melody.c, ATMega8Example\hxMidiPlayer_config.h и поврзете се.
2. Стартувајте го MidiToC.exe
3. Вчитајте ја датотеката Midi.
4. Поставете го плеерот: стапка на земање примероци, број на канали, форма на бранови итн. Софтверот ја репродуцира мелодијата на ист начин како што ќе репродуцира AVR.
5. Кликнете на „Create player config“ и залепете го изворот во hxMidiPlayer_config.h.
6. Кликнете на „Create melody code“ и залепете го изворот во melody.c
7. Во нашиот проект, го имплементираме методот Player_Output() за излез на звук преку PWM или надворешен DAC.
8. Поставете го тајмерот на Sampling rate и повикајте Player_TimerFunc() од прекинот.
9. Јавете се на Player_StartMelody(&s_melody, 0).

Мелодијата се репродуцира од прекинот на тајмерот. Ова значи дека за време на репродукцијата, микроконтролерот може да врши и корисна работа.

Како работи

Во остатокот од статијата ќе се обидам накратко да објаснам како сето ова се спроведува. За жал, нема да биде многу кратко - има многу материјал. Ако не сте заинтересирани, можете веднаш да отидете во секциите „Опис на софтверот“ и „API на играчот“.

Што е музика

Музиката е низа звуци со различна фреквенција и времетраење. Фреквенцијата на основната хармоника на звукот мора да одговара на фреквенцијата на одредена нота. Ако фреквенцијата на вибрации на звуците се разликува од фреквенциите на нотите, ни се чини дека музичарот е „нагласен“.

Табела. Забелешка фреквенции, Hz.

Сите ноти се поделени на октави, по 7 ноти во секоја + 5 полутонови (црни копчиња на пијаното). Фреквенциите на нотите во соседните октави се разликуваат за точно 2 пати.

Наједноставниот музички плеер содржи табела со низа ноти (нота + времетраење) на мелодија и табела со фреквенции на ноти. За да се синтетизира звук, се користи еден од каналите на тајмерот, кој формира меандер:

За жал, таков примитивен плеер има фиксна форма на бранови (квадратен бран), кој не е многу сличен на вистинските музички инструменти и може да свири само една нота во исто време.

Вистинската мелодија содржи најмалку два дела (соло + бас), а кога се свири на пијано, претходната нота сè уште продолжува да звучи кога ќе започне следната. Ова е лесно да се разбере со запомнување на структурата на пијаното - секоја нота одговара на посебна низа. Можеме да направиме неколку жици да звучат истовремено со поминување со рацете преку копчињата.

Некои микроконтролери имаат повеќе канали за тајмер, тие може да се користат за симултано репродукција на повеќе ноти. Но, обично овие канали се вреден ресурс и не е препорачливо да се користат сите. Освен, се разбира, ако не правиме само музичка кутија.
Севкупно, за да добиете полифонија и разни звуци на музички инструменти, треба да користите синтеза на звук.

Синтеза на звук на AVR

hxMidiPlayer користи аудио синтеза и може да репродуцира полифонија со различни бранови форми. Плеерот ја пресметува амплитудата на излезниот сигнал во управувачот за прекин на тајмерот со фреквенција од 8-22 KHz (колку е доволна моќноста на процесорот; исто така зависи од формата на бранот и бројот на канали).

Принципот на синтеза на звук може да се објасни со примерот на синусоидна синтеза.

Да земеме табела со големина 64, во секоја ќелија од која вредностите на синусната амплитуда се запишани на индекс на точки * 2 * PI / 64 (еден период):

Статички блиц uint8_t s_sineТабе 0 x95, 0x95, 0x95, 0x94 , 0x93, 0x93, 0x91, 0x90, 0x8F, 0x8D, 0x8C, 0x8A, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7E, 0x7C, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,0 0 x71, 0x70, 0x6F, 0x6D, 0x6D, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6C, 0x6D, 0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x7,7,0x0C);

128 (0x80) одговара на нула, 255 (0xff) на најголемата позитивна точка, 0 на најголемата негативна точка.

Сега да речеме дека ќе ги изнесеме вредностите од табелата во надворешен DAC во прекин на тајмерот повикан на фреквенција од 1000 Hz:

Статички uint8_t s_index = 0; // Timer1 output compare Рутинска услуга за прекин прекинува void timer1_compa_isr(void) ( SetDac(s_sineTable[ s_index]); if (s_index == 63) (s_index = 0; ) else (s_index++;)

Што ќе добиеме како резултат? Ќе добиеме синусоидни осцилации со фреквенција од 1000/64 Hz.

Сега да го зголемиме индексот во прекинот не за 1, туку за два.
Очигледно, излезната фреквенција на осцилација веќе ќе биде 1000/64 * 2 Hz.

Во принцип, за да ја добиете фреквенцијата F, треба да го зголемите индексот во табелата за:
додадете = F / 1000 * 64

Овој број може да биде фракционо, но за да се добие голема брзина, се користи аритметика со фиксна точка.

Бројот на записи во табелата и фреквенцијата на тајмерот влијаат на квалитетот на синтетизираниот звук. Во нашиот случај, 64 записи во табелата по период се доволни, а фреквенцијата на тајмерот е 12 kHz. Минималната прифатлива фреквенција на тајмерот е 8 kHz, идеалната е 44 kHz.

Очигледно, со фреквенција на тајмер од 12 kHz, можеме да генерираме максимум квадратни бранови од 6 kHz, бидејќи треба да направиме најмалку два прекинувачи по период. Сепак, повисоките фреквенции сè уште ќе бидат препознатливи ако излезната состојба е правилно пресметана при секое штиклирање на тајмерот.

Можете да внесете вредности за периодот на несинусоидни осцилации во табелата и да добиете различен звук.

Слабеење

Ако музичкиот инструмент се базира на жици (на пример, пијано), тогаш по притискање на копче звукот непречено исчезнува. За да добиете поприроден звук на синтисајзерот, треба непречено да ја намалите амплитудата на вибрациите по почетокот на нотата („завиткајте“ ги вибрациите во форма за слабеење - „плик“).

Плеерот содржи табела за распаѓање што ја користи за да ја намали амплитудата на синусот (или друга форма на бранови) од моментот на започнување на нотата.
„Синус“ „завиткан“ во таква школка наликува на звук на механичка музичка кутија.

Синтеза на меандер

Посебниот облик на меандерскиот бран овозможува значително поедноставување на синтезата. Табелите не се користат во овој случај. Доволно е да се пресмета каква состојба (1 или 0) треба да има излезот на дадена фреквенција при тековниот штиклирање на тајмерот. Ова се прави со користење на аритметика со цели броеви и работи многу брзо, што ја објаснува популарноста на користењето квадратен бран за репродукција на мелодии во 8-битни сет-топ кутии.

Пример: декларирање бројач:

Статички uint16_t s_counter = 0;

што ќе го зголемиме за 0x8000 во секој прекин на тајмерот, а најзначајниот бит од бројачот ќе излезе на портата:

// Излез на Timer1 споредба Рутински прекин на услугата за прекин Void timer1_compa_isr(void) ( PORTA.0 = (s_counter >> 15) & 1; s_counter += 0x8000; )

Бидејќи 0x8000 + 0x8000 = 0x10000, променливата s_counter се прелева, 17-тиот бит е отфрлен и 0x0000 се запишува на променливата.
Така, со фреквенција на тајмер од 8KHz, излезот ќе биде квадратен бран од 4KHz.
Ако го зголемите бројачот за 0x4000, добивате квадратен бран од 2KHz.

Во принцип, можете да ја добиете фреквенцијата F со додавање:
додадете = F / 8000 * 0x10000

На пример, за да добиете квадратен бран со фреквенција од 1234Hz, треба да додадете 0x277C. Вистинската фреквенција малку ќе се разликува од дадената, бидејќи членот го заокружуваме на цел број. Ова е прифатливо во синтисајзер.

Синтеза на звуци на вистински инструменти

Можете да го дигитализирате звукот на нотата пред пијаното (со користење на ADC за складирање на вредностите на амплитудата на звукот во меморија во редовни интервали):
а потоа репродуцирајте го звукот (користејќи го DAC за да ги емитувате снимените вредности во редовни интервали).

Во принцип, за да ги синтетизирате тапаните, треба да снимате звуци од тапаните и да ги репродуцирате во вистинскиот момент. Во 8-битните конзоли, наместо звуците на тапанот се користи „бел шум“. Вредностите на амплитудата за „бел шум“ се добиваат со помош на генератор случајни броеви. Трошоците за меморија се минимални.
hxMidiPlayer користи „бел шум“ за синтеза на барабанот.

Мешање на канали

Звучната амплитуда на даден знак на тајмер се пресметува за секој канал посебно. За да ја добиете конечната вредност на амплитудата, треба да ги додадете вредностите на сите канали. Точно, неопходно е да се прилагоди збирот, бидејќи воочената гласност е послушна на логаритамска зависност, но во таков едноставен синтисајзер ќе треба да се задоволите со едноставно собирање. Затоа, максималната амплитуда на секој канал е 255/N.

Емитување звук од AVR

По извршувањето на сите потребни пресметки, играчот го добива нивото на сигнал што треба да се претвори во аналогно. За овие цели, можете да користите надворешен DAC или PWM.
Овде треба да се забележи дека и во двата случаи препорачливо е да се филтрира примениот сигнал - да се отстрани високофреквентниот шум што се јавува поради малата фреквенција на синтеза и заокружување.

Излез на надворешен паралелен DAC

Бидејќи нема смисла да се користат прецизни DAC чипови, ваквите проекти обично се задоволуваат со R2R матрица:

Со оваа шема, ние едноставно ја испуштаме пресметаната амплитуда на пристаништето:

PORTB = примерок;

Недостатоци:
1) излезот од матрицата R2R е исто така слаб сигнал, употребата на аналоген засилувач е задолжителна;
2) потребно е да се користат најмалку 5 пинови (и по можност 8);
Овој метод е оправдан само кога нема бесплатни PWM канали.

(за да зачувате пинови, можете да користите надворешен ADC со интерфејс SPI).

PWM

Ако има бесплатен PWM канал, тогаш најлесниот начин е да го користите овој метод.

Иницијализација на PWM (ATMega8):

// Иницијализација на тајмер/бројач 2 // Извор на часовник: Системски часовник // Вредност на часовникот: 20000.000 kHz // Режим: Брз PWM top=0xFF // OC2 излез: Неинвертиран PWM ASSR=0x00; TCCR2=0x69; TCNT2=0x00; OCR2=0x00; И излезниот примерок: void Player_Output(uint8_t примерок) ( OC2 = примерок. )

Вообичаената практика за користење PWM вклучува измазнување на излезниот сигнал со помош на RC филтер:

За жал, по филтрирањето сигналот е премногу ослабен, па мора да направите аналоген засилувач за да го поврзете звучникот.

За да се поедностави колото, подобро е да останете „дигитални“ до самиот звучник. Бидејќи евтин звучник сè уште не може да репродуцира фреквенции над 30 kHz, нема потреба да ги филтрирате. Самиот дифузер ќе ги „филтрира“ високите PWM фреквенции.

Ако треба да добиете повеќе струја, можете да користите транзисторски засилувач. R1 е избран за да ја обезбеди потребната струја на звучникот.

Еве како можете да поврзете мали звучници од играчки:

За поголеми звучници, подобро е да го соберете погонот користејќи 2 транзистори и да инсталирате LC филтер за да го отстраните шумот:

Кондензаторот C1 служи за ограничување на струјата низ звучникот кога PWM не работи. Исто така, поради вклучувањето на сериски кондензатор, до звучникот стигнува сигнал кој е симетричен околу нула. Така, конусот на звучникот ќе се движи во однос на централната „опуштена“ положба, што позитивно влијае на квалитетот на звукот.
Во овој случај, транзисторите работат во режим на префрлување, така што нема потреба да се компензира за основната поместување.

PWM, поврзување со два пина

Недостаток на првите две кола е тоа што звучникот се напојува со струја во една насока. Ако ја смениме насоката на струјата, волуменот може да се зголеми за 2 пати без да се надмине дозволената моќност. За да го направите ова, звучникот е поврзан со два пина на микроконтролерот - непревртени и превртени, на пример OC1A и /OC1A. Ако нема неинвертиран излез, можете да го користите вториот канал во превртен режим (OC1B):

// Иницијализација на тајмер/бројач 1 // Извор на часовник: Системски часовник // Вредност на часовникот: 24500.000 kHz // Режим: Брз PWM врв=0x00FF // Излез OC1A: Неинв. // Излез OC1B: Превртено // Поништувач на шум: Исклучено // Влезно снимање на раб // Прекин на прелевање на тајмер 1: Исклучено // Прекин за снимање на влез: исклучено // Споредете прекин на натпревар: исклучено // Споредете Б прекин на совпаѓање: исклучено TCCR1A =0xB1; TCCR1B=0x09; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; void Player_Output (uint8_t примерок) ( OCR1A = примерок; OCR1B = примерок; )

PWM, два пина, засилувач од класа D

Недостаток на предложените кола е потрошувачката на струја за време на тишината.
„Тишина“ за нас одговара на ниво на сигнал од 128, односно PWM со 50% полнење - струјата секогаш тече низ звучникот!

Со малку менување на софтверот, можете да добиете прилично моќен софтверски и хардверски засилувач од класа D:

Void Player_Output(uint8_t примерок) ( ако (примерок >= 128) ( TCCR2=0x21; //нормално, јасно при споредување TCCR2=0x21 | 0x80; //CLEAR OC2 PORTC.0 = 0; TCCR2=0x69; //n -инвертирање PWM OCR2 = (примерок-128) * 2; ) друго // ако (примерок< 128) { TCCR2=0x31; //normal, set on compare match TCCR2=0x31 | 0x80; //SET OC2 PORTC.0 = 1; TCCR2=0x79; //inverting PWM OCR2 = (128-sample) *2; } }

Во овој случај, еден пар транзистори е поврзан со излезот PWM, вториот - со редовен дигитален излез.

Како што можете да видите од кодот, ние го сметаме сигналот над 128 како струја насочена во една насока, а сигналот под 128 како струја насочена во друга насока. На 128, двата пина на звучниците се поврзани со истиот пин за напојување и нема струја. При отстапување од нивото 128, полнењето PWM се зголемува, а струјата со соодветниот поларитет тече низ звучникот.

Важна точка во имплементацијата е принудното префрлување на излезот PWM во посакуваната состојба во моментот на префрлување на вториот (обичен дигитален) пин (PORTC.0). Пишувањето во регистарот OCR2 е баферирано за да се елиминираат дефектите на PWM. Треба веднаш да го префрлиме излезот PWM, без да го чекаме крајот на периодот.

Последното коло е IMHO најдобрата опција во смисла на едноставност, заштеда на енергија и излезна моќност.

Излез на звук со бранова форма на SquareWave

Кога се синтетизира меандер, се користат поедноставени алгоритми.

Секој канал (вклучувајќи тапани) излегува или 0 или 1. Така, 3-канален грамофон дава вредности во опсегот 0..3. Затоа, кога користите PWM, излезната процедура изгледа вака:

Void Player_Output(uint8_t примерок) ( OCR2 = примерок * (255 / HXMIDIPLAYER_CHANNELS_COUNT); )

Ако не користите PWM, тогаш за излез на 3-канална мелодија, доволни се два обични дигитални излези и 2-битна R2R матрица.

MIDI формат

Ако го погледнете добиениот код на мелодијата, лесно можете да видите дека низата користи повторувачки броеви од мал опсег. Ова е разбирливо: мелодијата користи ограничен број ноти во рамките на 1-2 октави, темпото на мелодијата е фиксно - еднакви доцнења, бројот на канали е во опсег од 0..15.
Сето ова значи дека добиената низа може значително да се намали со примена на некој вид алгоритам за компресија.
Алгоритмите како ZIP обезбедуваат добра компресија, но бараат и многу меморија за работа (ZIP речник - 64Kb). Можеме да користиме многу едноставен метод на компресија кој практично не бара меморија, чија суштина е како што следува.

Во еден бајт, сите броеви се рамномерно распоредени во опсегот 0...255, а секој број е претставен со 8 бита. Во нашиот случај, некои бројки се многу почести од другите. Ако ги кодирате често појавуваните броеви со помалку битови, а поретко со повеќе, може да добиете зголемување на меморијата.

Избираме фиксен метод за кодирање: комбинациите на битови 000.001 и 010 (должина - 3 бита) ќе ги претставуваат 3-те најчесто појавувани броеви. Комбинации на битови 0110, 0111 (должина – 4 бита) – следните 2 најчести броеви, итн.:

//000..010 - 0..2 //011 x 3..4 //100 xx 5..8 //101 xxx 9..16 //110 xxx 17..24 //111 веднаш

Комбинацијата која започнува со 111 (должина – 11 бита) ќе ги шифрира сите други броеви.
Методот на битско кодирање може да биде различен. Пробав неколку методи и го избрав овој како да дава најдобри резултати за такви податоци.

Постапката за компресија изгледа вака:
1. Пресметајте го вкупниот број на бројот X во потокот за X = .
2. Сортирајте по намалување на фреквенцијата на појавување во потокот.
3. Земете ги првите 25 броеви. Тие ќе бидат кодирани во помалку битови.
4. Кодирајте го влезниот тек.

Излезот е низа од 25 најчесто појавувани броеви и поток на битови.
Оваа компресија ви овозможува да постигнете 50% компресија со минимални трошоци за меморија и перформанси. За жал, ова го зголемува кодот на плеерот, па не се препорачува компресија за кратки мелодии.

Складирање на фреквенции на белешки

Прилично е скапо да се складираат фреквенциите на сите белешки во табела од меморијата. Всушност, постои формула за одредување на фреквенцијата на белешката според нејзиниот миди број:

F = 2^((N - 69)/12) * 440, Hz

Но, пресметувањето на фракционата моќ е доста тешко. Наместо тоа, плеерот складира 12 фреквенции на ноти во горната октава. Фреквенциите на нотите во пониските октави се одредуваат со намалување на фреквенцијата за 2^Y повеќе пати, каде што Y е бројот на октави надолу.

Понатамошен развој на компресија

Мелодијата често содржи повторувачки фрагменти („рефрени“, „стихови“). Со наоѓање на повторувачки фрагменти и прикажување на мелодијата во форма на фрагменти, можете да ја намалите мелодијата за уште 50%, речиси и да не трошите време RAM меморијаи продуктивноста. Не имплементирав таков алгоритам за да не го комплицирам проектот.

Опис на софтверот

Главен прозорец на програмата за конвертор:

Копчето Load Midi ви овозможува да вчитате midi датотека. Програмата веднаш започнува со репродукција на датотеката со моментално избраните параметри, симулирајќи го звукот што ќе биде во хардверот.

Информативниот прозорец (4) прикажува:
– Должина – должина на избраниот фрагмент од мелодија во ms;
– Max Active канали за синтисајзер – максимален број на истовремено активни канали за синтисајзер;
– Макс активни канали на барабанот – максимален број на истовремено активни канали за синтисајзер што репродуцираат „тапани“;
– Макс активни стерео белешки – максимален број на канали кои ја репродуцираат истата нота (види подолу);
– Проценета големина, бајти – големина на мелодијата во бајти. Во режимот „Прилагоден примерок“, големината се прикажува како A+B, каде што A е големината на мелодијата, B е големината на примерокот. Големината на кодот на плеерот не е наведена овде.

Прозорецот за напредок ја прикажува моменталната позиција на репродукција.
Можете да кликнете на лентата за напредок за да започнете со репродукција од наведената точка.
Влезните полиња лево и десно ви дозволуваат да го одредите почетокот и крајот на фрагментот на мелодијата во ms.

Етикетата „Нема доволно канали за репродукција на мелодија“ со црвена боја покажува дека нема доволно канали за синтисајзер за репродукција на мелодијата со тековните поставки. Ако плеерот не најде бесплатен канал, ја исклучува најстарата белешка. Во многу случаи ова ќе функционира добро. Има смисла да се зголеми бројот на канали само кога мелодијата звучи неправилно на увото.

Поставките може да се поделат на поставки за плеер и поставки за обработка на миди датотеки. Плеерот ќе може да го репродуцира добиениот код на мелодијата ако конфигурацијата на плеерот и кодот на мелодијата се создадени со истите поставки на плеерот. Покрај тоа, плеерот ќе може да репродуцира мелодија чиј код е креиран за плеер со помал (но не поголем) број на канали.

Хардверските поставки на плеерот вклучуваат:

– Стапка на земање примероци – фреквенција на синтеза. Максималната фреквенција на фузија се одредува експериментално. Врз основа на Atmega 16MHz, можете да започнете на 12000Hz за плеер со 6 канали и да го зголемувате по желба додека изобличувањето на мелодијата не стане забележливо со уво во хардверскиот плеер. Максималната фреквенција зависи од бројот на канали, брановата форма и сложеноста на самата мелодија.

– Бранова форма – бранова форма:
– Квадратен бран – меандер;
– Синус – синус;
– Синус + Обвивка – синус со слабеење;
– Waveform * + Envelope – различни опции за несинусоидни бранови со и без слабеење;
– Прилагоден примерок – користете примерок од инструментот.

Копчето „Вчитај примерок“ ви овозможува да вчитате примерок од датотека WAV. WAV-датотеката мора да биде во PCM 8-битна моно, 4173Hz, C-5. Совет: можете да ја зголемите фреквенцијата и да ја намалите белешката, но променете ја висината во поставките на плеерот. Нема проверки на формат - ако форматот е различен, звукот нема да се репродуцира правилно.
Висина - ви овозможува да ја промените висината на звукот. На пример, за да играте 1 октава повисоко, треба да поставите Pitch +12.

Користете компресија - користете компресија на мелодија.
Овозможи синтисајзер на тапани – овозможете го синтисајзерот на барабанот.

Канали за репродукција: Број на канали за синтисајзер (максималниот број на белешки што ќе звучат истовремено).

Поставките за обработка на Midi датотеки вклучуваат:

Вообичаено, такво фино подесување не е потребно. Овие поставки може да се остават како стандардни.

АПИ на играчот

Имплементацијата на плеерот се наоѓа во датотеките Common\hxMidiPlayer.c и Common\hxMidiPlayer.h. Овие датотеки мора да бидат вклучени во проектот. Исто така, треба да креирате датотека hxMidiPlayer_config.h, во која треба да ја поставите конфигурацијата.
Плеерот е напишан во C без монтажни влошки, што го олеснува пренесувањето на други микроконтролери.

Надворешен void Player_StartMelody (конструира флеш TMelody* _pMelody, uint16_t _delay);

Почнете да ја свирите мелодијата. _delay го поставува почетното одложување пред репродукцијата, 255 единици = 1 секунда.

Void Player_Stop();

Престанете да ја свирите мелодијата.

Extern bool Player_IsPlaying();

Враќа лажно ако мелодијата завршила со репродукција.

Надворешна празнина Player_WaitFinish();

Почекајте додека мелодијата не заврши со репродукција.

Extern void Player_TimerFunc();

Оваа функција мора да се повика во прекин на тајмерот со брзината на земање примероци наведена во конфигурацијата. Кога мелодијата ќе заврши со репродукција, не мора да остварувате никакви повици.

Extern void Player_Output (uint8_t примерок);

Мора да биде имплементиран од корисникот. Повикан од плеерот кога треба да се излезе следниот примерок.

Extern void Player_Started();

Мора да биде имплементиран од корисникот. Се повикува кога играчот почнува да свири мелодија. Може да се користи за конфигурирање на прекини на тајмерот.

Extern void Player_Finished();

Мора да биде имплементиран од корисникот. Се повикува кога плеерот ќе заврши со свирењето на мелодијата. Може да се користи за оневозможување на прекини на тајмерот или за почеток на репродукција на друга мелодија.

//#define NOTES_TO_EEPROM //#define SINETABLE_TO_EEPROM //#define ENVELOPE_TO_EEPROM

Овие линии треба да се откоментираат во датотеката hxMidiPlayer_config.h ако табелата за белешки, синусната табела и табелата за слабеење треба да се наоѓаат во eeprom.

Пример проекти

ATMega644Example – проект за ATMega644, 25MHz, PWM излез на PB3.

Барања за меморија

Табела. Големина на плеерот и мелодии во блиц.

*при додавање играч на постоечки непразен проект, големината на кодот ќе биде помала

**нема доволно канали за нормална репродукција на мелодија

Мелодија 1: bach_minuet_in_g.mid, 35 сек
Мелодија 2: yiruma-river_flows_in_you.mid, 165 sec
Мелодија 3: Франц Шуберт – Серенада.средина, 217 сек

Како што можете да видите од табелата, во минималната конфигурација можете да стиснете прилично долга мелодија дури и во ATTiny2313. Компресијата може да ја намали мелодијата за повеќе од два пати, но големината на кодот на плеерот се зголемува за ~ 600 бајти.

Табелите со белешки од синус и распаѓање може да се постават во EEPROM, заштедувајќи приближно 16, 50 и 100 бајти блиц соодветно.

Кога користите примерок од датотека wav, треба да ја додадете големината на примерокот во бајти на големината на кодот на плеерот.

Пример за употреба

Како пример за користење плеер, да го разгледаме процесот на создавање музичка кутија.

Земаме готова кутија од МДФ:

Како микроконтролер, го земаме ATTiny85 во пакетот SO-8 како најевтин со доволно голема количина на меморија. Ќе го оверклокираме на 27 MHz за да добиеме синтеза фреквенција од 18 KHz со 4 канали Sine+Envelope.

Засилувачот ќе биде од D-класа со 4 транзистори за заштеда на батерии.

Транзисторите работат во режим на префрлување и можат да бидат од секаков тип. Индукторот L1 и кондензаторот C6 се избираат според вкусот за да се добие звук без бучава со висока фреквенција. R1 и R2 може да се подигнат до 2K за да се намали јачината на звукот и да се намали отскокнувањето на звучниците.

Граничниот прекинувач од дискот се вклопува совршено, како да е создаден специјално за кутијата (работи за да се отвори - кога ќе го отворите капакот, напојувањето се испорачува на плочата):

Изворите на фирмверот се наоѓаат во директориумот ATTiny85MusicBox.

8 Kb одговара:
1) плеер: 18000 Hz, 4 канали, Sine+Envelope, Pitch+12, компресија, пушта мелодии една по една (последната е зачувана во EEPROM)
2) Јирума - река тече во вас
3) Франц Шуберт – Серенада
4) П.И. Чајковски „Октомври“

Резултат на видеото:

Понатамошно развивање

Во принцип, играчот може дополнително да се развива, доведувајќи го до полноправен Midi или MOD плеер. Јас лично мислам дека за да се добие висококвалитетна мелодија би било полесно да се поврзе SD-картичка и да се репродуцираат сите WAV-датотеки од неа со многу повеќе најдобар квалитетотколку што е генерално можно да се добие со синтеза на софтвер. И таков играч е многу поедноставен во софтвер и хардвер. Нишата на hxMidiPlayer додава добар звук на готови проекти кога остануваат неколку краци и малку простор во блицот. Таа се справува со оваа задача „одлично“ веќе во постоечката форма.

Мислам дека ова може да го затвори прашањето за создавање на секакви музички кутии/ѕвона на AVR :)

Продолжувањето на лекцијата траеше долго, што е разбирливо, морав да совладам работа со мемориски картички и датотеки FAT систем. Но, сепак, се случи, лекцијата е подготвена - всушност, новогодишно чудо.

За да не ја преоптоварувам статијата со информации, нема да ја опишам структурата на форматот на датотеката wav; има повеќе од доволно информации во пребарувачите. Доволно е да се каже дека ако отворите датотека со некој вид Hex уредник, тогаш првите 44 бајти ги содржат сите информации за типот на датотеката, стапката на земање примероци, бројот на канали итн. Ако треба да ја анализирате датотеката, прочитајте го ова заглавие и ќе бидете среќни.

Податоците за носивоста започнуваат од 44 бајти, во суштина ги содржат нивоата на напон што го сочинуваат звукот. Веќе разговаравме за нивоата на напон во последниот дел од лекцијата. Така, сè е едноставно, треба да ги пренесете овие чекори на звучникот на фреквенцијата на земање примероци на датотеката.

Како физички да направите звучник да се тресе? Треба да ги извлечете овие напонски нивоа користејќи PWM или да користите R2R. Во секој случај, многу е едноставен за користење, прочитајте го бројот, ставете го или во OCR или PORTx. Потоа, по одредено време, ја заменив следната вредност и така натаму до крајот на датотеката.

Пример, одредена wav датотека, податоците доаѓаат од бајти 44=0x2C, таму е запишан бројот 0x80, го репродуцираме звукот, на пример, со PWM на првиот тајмер, напишете OCR1A=0x80; Да речеме дека фреквенцијата на земање примероци е 8 kHz, така што прекинот треба да биде поставен на истата фреквенција. Во прекинот, заменете ја следната вредност 0x85 по 1/8000 = 125 µs.

Како да поставите прекин на 8 kHz? Да потсетиме дека ако тајмерот работи на фреквенција од 250 kHz, тогаш регистарот за споредба на прекини мора да биде заменет (250/8)-1=31-1 или 0x1E. Со PWM, сè е исто така едноставно; колку е поголема фреквенцијата на која работи, толку подобро.

За да работи фирмверот, ќе се согласиме дека флеш-уредот е форматиран во FAT32, користејќи го PetitFat lib од лекцијата 23.2. Датотеката е во формат wav, или 8kHz или 22.050kHz, моно. Име на датотека 1.wav. Ајде да го анализираме фирмверот.

#вклучи #include "diskio.h" #include "pff.h" непотпишан тампон со знаци[ 512 ] ; /* бафер во кој информациите се копираат од флеш-уредот */испарливи непотпишани int count; //копиран бројач на податоципрекини [TIM2_COMP] тајмер за празнина2_comp_isr(празнина) //прекин во кој се заменуваат вредностите( OCR1A = тампон[број] ; // емитува звук на звучникотако (++ брои >= 512 ) //зголемете го бројачотброи = 0 ; //ако 512 се ресетира) void main(void) (непотпишан int br; /* бројач на датотека за читање/запишување */непотпишан знак buf = 0 ; //променлива која дефинира кој дел од баферот се чита FATFS fs; /* Работен простор (објект на датотечен систем) за логички дискови */ PORTB= 0x00 ; DDRB= 0x02 ; //скок шим ocr1a // Иницијализација на тајмер/бројач 1// Извор на часовник: Системски часовник // Вредност на часовникот: 8000.000 kHz // Режим: Брз PWM врв=0x00FF // Излез OC1A: Неинв. TCCR1A= 0x81 ; TCCR1B= 0x09 ; TCNT1= 0x00 ; OCR1A= 0x00 ; // Иницијализација на тајмер/бројач 2// Извор на часовник: Системски часовник // Вредност на часовникот: 250.000 kHz // Режим: CTC top=OCR2 TCCR2= 0x0B ; TCNT2= 0x00 ; //OCR2=0x1E; //поставување на споредбениот регистар за 8 kHz OCR2= 0xA ; //за 22 kHz #asm("sei") // Тајмер(и)/бројач(и) Иницијализација на прекин(и).ако (disk_initialize() == 0) //иницијализирај го флеш-уредот(pf_mount(&fs); //монтирање датотечен систем pf_open("1.wav"); //отвори нишка pf_lseek(44); //поместете го покажувачот на 44 pf_read(бафер, 512,& br); //за прв пат голтаме 512 бајти одеднаш TIMSK= 0x80 ; //вклучете ја музиката додека (1) (ако (! buf && count> 255 ) //ако се репродуцираат повеќе од 255 бајти,(pf_read(& buffer[0], 256,& br); //тогаш ги читаме информациите од флеш-уредот во првата половина од баферот buf= 1 ; ако (бр< 256 ) //ако баферот не содржи 256 вредности, тоа значи крај на датотекатапауза ; ) ако (buf && count< 256 ) { pf_read(& buffer[ 256 ] , 256 ,& br) ; // прочитајте во вториот дел од баферот од флеш-уредотбуф = 0 ; ако (бр< 256 ) break ; } } TIMSK = 0x00 ; //глушим все pf_mount(0x00 ) ; //расклопи го превезот) додека (1 ) ( ) )

#вклучи #include "diskio.h" #include "pff.h" непотпишан тампон со знаци; /* тампон во кој се копираат информациите од флеш-уредот */ нестабилно непотпишано броење на int; //бројач на копирани податоци прекини void timer2_comp_isr(void) //прекин во кој се заменуваат вредности ( OCR1A = бафер; //излез звук на звучникот ако (++ count >= 512) //зголеми го бројот на бројачот = 0; //if 512 reset ) void main(void) (непотпишан int br; /* бројач на датотека за читање/запишување */ непотпишан char buf = 0; //променлива што дефинира кој дел од баферот се чита FATFS fs; /* Работи област (објект на датотечниот систем) за логички погони */ PORTB=0x00; DDRB=0x02; // прескокнете го шимот ocr1a // Иницијализација на тајмерот/бројачот 1 // Извор на часовник: Системски часовник // Вредност на часовникот: 8000.000 kHz // Режим: Брз PWM top=0x00FF // OC1A излез: Неинв. TCCR1A=0x81; TCCR1B=0x09; TCNT1=0x00; OCR1A=0x00; // Иницијализација на тајмер/бројач 2 // Извор на часовник: вредност на системскиот часовник // часовник : 250.000 kHz // Режим: CTC top= OCR2 TCCR2=0x0B; TCNT2=0x00; //OCR2=0x1E; //поставување на споредбениот регистар за 8kHz OCR2=0xA; //за 22kHz #asm("sei") // Тајмер(и)/бројач(и) Иницијализација на прекини(и) if(disk_initialize()==0) //иницијализирај го флеш-уредот ( pf_mount(&fs); // монтирајте го датотечниот систем pf_open ("1.wav"); //отвори ја гранката pf_lseek(44); //поместете го покажувачот на 44 pf_read(buffer, 512,&br); //за прв пат голтаме 512 бајти одеднаш TIMSK=0x80; //вклучете ја музиката додека(1) ( if(!buf && count>255) //ако се пуштени повеќе од 255 бајти, ( pf_read(&buffer, 256,&br);//тогаш прочитајте ги информациите од блицот вози во првата половина на тампон-тампон=1; ако (бр< 256) //если буфер не содержит 256 значений значит конец файла break; } if(buf && count<256) { pf_read(&buffer, 256,&br); // читаем во вторую часть буфера с флешки buf = 0; if (br < 256) break; } } TIMSK = 0x00; //глушим все pf_mount(0x00); //демонтируем фат } while (1) { } }

За да провериме, поврзуваме звучник со пинот OCR1A преку кондензатор од 100uF, „+“ со пинот на микроконтролерот, „-“ со звучникот. „-“ звучник до заземјување, „+“ до кондензатор.

Не очекувајте силен сигнал на излезот; потребен ви е засилувач за да звучи гласно. Ова е јасно видливо на видеото. За тестот, го натоварив петелот со 8 kHz и патеката со 22 kHz.

Оние кои сакаат можат безбедно да ја зголемат фреквенцијата на тајмерот2 за да репродуцираат датотеки од 44 kHz; експериментите покажуваат дека може да се постигне доста добар квалитет на звукот. Во видеото звукот е слаб, а квалитетот е слаб, но всушност тоа се должи на тоа што го снимив со камера.

Исто така, објавувам материјали љубезно обезбедени од Apparatchik - изворниот код за GCC, од кој е напишан фирмверот за CAVR.

И видео со репродукција од 44 kHz.

Ја користам оваа прилика да им ја честитам Новата година на сите, посакувам сите фирмвери и уреди да работат за вас :)

проект wav плеер на Atmega8

Напишав софтверски модул кој ви овозможува да ја додадете функцијата за репродукција на мелодии или секвенци на звуци на речиси секој проект на микроконтролерот AVR.

Карактеристики на модулот:

Лесна интеграција со готов проект

Се користи само 8-битниот тајмер t2, додека останува можно да се користи за гласање или формирање временски интервали

Модулот е прилагодлив на речиси секоја фреквенција на генератор на часовник

Висината на нотите е наведена како симболични константи (C0, A2, итн.) или во Херци

Времетраењето се наведени во стандардна форма (четвртини, осми, итн.) или во милисекунди

Можно е да се постави темпото на репродукција на мелодијата и бројот на нејзини повторувања

За време на репродукцијата, мелодијата може да се паузира


Поврзување звучен модул

1. Копирајте ги сите датотеки со модули (tone.h, sound.h, sound.c) во проектната папка.

2. Поврзете ја датотеката sound.c со проектот.

За IAR `a – кликнете со десното копче во прозорецот на работниот простор и изберете Додај > Додај датотеки…

За WINAVR е приближно исто, само sound.c треба да се додаде во мејкфајлот:

SRC = $(TARGET).c звук.в

3. Вклучете ја датотеката со наслов sound.h во соодветниот модул. На пример, во главниот.в

#вклучи „sound.h“

4. Поставете ги поставките на модулот во датотеката sound.h

//ако коментирате, времетраењето на белешките ќе биде

//пресметано од BPM наведен во мелодијата

//ако е лево, тогаш од вредноста наведена подолу

//#define SOUND_BPM 24

//фреквенција на часовникот μ

#define SOUND_F_CPU 16U

//излез на микроконтролерот на кој ќе се генерира звукот

#define PORT_SOUND PORTB

#define PINX_SOUND 0

//број на наведени мелодии.

#define SOUND_AMOUNT_MELODY 4

5. Додајте ги вашите мелодии на sound.c и напишете ги имињата на мелодиите во мелодиската низа.

Додавање мелодии

Мелодијата е низа од 16-битни броеви и ја има следната структура

BPM (четврт белешки во минута)е константа што се користи за пресметување на времетраењето на нотите и ја одредува брзината со која се свири мелодијата.

BPM може да се движи од 1 до 24, што одговара на 10 и 240 четвртини ноти во минута, соодветно.

Ако времетраењето на нотите/звуците е одредено во милисекунди, тогаш BPM запишан во низата треба да биде еднаков на 1.

Ако константата SOUND_BPM се коментира во заглавието на датотеката sound.h, тогаш времетраењето на белешките се пресметува за време на извршувањето на програмата според BPM наведено во низата. Ако SOUND_BPM не се коментира, времетраењето на нотите се пресметува во фазата на компилација, врз основа на вредноста на оваа константа, и сите мелодии ќе се репродуцираат со исто темпо. Ова ја ограничува функционалноста, но заштедува неколку бајти код.

Број на повторувања.Може да земе вредности 1 ... 254 и LOOP (255). LOOP - значи дека мелодијата ќе се повторува бескрајно додека не се даде командата SOUND_STOP или SOUND_PAUSE.

Забелешка траење– времето во кое се генерира даден звучен тон или се одржува пауза. Може да се специфицира во ms, користејќи го макрото ms(x), или како стандардни вредности на ноти - осми белешки, шеснаесетти белешки итн. Подолу е листа на поддржани траења. Ако има потреба од некои егзотични траења, секогаш можете да ги додадете во датотеката tone.h

n1 - цела белешка

n2 - половина белешка

n4 - четвртина

n8 - осмо

n3 - осма тројка

n16 - шеснаесетти

n6 - секстола

n32 - триесет и втора

Забелешка теренотсе одредува со помош на симболични константи опишани во датотеката tone.h, на пример C2, A1, итн. Исто така, висината на белешките може да се одреди во Херц користејќи го макрото f(x).

Програмата има ограничувања за минималната и максималната фреквенција на звукот!

Маркер за крај на мелодијата.Вредноста на последниот елемент од низата мора да биде нула.

Користење на звучниот модул

На почетокот на main, мора да ја повикате функцијата SOUND_Init(). Оваа функција го поставува излезниот пин на микроконтролерот, го конфигурира тајмерот T2 и ги иницијализира променливите на модулот.

Потоа треба да го поставите знамето за овозможување на прекин - __enable_interrupt(), бидејќи модулот користи прелевање на тајмерот T2 и прекини на случајност.

По ова, можете да почнете да репродуцирате мелодии.

На пример, вака:

SOUND_SetSong (2);

SOUND_Com(SOUND_PLAY); //свири мелодија

//поставете го покажувачот на втората мелодија

//и започнете со репродукција

SOUND_PlaySong (2);

Репродукцијата на мелодијата може да се прекине во секое време со издавање на командата SOUND_STOP.
Можете исто така да ја паузирате мелодијата користејќи ја командата SOUND_PAUSE. Последователното издавање на командата SOUND_PLAY ја продолжува репродукцијата на мелодијата од местото каде што била прекината.

Во принцип, оваа функционалност не е особено потребна (штотуку ја измислив) и при работа со модулот, доволна е функцијата SOUND_PlaySong(unsigned char numSong);

Датотеки

Можете да преземете примери за користење на звучниот модул од линковите подолу. Не нацртав дијаграм затоа што таму сè е едноставно. поврзан со пинот PB0, копчето за почеток на мелодиите е поврзано со пинот PD3. Во проектите се дефинирани 4 мелодии. Со притискање на копчето секој пат започнува нова мелодија. Се користи микроконтролерот atmega8535. Првично сакав да се замарам со проект со четири копчиња - PLAY, STOP, PAUSE и NEXT, но потоа помислив дека е непотребен.

PS: Модулот не претрпел опширно тестирање и е обезбеден „како што е“. Ако има некакви рационални предлози, да го финализираме.

Во оваа статија, ќе погледнеме како да свириме тонови и ќе научиме како да свириме монофонична мелодија.

Подготовка за работа

Програмата декларира две низи. Низа со белешки белешкисодржи едноставна листа на белешки. Овие белешки се совпаѓаат со времетраењето на звукот во низата бие. Времетраењето во музиката го одредува делителот на нота во однос на целата нота. Вредноста земена како цела белешка е 255 . Половини, четвртини, осми се добиваат со делење на овој број.
Ве молиме имајте предвид дека времетраењето на првата нота не се добива со делење на 255 со моќност од два. Тука ќе треба да се префрлите на музичка теорија. Нотите на оригиналната мелодија може да се видат. Овие белешки се комбинираат во тројки. Кога се комбинираат на овој начин, трите осми ноти звучат исто како една четвртина нота. Затоа нивното релативно времетраење е 21.
Корисникот, исто така, треба експлицитно да го наведе бројот на белешки во низата со директивата:

# дефинира SEQU_SIZE 19

Во главната програма, пред сè, фреквентните низи се пресметуваат повторно и времетраењето во периоди на сигнали и времетраење на белешките.
Со периоди на сигнал (низа сигнал_период) сè е едноставно. За да го добиете времетраењето на периодот во микросекунди, едноставно поделете 1.000.000 со фреквенцијата на сигналот.
За да се пресмета апсолутното времетраење на звукот на нотите, неопходно е да се наведе темпото на музичката работа. Ова се прави со директива

# дефинирајте го ТЕМПО 108

Темпо во музиката е бројот на четвртини ноти во минута. Во линија

# дефинира WHOLE_NOTE_DUR 240000 / TEMPO

Се пресметува времетраењето на цела нота во милисекунди. Сега е доволно повторно да се пресметаат релативните вредности од низата користејќи ја формулата биедо апсолутна низа белешка_времетраење.
Во главната јамка, променливата поминато времесе зголемува по секој период од свирениот сигнал за времетраењето на овој период додека не го надмине времетраењето на нотата. Вреди да се обрне внимание на овој запис:

додека (поминато_време< 1000 * ((uint32_t) note_duration[ i] ) )

Променлива поминато време 32-битни и елементите на низата белешки_времетраење 16-битен. Ако 16-битен број се помножи со 1000, тогаш се гарантира прелевање и променливата поминато времеќе се споредуваат со ѓубре. Модификатор (uint32_t)конвертира елемент од низа белешки_времетраење[i]во 32-битен број нема прелевање.
Може да видите друга карактеристика во аудио циклусот. Нема да може да се користи функцијата _delay_us(), бидејќи нејзиниот аргумент не може да биде променлива.
За да создадете такви одложувања, користете ја функцијата VarDelay_us(). Во него, јамка со задоцнување од 1 μs се скролува одреден број пати.

void VarDelay_us(uint32_t takt) ( while (takt- - ) ( _delay_us (1 ) ;) )

При свирење на мелодија се користат уште две одложувања. Ако белешките се репродуцираат без паузи, тие ќе се спојат во една. За да го направите ова, меѓу нив се вметнува доцнење од 1 ms, наведено во директивата:

# дефинирајте NOTES_PAUSE 1

По секој комплетен циклус на свирење на мелодијата, програмата паузира 1 секунди и повторно почнува да репродуцира.
Како резултат на тоа, добивме код во кој е лесно да се промени темпото, да се прилагоди времетраењето или целосно да се преработи мелодијата. За да го направите ова, ќе биде доволно само да се трансформира само делот од програмата со директиви и декларации на променливи.

Индивидуални задачи

  1. Во предложената мелодија, обидете се да го промените темпото и паузирајте 5 секунди помеѓу повторувањата.
  2. Елементи од низа биеприфаќајте само вредности од 0 до 255. Променете ја битната ширина на елементите на низата и погледнете во излезот на компајлерот за да видите како тоа влијае на количината на меморија окупирана од програмата.
  3. Сега обидете се сами да ја промените мелодијата. На пример, тука е „Imperial March“ од истиот филм: int notes = ( A4, R, A4, R, A4, R, F4, R, C5, R, A4, R, F4, R, C5, R, A4, R, E5, R, E5, R, E5, R, F5, R, C5, R, G5, R, F5, R, C5, R, A4, R); инт отчукувања = ( 50 , 20 , 50 , 20 , 50 , 20 , 40 , 5 , 20 , 5 , 60 , 10 , 40 , 5 , 20 , 5 , 60 , 80 , 2, 5, 50 20, 40, 5, 20

    Ако вашиот автомобил нема инсталирана звучна сирена и сè уште не можете да одлучите која да ја купите и инсталирате, тогаш овој напис е само за вас. Зошто да купувате скапи аларми ако можете сето тоа сами да го соберете на прилично едноставен начин?

    Ви претставувам две од овие едноставни колана микроконтролерите AVR ATmega8 и Attiny2313, поточно истото коло едноставно е имплементирано за работа на овие два микроконтролери. Патем, во архивата ќе најдете две верзии на фирмверот за микроконтролерот Atmega8, од кои првата репродуцира звук сличен на автомобил аларм, а вториот звук е сличен на безбедносниот аларм на зградата (брз и остар сигнал).

    Можете да го преземете целиот фирмвер подолу во архивата (сите се потпишани), во архивата ќе најдете и симулација на кола во Proteus, што значи дека откако ќе ги слушнете сите мелодии можете да изберете од листата што најмногу ви се допаѓа .

    Подолу е сигналниот дијаграм за Atmega8

    Список на радио компоненти што се користат во колото Atmega8

    U1- AVR микроконтролер 8-битен ATmega8-16PU, кол. 1,
    R1- Отпорник со номинална вредност од 47 Ом, бр. 1,
    R2, R3 - Отпорник со номинална вредност од 270 Ом, бр. 2,
    D2,D3-LED, бр. 2,
    LS1-звучник, бр. 1,
    S1-сензор.

    А во колото за сигнализација на Attiny2313 само МК е сменет.
    U1- Микроконтролер AVR 8-битен ATtiny2313-20PU, количина. 1.

    Печатено колоза Atmega8 изгледа вака:

    Како што можете да видите, колото е многу едноставно, има само еден микроконтролер, 3 отпорници, 2 LED диоди и уште еден звучник. Наместо копче, можете да користите прекинувач за трска или друг контакт.

    Принципот на работа е како што следува. Веднаш штом напојуваме, ЛЕД-то (во колото D3) веднаш се пали или почнува да трепка (во зависност од фирмверот), а ако не го допреме сензорот, алармот ќе биде тивок. Сега, ако се активира сензорот, ќе работи и сирената, ќе трепка и ЛЕР, но D2.

    Ако сакате фаровите на автомобилот да трепкаат кога алармот работи, тогаш за да го направите ова, треба да го поврзете пинот на микроконтролерот 24 PC1 со релето преку транзистор, а самото реле со фаровите. За да ја исклучите сирената, треба да го исклучите и повторно да го вклучите уредот или едноставно да го притиснете копчето. За да ракувате со микроконтролерот, потребен ви е внатрешен осцилатор од 8 MHz,

    Ако сакате некако да го подобрите звукот на алармот, можете да соберете засилувач со транзистори и да го поврзете со колото. Токму тоа го направив, но не го прикажав на овој дијаграм.

    Ајде да преминеме на колото на Attiny 2313, како што кажав претходно, ги има сите исти детали и истиот принцип на работа, само МК е сменет и како резултат на тоа, поврзаните пинови. Овој микроконтролер работи од внатрешен осцилатор од 4 MHz, иако може да трепка на 1 MHz.

    Подолу е дијаграмот за поврзување веќе на Attiny2313

    За овој МК напишав само една верзија на фирмверот, склопив се на плочката, проверив, се работи добро.
    И осигурувачите треба да се постават како што е прикажано подолу:





Врв