Tonuri de apel Atmega8. Sirene sonore simple pe MK AVR. Folosind modulul de sunet

Articolul descrie principiile sintezei muzicii pe un AVR. Software-ul inclus vă permite să convertiți orice fișier midi în sursăîn C pentru microcontrolere AVR pentru a adăuga redarea fragmentelor muzicale la dezvoltări gata făcute. Este luat în considerare un exemplu de utilizare a software-ului într-o cutie muzicală.

Mai întâi, un scurt videoclip despre cum funcționează totul:

Ce permite software-ul

Software-ul pentru computer vă permite să obțineți o sursă C pentru CodeVision AVR, care redă fișierul midi selectat:

1. Conectați common\hxMidiPlayer.h, common\hxMidiPlayer.c la proiectul dvs. Copiați șabloanele ATMega8Example\melody.h, ATMega8Example\melody.c, ATMega8Example\hxMidiPlayer_config.h și conectați-vă.
2. Lansați MidiToC.exe
3. Încărcați fișierul Midi.
4. Configurați playerul: rata de eșantionare, numărul de canale, forma de undă etc. Software-ul redă melodia în același mod în care va reda AVR-ul.
5. Faceți clic pe „Creare player config” și inserați sursa în hxMidiPlayer_config.h.
6. Faceți clic pe „Creați codul melodiei” și inserați sursa în melody.c
7. În proiectul nostru, implementăm metoda Player_Output() pentru a scoate sunet prin PWM sau un DAC extern.
8. Setați cronometrul la rata de eșantionare și apelați Player_TimerFunc() de la întrerupere.
9. Apelați Player_StartMelody(&s_melody, 0).

Melodia este redată de la întreruperea temporizatorului. Aceasta înseamnă că, în timpul redării, microcontrolerul poate face și o muncă utilă.

Cum functioneaza

În restul articolului voi încerca să explic pe scurt cum sunt implementate toate acestea. Din păcate, nu va fi foarte scurt - există o mulțime de materiale. Dacă nu sunteți interesat, puteți accesa imediat secțiunile „Descriere software” și „API Player”.

Ce este muzica

Muzica este o secvență de sunete cu frecvențe și durate diferite. Frecvența armonicii fundamentale a unui sunet trebuie să corespundă frecvenței unei anumite note. Dacă frecvența de vibrație a sunetelor diferă de frecvența notelor, ni se pare că muzicianul este „deacord”.

Masa. Notă frecvențe, Hz.

Toate notele sunt împărțite în octave, câte 7 note în fiecare + 5 semitonuri (clape negre la pian). Frecvențele notelor din octavele adiacente diferă de exact de 2 ori.

Cel mai simplu music player conține un tabel cu secvența de note (notă + durată) a unei melodii și un tabel cu frecvențe de note. Pentru a sintetiza sunetul, se folosește unul dintre canalele temporizatorului, care formează un meandre:

Din păcate, un astfel de jucător primitiv are o formă de undă fixă ​​(undă pătrată), care nu este foarte asemănătoare cu instrumentele muzicale reale și poate cânta doar o notă la un moment dat.

O melodie adevărată conține cel puțin două părți (solo + bas), iar atunci când este cântată la pian, nota anterioară continuă să sune atunci când a început următoarea. Acest lucru este ușor de înțeles prin amintirea structurii unui pian - fiecare notă corespunde unei coarde separate. Putem face să sune mai multe corzi în același timp trecându-ne mâinile peste taste.

Unele microcontrolere au mai multe canale de cronometru, acestea pot fi folosite pentru a reda mai multe note simultan. Dar, de obicei, aceste canale sunt o resursă valoroasă și nu este recomandabil să le folosiți pe toate. Dacă, desigur, nu facem decât o cutie muzicală.
În total, pentru a obține polifonie și diverse sunete ale instrumentelor muzicale, trebuie să utilizați sinteza sunetului.

Sinteza sunetului pe AVR

hxMidiPlayer folosește sinteza audio și poate reda polifonie cu diferite forme de undă. Playerul calculează amplitudinea semnalului de ieșire în handler-ul de întrerupere a temporizatorului cu o frecvență de 8-22 KHz (câtă putere procesor este suficientă; depinde și de forma de undă și de numărul de canale).

Principiul sintezei sunetului poate fi explicat folosind exemplul sintezei sinusoide.

Să luăm un tabel cu dimensiunea 64, în fiecare celulă din care valorile amplitudinii sinusului sunt scrise la punctele index * 2 * PI / 64 (o perioadă):

Flash const static uint8_t s_sineTable[ 64 ] = ( 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x93, 0x93, 0x93, 0x93, 0x93, 0x8C, 0x8D, 0x8F 9 5, 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. x7 1, 0x70, 0x6F, 0x6D, 0x6D, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6C, 0x6D, 0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78

128 (0x80) corespunde cu zero, 255 (0xff) celui mai mare punct pozitiv, 0 celui mai mare punct negativ.

Acum să presupunem că vom scoate valorile din tabel într-un DAC extern într-o întrerupere a temporizatorului numită la o frecvență de 1000 Hz:

Static uint8_t s_index = 0; // Timer1 output compare O rutină de întrerupere a serviciului de întrerupere void timer1_compa_isr(void) ( SetDac(s_sineTable[ s_index]); if (s_index == 63) ( s_index = 0; ) else ( s_index++; ) )

Ce vom obține ca rezultat? Vom obține oscilații sinusoidale cu o frecvență de 1000/64 Hz.

Acum să creștem indicele în întrerupere nu cu 1, ci cu două.
Evident, frecvența de oscilație de ieșire va fi deja 1000/64 * 2 Hz.

În general, pentru a obține frecvența F, trebuie să creșteți indicele din tabel cu:
adăugați = F / 1000 * 64

Acest număr poate fi fracționar, dar pentru a obține viteză mare se folosește aritmetica cu punct fix.

Numărul de intrări din tabel și frecvența cronometrului afectează calitatea sunetului sintetizat. În cazul nostru, 64 de intrări în tabel pe perioadă sunt suficiente, iar frecvența temporizatorului este de 12 kHz. Frecvența minimă acceptabilă a temporizatorului este de 8 kHz, ideala este de 44 kHz.

Evident, cu o frecvență de cronometru de 12 kHz, putem genera maxim 6 kHz unde pătrate, deoarece trebuie să facem cel puțin două comutatoare pe perioadă. Cu toate acestea, frecvențele mai înalte vor fi în continuare recunoscute dacă starea de ieșire este calculată corect la fiecare bifare a temporizatorului.

Puteți introduce valori pentru perioada de oscilații non-sinusoidale în tabel și puteți obține un sunet diferit.

Atenuare

Dacă un instrument muzical se bazează pe coarde (de exemplu, un pian), atunci după apăsarea unei taste, sunetul dispare fără probleme. Pentru a obține un sunet de sintetizator mai natural, trebuie să reduceți ușor amplitudinea vibrațiilor după începerea notei („înveliți” vibrațiile într-o formă de atenuare – „înveliș”).

Playerul conține o tabelă de dezintegrare pe care o folosește pentru a reduce amplitudinea sinusului (sau a altei forme de undă) din momentul în care începe nota.
„Sine” „învelit” într-o astfel de carcasă seamănă cu sunetul unei cutii muzicale mecanice.

Sinteza meandrelor

Forma specială a undei meandrului permite simplificarea semnificativă a sintezei. Tabelele nu sunt folosite în acest caz. Este suficient să se calculeze ce stare (1 sau 0) ar trebui să aibă ieșirea la o anumită frecvență la bifarea cronometrului curent. Acest lucru se face folosind aritmetica întregi și funcționează foarte rapid, ceea ce explică popularitatea utilizării unui val pătrat pentru a reda melodii în set-top box-uri de 8 biți.

Exemplu: declararea unui contor:

Static uint16_t s_counter = 0;

pe care îl vom crește cu 0x8000 la fiecare întrerupere a temporizatorului, iar cel mai semnificativ bit al contorului va fi scos la port:

// Timer1 output compare O rutină de serviciu de întrerupere întreruperea void timer1_compa_isr(void) ( PORTA.0 = (s_counter >> 15) & 1; s_counter += 0x8000; )

Deoarece 0x8000 + 0x8000 = 0x10000, variabila s_counter depășește, al 17-lea bit este eliminat și 0x0000 este scris în variabilă.
Astfel, cu o frecvență de cronometru de 8KHz, ieșirea va fi o undă pătrată de 4KHz.
Dacă creșteți contorul cu 0x4000, obțineți o undă pătrată de 2KHz.

În general, puteți obține frecvența F adăugând:
adăugați = F / 8000 * 0x10000

De exemplu, pentru a obține o undă pătrată cu o frecvență de 1234 Hz, trebuie să adăugați 0x277C. Frecvența reală va diferi ușor de cea dată, deoarece rotunjim termenul la un număr întreg. Acest lucru este acceptabil într-un sintetizator.

Sinteza sunetelor instrumentelor reale

Puteți digitiza sunetul notei înainte de pian (folosind un ADC pentru a stoca valorile amplitudinii sunetului în memorie la intervale regulate):
și apoi redați sunetul (folosind DAC pentru a scoate valorile înregistrate la intervale regulate).

În general, pentru a sintetiza tobe, trebuie să înregistrați sunete de tobe și să le redați la momentul potrivit. În consolele pe 8 biți, „zgomotul alb” este folosit în loc de sunetele de tobe. Valorile de amplitudine pentru „zgomotul alb” sunt obținute folosind un generator numere aleatorii. Costurile de memorie sunt minime.
hxMidiPlayer folosește „zgomot alb” pentru sinteza tobei.

Mixarea canalelor

Amplitudinea sunetului la un timp dat este calculată pentru fiecare canal separat. Pentru a obține valoarea finală a amplitudinii, trebuie să adăugați valorile tuturor canalelor. În mod corect, este necesar să ajustați suma, deoarece volumul perceput se supune unei dependențe logaritmice, dar într-un sintetizator atât de simplu va trebui să vă descurcați cu o simplă adăugare. Prin urmare, amplitudinea maximă a fiecărui canal este de 255/N.

Se emite sunet de la AVR

După efectuarea tuturor calculelor necesare, jucătorul primește nivelul semnalului care trebuie convertit în analog. În aceste scopuri, puteți utiliza un DAC sau PWM extern.
Trebuie remarcat aici că, în ambele cazuri, este recomandabil să filtrați semnalul primit - pentru a elimina zgomotul de înaltă frecvență care apare din cauza frecvenței scăzute de sinteză și rotunjire.

Ieșire către DAC paralel extern

Deoarece nu are sens să folosești cipuri DAC precise, astfel de proiecte se descurcă de obicei cu o matrice R2R:

Cu această schemă, pur și simplu trimitem amplitudinea calculată către port:

PORTB = proba;

Defecte:
1) ieșirea matricei R2R este de asemenea semnal slab, folosirea unui amplificator analogic este obligatorie;
2) este necesar să folosiți cel puțin 5 pini (și de preferat 8);
Această metodă este justificată numai atunci când nu există canale PWM gratuite.

(pentru a salva pinii, puteți utiliza un ADC extern cu o interfață SPI).

PWM

Dacă există un canal PWM gratuit, atunci cel mai simplu mod este să utilizați această metodă.

Inițializare PWM (ATMega8):

// Inițializare Timer/Counter 2 // Sursa ceas: System Clock // Valoare ceas: 20000.000 kHz // Mod: Fast PWM top=0xFF // Ieșire OC2: Non-Inverted PWM ASSR=0x00; TCCR2=0x69; TCNT2=0x00; OCR2=0x00; Și rezultatul eșantionului: void Player_Output(uint8_t sample) ( OC2 = sample. )

Practica obișnuită pentru utilizarea PWM implică netezirea semnalului de ieșire folosind un filtru RC:

Din păcate, după filtrare semnalul este slăbit prea mult, așa că trebuie să faci un amplificator analogic pentru a conecta difuzorul.

Pentru a simplifica circuitul, este mai bine să rămâneți „digital” până la difuzorul însuși. Deoarece un difuzor ieftin încă nu poate reproduce frecvențe de peste 30 kHz, nu este nevoie să le filtrați. Difuzorul în sine va „filtra” frecvențele înalte PWM.

Dacă trebuie să obțineți mai mult curent, puteți utiliza un amplificator cu tranzistor. R1 este selectat pentru a furniza curentul necesar difuzorului.

Iată cum puteți conecta difuzoare mici de la jucării:

Pentru difuzoarele mai mari, este mai bine să asamblați unitatea folosind 2 tranzistori și să instalați un filtru LC pentru a elimina zgomotul:

Condensatorul C1 servește la limitarea curentului prin difuzor atunci când PWM-ul nu funcționează. De asemenea, datorită includerii unui condensator în serie, un semnal care este simetric față de zero ajunge la difuzor. Astfel, conul difuzorului se va deplasa în raport cu poziția centrală „relaxată”, ceea ce are un efect pozitiv asupra calității sunetului.
În acest caz, tranzistoarele funcționează în modul de comutare, deci nu este nevoie să se compenseze decalajul de bază.

PWM, conexiune cu doi pini

Dezavantajul primelor două circuite este că difuzorul este alimentat cu curent într-o singură direcție. Dacă schimbăm direcția curentului, volumul poate fi mărit de 2 ori fără a depăși puterea admisă. Pentru a face acest lucru, difuzorul este conectat la doi pini ai microcontrolerului - neinversat și inversat, de exemplu OC1A și /OC1A. Dacă nu există o ieșire neinversată, puteți utiliza cel de-al doilea canal în modul inversat (OC1B):

// Temporizator/Inițializare contor 1 // Sursă ceas: Ceas sistem // Valoare ceas: 24500.000 kHz // Mod: PWM rapid top=0x00FF // Ieșire OC1A: Non-Inv. // Ieșire OC1B: inversată // Anulare zgomot: Dezactivat // Captură de intrare pe marginea de cădere // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Comparare A Match Interrupt: Off // Compara B Match Interrupt: Off 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 sample) ( OCR1A = probă; OCR1B = probă; )

PWM, doi pini, amplificator clasa D

Dezavantajul circuitelor propuse este consumul de curent în timpul tăcerii.
„Tăcerea” pentru noi corespunde unui nivel de semnal de 128, adică PWM cu umplere de 50% - curentul trece întotdeauna prin difuzor!

Schimbând ușor software-ul, puteți obține un software destul de puternic și un amplificator hardware de clasă D:

Void Player_Output(uint8_t sample) ( dacă (eșantion >= 128) ( TCCR2=0x21; //normal, ștergeți la comparație TCCR2=0x21 | 0x80; //CLEAR OC2 PORTC.0 = 0; TCCR2=0x69; //non -inversarea PWM OCR2 = (proba-128) * 2; ) else // if (probă< 128) { TCCR2=0x31; //normal, set on compare match TCCR2=0x31 | 0x80; //SET OC2 PORTC.0 = 1; TCCR2=0x79; //inverting PWM OCR2 = (128-sample) *2; } }

În acest caz, o pereche de tranzistori este conectată la ieșirea PWM, a doua - la o ieșire digitală obișnuită.

După cum puteți vedea din cod, considerăm un semnal peste 128 ca un curent direcționat într-o direcție, iar un semnal sub 128 ca un curent direcționat în cealaltă direcție. La 128, ambii pini de difuzor sunt conectați la același pin de alimentare și nu există curent. Când devii de la nivelul 128, umplerea PWM crește, iar un curent cu polaritatea corespunzătoare curge prin difuzor.

Un punct important în implementare este comutarea forțată a ieșirii PWM la starea dorită în momentul comutării celui de-al doilea pin (digital obișnuit) (PORTC.0). Scrierea în registrul OCR2 este tamponată pentru a elimina erorile PWM. Trebuie să comutăm imediat ieșirea PWM, fără a aștepta sfârșitul perioadei.

Cel din urmă circuit este, din punctul meu de vedere, cea mai bună opțiune în ceea ce privește simplitatea, economiile de energie și puterea de ieșire.

Ieșire de sunet cu formă de undă SquareWave

La sintetizarea unui meandre, se folosesc algoritmi simplificați.

Fiecare canal (inclusiv tobe) iese fie 0, fie 1. Astfel, o placă turnantă cu 3 canale emite valori în intervalul 0..3. Prin urmare, atunci când utilizați PWM, procedura de ieșire arată astfel:

Void Player_Output(uint8_t sample) ( OCR2 = sample * (255 / HXMIDIPLAYER_CHANNELS_COUNT); )

Dacă nu utilizați PWM, atunci pentru a scoate o melodie cu 3 canale, sunt suficiente două ieșiri digitale obișnuite și o matrice R2R de 2 biți.

format MIDI

Dacă te uiți la codul de melodie rezultat, poți vedea cu ușurință că matricea folosește numere care se repetă dintr-un interval mic. Acest lucru este de înțeles: melodia folosește un număr limitat de note în 1-2 octave, tempo-ul melodiei este fix - întârzieri egale, numărul de canale este în intervalul 0..15.
Toate acestea înseamnă că matricea rezultată poate fi redusă semnificativ prin aplicarea unui fel de algoritm de compresie.
Algoritmi precum ZIP oferă o compresie bună, dar necesită și multă memorie pentru a funcționa (dicționar ZIP - 64Kb). Putem folosi o metodă de compresie foarte simplă, care practic nu necesită memorie, a cărei esență este următoarea.

Într-un octet, toate numerele sunt distribuite uniform în intervalul 0...255, iar fiecare număr este reprezentat de 8 biți. În cazul nostru, unele numere sunt mult mai frecvente decât altele. Dacă codificați numere care apar frecvent cu mai puțini biți și pe cele care apar mai puțin frecvent cu mai mulți, puteți obține un câștig de memorie.

Alegem o metodă de codare fixă: combinațiile de biți 000.001 și 010 (lungime - 3 biți) vor reprezenta cele 3 numere care apar cel mai frecvent. Combinații de biți 0110, 0111 (lungime – 4 biți) – următoarele 2 numere cele mai comune etc.:

//000..010 - 0..2 //011 x 3..4 //100 xx 5..8 //101 xxx 9..16 //110 xxx 17..24 //111 imediat

Combinația care începe cu 111 (lungime – 11 biți) va codifica toate celelalte numere.
Metoda de codificare a biților poate fi diferită. Am încercat mai multe metode și am ales-o pe aceasta ca oferind cele mai bune rezultate pe astfel de date.

Procedura de compresie arată astfel:
1. Calculați numărul total de număr X din flux pentru X = .
2. Sortați după frecvența descrescătoare a apariției în flux.
3. Luați primele 25 de numere. Ele vor fi codificate în mai puțini biți.
4. Codificați fluxul de intrare.

Ieșirea este o matrice a celor 25 de numere care apar cel mai frecvent și un flux de biți.
Această compresie vă permite să obțineți o compresie de 50% cu costuri minime de memorie și performanță. Din păcate, acest lucru mărește codul playerului, așa că compresia nu este recomandată pentru melodiile scurte.

Stocarea frecvențelor notelor

Este destul de costisitor să stocați frecvențele tuturor notelor într-un tabel din memorie. De fapt, există o formulă pentru a determina frecvența unei note după numărul său midi:

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

Dar calcularea puterii fracționale este destul de dificilă. În schimb, jucătorul stochează 12 frecvențe de note în octava superioară. Frecvențele notelor din octavele inferioare sunt determinate prin scăderea frecvenței de 2^Y de mai multe ori, unde Y este numărul de octave în jos.

Dezvoltarea în continuare a compresiei

Melodia conține adesea fragmente care se repetă („refrenuri”, „versuri”). Găsind fragmente care se repetă și prezentând melodia sub formă de fragmente, puteți reduce melodia cu încă 50%, fără a pierde timp. RAMși productivitatea. Nu am implementat un astfel de algoritm pentru a nu complica proiectul.

Descrierea software-ului

Fereastra principală a programului convertor:

Butonul Load Midi vă permite să încărcați un fișier midi. Programul începe imediat redarea fișierului cu parametrii selectați în prezent, simulând sunetul care va fi în hardware.

Fereastra de informații (4) afișează:
– Lungime – lungimea fragmentului de melodie selectat în ms;
– Max canale de sintetizator activ – numărul maxim de canale de sintetizator activ simultan;
– Max canale de tobe active – numărul maxim de canale de sintetizator activ simultan care reproduc „tobe”;
– Max note stereo active – numărul maxim de canale care reproduc aceeași notă (vezi mai jos);
– Dimensiunea estimată, octeți – dimensiunea melodiei în octeți. În modul „Custom Sample”, dimensiunea este afișată ca A+B, unde A este dimensiunea melodiei, B este dimensiunea eșantionului. Mărimea codului jucătorului nu este specificată aici.

Fereastra de progres afișează poziția curentă de redare.
Puteți face clic pe bara de progres pentru a începe redarea din punctul specificat.
Casetele de intrare din stânga și din dreapta vă permit să specificați începutul și sfârșitul fragmentului de melodie în ms.

Eticheta „Nu sunt suficiente canale pentru a reda melodia” în roșu indică faptul că nu există suficiente canale de sintetizator pentru a reda melodia cu setările curente. Dacă playerul nu găsește un canal gratuit, oprește cea mai veche notă. În multe cazuri, acest lucru va funcționa bine. Este logic să creșteți numărul de canale doar atunci când melodia sună incorect la ureche.

Setările pot fi împărțite în setări player și setări de procesare a fișierelor midi. Playerul va putea reda codul de melodie rezultat dacă configurația playerului și codul de melodie au fost create cu aceleași setări ale playerului. În plus, jucătorul va putea reda o melodie al cărei cod a fost creat pentru un player cu un număr mai mic (dar nu mai mare) de canale.

Setările hardware ale playerului includ:

– Frecvența de eșantionare – frecvența de sinteză. Frecvența maximă de fuziune este determinată experimental. Bazat pe Atmega 16MHz, puteți începe de la 12000Hz pentru un player cu 6 canale și puteți crește după cum doriți până când distorsiunea melodiei devine vizibilă la ureche în playerul hardware. Frecvența maximă depinde de numărul de canale, forma de undă și complexitatea melodiei în sine.

– formă de undă – formă de undă:
– Undă pătrată – meandre;
– Sinus – sinus;
– Sinus + Envelope – sinus cu atenuare;
– Waveform * + Envelope – diverse opțiuni pentru unde nesinusoidale cu și fără atenuare;
– Probă personalizată – utilizați un eșantion al instrumentului.

Butonul „Load Sample” vă permite să încărcați un eșantion dintr-un fișier WAV. Fișierul WAV trebuie să fie în PCM mono pe 8 biți, 4173 Hz, C-5. Sugestie: Puteți crește frecvența și reduce nota, dar modificați Pitch-ul în setările playerului. Nu există verificări de format - dacă formatul este diferit, sunetul nu va fi redat corect.
Pitch – vă permite să schimbați înălțimea sunetului. De exemplu, pentru a reda cu 1 octavă mai sus, trebuie să setați Pitch +12.

Utilizați compresia – utilizați compresia melodiei.
Activați sintetizatorul de tobe – activați sintetizatorul de tobe.

Player Channels: numărul de canale de sintetizator (numărul maxim de note care vor suna simultan).

Setările de procesare a fișierelor Midi includ:

De obicei, o astfel de reglare fină nu este necesară. Aceste setări pot fi lăsate ca implicite.

Player API

Implementarea playerului se află în fișierele Common\hxMidiPlayer.c și Common\hxMidiPlayer.h. Aceste fișiere trebuie incluse în proiect. De asemenea, trebuie să creați un fișier hxMidiPlayer_config.h, în care trebuie să plasați configurația.
Playerul este scris în C fără inserții de asamblare, ceea ce facilitează portarea lui la alte microcontrolere.

Extern void Player_StartMelody(const flash TMelody* _pMelody, uint16_t _delay);

Începeți să redați melodia. _delay setează întârzierea inițială înainte de redare, 255 unități = 1 secundă.

Void Player_Stop();

Nu mai cânta melodia.

Extern bool Player_IsPlaying();

Returnează false dacă melodia s-a terminat.

Extern void Player_WaitFinish();

Așteptați până când melodia se încheie.

Extern void Player_TimerFunc();

Această funcție trebuie apelată într-o întrerupere a temporizatorului la rata de eșantionare specificată în configurație. Când melodia s-a terminat de redat, nu trebuie să efectuați niciun apel.

Extern void Player_Output(uint8_t sample);

Trebuie implementat de utilizator. Apelat de jucător atunci când următorul eșantion trebuie să fie scos.

Extern void Player_Started();

Trebuie implementat de utilizator. Apelat atunci când jucătorul începe să cânte o melodie. Poate fi folosit pentru a configura întreruperile temporizatorului.

Extern void Player_Finished();

Trebuie implementat de utilizator. Apelat când jucătorul a terminat de redat melodia. Poate fi folosit pentru a dezactiva întreruperile temporizatorului sau pentru a începe să redați o altă melodie.

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

Aceste linii trebuie să fie decomentate în fișierul hxMidiPlayer_config.h dacă tabelul de note, tabelul de sinus și tabelul de atenuare trebuie să fie localizate în eeprom.

Exemple de proiecte

ATMega644Example – proiect pentru ATMega644, 25MHz, ieșire PWM pe PB3.

Cerințe de memorie

Masa. Dimensiunea playerului și melodiile în flash.

* când adăugați un jucător la un proiect existent nevid, dimensiunea codului va fi mai mică

**nu există suficiente canale pentru redarea normală a melodiei

Melodia 1: bach_minuet_in_g.mid, 35 sec
Melodia 2: yiruma-river_flows_in_you.mid, 165 sec
Melodia 3: Franz Schubert – Serenade.mid, 217 sec

După cum puteți vedea din tabel, în configurația minimă puteți stoarce o melodie destul de lungă chiar și în ATTiny2313. Compresia poate reduce melodia de mai mult de două ori, dar dimensiunea codului playerului crește cu ~600 de octeți.

Tabelele de note sinus și decay pot fi plasate în EEPROM, salvând aproximativ 16, 50 și, respectiv, 100 de octeți de memorie flash.

Când utilizați o mostră dintr-un fișier wav, trebuie să adăugați dimensiunea eșantionului în octeți la dimensiunea codului playerului.

Exemplu de utilizare

Ca exemplu de utilizare a unui player, să luăm în considerare procesul de creare a unei cutii muzicale.

Luăm o cutie MDF gata făcută:

Ca microcontroler, luăm ATTiny85 în pachet SO-8 drept cel mai ieftin cu o cantitate suficient de mare de memorie. Îl vom overclock la 27MHz pentru a obține o frecvență de sinteză de 18KHz cu 4 canale Sine+Envelope.

Amplificatorul va fi clasa D cu 4 tranzistoare pentru a economisi bateriile.

Tranzistoarele funcționează în modul de comutare și pot fi de orice tip. Inductorul L1 și condensatorul C6 sunt selectați în funcție de gust pentru a obține sunet fără zgomot de înaltă frecvență. R1 și R2 pot fi crescute până la 2K pentru a reduce volumul și a reduce saritura difuzorului.

Întrerupătorul de limită de la unitatea de disc se potrivește perfect, ca și cum a fost creat special pentru cutie (funcționează pentru a se deschide - când deschideți capacul, placa este alimentată):

Sursele de firmware se află în directorul ATTiny85MusicBox.

8Kb se potrivește:
1) player: 18000Hz, 4 canale, Sine+Envelope, Pitch+12, compresie, redă melodii una câte una (ultima este stocată în EEPROM)
2) Yiruma – Râul curge în tine
3) Franz Schubert – Serenada
4) P.I. Ceaikovski „octombrie”

Rezultat pe video:

Dezvoltare în continuare

În principiu, jucătorul poate fi dezvoltat în continuare, aducându-l la un jucător Midi sau MOD cu drepturi depline. Personal cred că pentru a obține o melodie de înaltă calitate ar fi mai ușor să conectați un card SD și să redați orice fișiere WAV de pe acesta cu mult mai mult cea mai buna calitate decât este în general posibil de obținut prin sinteză software. Și un astfel de player este mult mai simplu în software și hardware. Nișa hxMidiPlayer adaugă un sunet bun proiectelor gata făcute atunci când mai rămân câteva picioare și puțin spațiu în bliț. Face față acestei sarcini „excelent” deja în forma sa existentă.

Cred că acest lucru poate închide problema creării a tot felul de cutii muzicale/clopote pe AVR :)

Continuarea lecției a durat mult timp, ceea ce este de înțeles; a trebuit să stăpânesc lucrul cu carduri de memorie și fișiere Sistemul FAT. Dar totuși, s-a întâmplat, lecția este gata - de fapt, un miracol de Anul Nou.

Pentru a nu supraîncărca articolul cu informații, nu voi descrie structura formatului de fișier wav; există mai mult decât suficiente informații în motoarele de căutare. Este suficient să spunem că, dacă deschideți un fișier cu un fel de editor Hex, atunci primii 44 de octeți conțin toate informațiile despre tipul fișierului, rata de eșantionare, numărul de canale etc. Dacă trebuie să analizați fișierul, citiți aceasta antet și vei fi fericit.

Datele de sarcină utilă încep de la 44 de octeți, conținând în esență nivelurile de tensiune care alcătuiesc sunetul. Am vorbit deja despre nivelurile de tensiune în ultima parte a lecției. Astfel, totul este simplu, trebuie să transmiteți acești pași către difuzor la frecvența de eșantionare a fișierului.

Cum să faci fizic un difuzor să tremure? Trebuie să scoateți aceste niveluri de tensiune folosind PWM sau să utilizați R2R. În orice caz, este foarte simplu de utilizat, citiți numărul, puneți-l fie în OCR, fie în PORTx. Apoi, după un anumit timp, am înlocuit următoarea valoare și așa mai departe până la sfârșitul fișierului.

De exemplu, un anumit fișier wav, datele provin de la octeții 44=0x2C, acolo este scris numărul 0x80, redăm sunetul, de exemplu, prin PWM al primului temporizator, scriem OCR1A=0x80; Să presupunem că frecvența de eșantionare a probei este de 8 kHz, deci întreruperea ar trebui să fie setată la aceeași frecvență. În întrerupere, înlocuiți următoarea valoare 0x85 după 1/8000 = 125 µs.

Cum se setează întreruperea la 8kHz? Să ne amintim că, dacă temporizatorul funcționează la o frecvență de 250 kHz, atunci registrul de comparare a întreruperilor trebuie înlocuit (250/8)-1=31-1 sau 0x1E. Cu PWM, totul este, de asemenea, simplu; cu cât este mai mare frecvența la care funcționează, cu atât mai bine.

Pentru ca firmware-ul să funcționeze, vom fi de acord ca unitatea flash să fie formatată în FAT32, folosind lib-ul PetitFat din lecția 23.2. Fișierul este în format wav, fie 8kHz, fie 22.050kHz, mono. Nume fișier 1.wav. Să analizăm firmware-ul.

#include #include "diskio.h" #include "pff.h" buffer de caracter nesemnat[ 512 ] ; /* buffer în care sunt copiate informațiile de pe unitatea flash */ număr de int volatile nesemnate; //contorul de date copiatîntrerupe [TIM2_COMP] void timer2_comp_isr(void) //întreruperea în care se înlocuiesc valorile( OCR1A = buffer[ count] ; // scoate sunet la difuzor dacă (++ număr >= 512 ) //mărește contorul număr = 0; //dacă 512 este resetat) void main(void) ( unsigned int br; /* contor de citire/scriere fișier */ unsigned char buf = 0 ; //variabilă care definește ce parte din buffer este citită FATFS fs; /* Spațiu de lucru (obiect sistem de fișiere) pentru unitățile logice */ PORTB= 0x00 ; DDRB= 0x02 ; //salt shim ocr1a // Inițializarea temporizatorului/contorului 1// Sursa ceas: Ceas sistem // Valoare ceas: 8000.000 kHz // Mod: Fast PWM top=0x00FF // Ieșire OC1A: Non-Inv. TCCR1A= 0x81; TCCR1B= 0x09; TCNT1= 0x00; OCR1A= 0x00; // Inițializarea temporizatorului/contorului 2// Sursa ceas: Ceas sistem // Valoare ceas: 250.000 kHz // Mod: CTC top=OCR2 TCCR2= 0x0B ; TCNT2= 0x00; //OCR2=0x1E; //setarea registrului de comparație pentru 8kHz OCR2= 0xA; //pentru 22kHz #asm("sei") // Timer(e)/Contor(e) Întrerupe(e) de inițializare if (disk_initialize() == 0) //inițializați unitatea flash( pf_mount(&fs) ; //montură Sistemul de fișiere pf_open("1.wav"); //deschide un thread pf_lseek(44) ; //mută indicatorul la 44 pf_read(buffer, 512 ,& br) ; // pentru prima dată înghițim 512 octeți deodată TIMSK= 0x80 ; //porniți muzica în timp ce (1) ( dacă (! buf && numără> 255 ) //dacă sunt reproduși mai mult de 255 de octeți,( pf_read(& buffer[ 0 ], 256 ,& br) ; //apoi citim informațiile de pe unitatea flash în prima jumătate a memoriei tampon buf= 1; dacă (br< 256 ) //dacă bufferul nu conține 256 de valori, înseamnă sfârșitul fișierului pauză ; ) dacă (buf && numără< 256 ) { pf_read(& buffer[ 256 ] , 256 ,& br) ; // citește a doua parte a buffer-ului de pe unitatea flash buf = 0 ; dacă (br< 256 ) break ; } } TIMSK = 0x00 ; //глушим все pf_mount(0x00 ) ; //demontează vălul) în timp ce (1 ) ( ) )

#include #include „diskio.h” #include „pff.h” buffer de caracter nesemnat; /* buffer în care informațiile sunt copiate de pe unitatea flash */ volatile unsigned int count; //contorul de date copiate întrerupe void timer2_comp_isr(void) //întrerupe în care valorile sunt înlocuite (OCR1A = buffer; //ieșire sunet la difuzor dacă (++count >= 512) //crește numărul contorului = 0; //dacă 512 reset ) void main(void) ( unsigned int br; /* contor de citire/scriere fișier */ unsigned char buf = 0; //variabilă care definește ce parte din buffer este citită FATFS fs; /* Funcționează zonă (obiect de sistem de fișiere) pentru unitățile logice */ PORTB=0x00; DDRB=0x02; //săriți shim-ul ocr1a // Inițializare Timer/Counter 1 // Sursa ceas: System Clock // Valoare ceas: 8000.000 kHz // Mod: Fast PWM top=0x00FF // Ieșire OC1A: Non-Inv. TCCR1A=0x81; TCCR1B=0x09; TCNT1=0x00; OCR1A=0x00; // Inițializare Timer/Counter 2 // Sursa ceas: Ceas sistem // Valoare ceas : 250.000 kHz // Mod: CTC top= OCR2 TCCR2=0x0B; TCNT2=0x00; //OCR2=0x1E; //setarea registrului de comparație pentru 8kHz OCR2=0xA; //pentru 22kHz #asm("sei") // Timer(e)/Contor(e) Întrerupe(e) inițializarea if(disk_initialize()==0) //inițializează unitatea flash ( pf_mount(&fs); //montează sistemul de fișiere pf_open("1.wav"); //deschide ramura pf_lseek(44); //mută indicatorul la 44 pf_read(buffer, 512,&br); // pentru prima dată înghițim 512 octeți deodată TIMSK=0x80; //porniți muzica în timp ce(1) ( dacă (!buf && count>255) //dacă au fost redați mai mult de 255 de octeți, ( pf_read(&buffer, 256,&br);//apoi citiți informațiile din flash conduceți în prima jumătate a tamponului buf=1; dacă (br< 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) { } }

Pentru a verifica, conectăm un difuzor la pinul OCR1A printr-un condensator de 100uF, „+” la pinul microcontrolerului, „-” la difuzor. „-” difuzorul la masă, „+” la condensator.

Nu vă așteptați la un semnal puternic la ieșire; aveți nevoie de un amplificator pentru a suna tare. Acest lucru este clar vizibil în videoclip. Pentru test am incarcat cocosul cu 8 kHz si pista cu 22 kHz.

Cei care doresc pot crește în siguranță frecvența timer-ului2 pentru a reda fișiere de 44 kHz; experimentele arată că se poate obține o calitate a sunetului destul de bună. În videoclip, sunetul este slab și calitatea este slabă, dar de fapt asta se datorează faptului că l-am filmat cu o cameră.

De asemenea, postez materiale oferite cu amabilitate de Apparatchik - codul sursă pentru GCC, din care a fost scris firmware-ul pentru CAVR.

Și video cu redare de 44 kHz.

Profit de această ocazie pentru a felicita pe toată lumea pentru Anul Nou, îmi doresc ca toate firmware-urile și dispozitivele să funcționeze pentru tine :)

proiect player wav pe Atmega8

Am scris un modul software care vă permite să adăugați funcția de redare a melodiilor sau secvențelor de sunet la aproape orice proiect de pe microcontrolerul AVR.

Caracteristicile modulului:

Integrare ușoară cu un proiect gata făcut

Este folosit doar cronometrul de 8 biți t2, în timp ce rămâne posibil să îl utilizați pentru interogare sau formare a intervalelor de timp

Modulul este reglabil la aproape orice frecvență a generatorului de ceas

Înălțimea notelor este specificată ca constante simbolice (C0, A2, etc.) sau în Herți

Duratele sunt specificate în formă standard (sferturi, optimi etc.) sau în milisecunde

Este posibil să setați tempo-ul de redare a melodiei și numărul de repetări ale acesteia

În timpul redării, melodia poate fi întreruptă


Conectarea unui modul de sunet

1. Copiați toate fișierele modulului (tone.h, sound.h, sound.c) în folderul proiectului.

2. Conectați fișierul sound.c la proiect.

Pentru IAR `a – faceți clic dreapta în fereastra spațiului de lucru și selectați Adăugare > Adăugați fișiere...

Pentru WINAVR este cam același, doar sound.c trebuie adăugat la makefile:

SRC = $(TARGET).c sunet.c

3. Includeți fișierul antet sound.h în modulul corespunzător. De exemplu, în main.c

#include „sound.h”

4. Setați setările modulului în fișierul sound.h

//dacă comentați, durata notelor va fi

//calculat din BPM-ul specificat în melodie

//dacă a rămas, atunci din valoarea specificată mai jos

//#definiți SOUND_BPM 24

//frecvența ceasului μ

#define SOUND_F_CPU 16U

//ieșirea microcontrolerului pe care va fi generat sunetul

#define PORT_SOUND PORTB

#define PINX_SOUND 0

//numărul de melodii specificate.

#define SOUND_AMOUNT_MELODY 4

5. Adăugați melodiile dvs. în sound.c și scrieți numele melodiilor în matricea de melodii.

Adăugarea tonurilor de apel

Melodia este o matrice de numere pe 16 biți și are următoarea structură

BPM (note sferturi pe minut) este o constantă folosită pentru a calcula durata notelor și determină viteza cu care este redată melodia.

BPM poate varia de la 1 la 24, ceea ce corespunde la 10 și, respectiv, 240 de note pe minut.

Dacă durata notelor/sunetelor este specificată în milisecunde, atunci BPM-ul scris în matrice ar trebui să fie egal cu 1.

Dacă constanta SOUND_BPM este comentată în fișierul antet sound.h, atunci durata notelor este calculată în timpul execuției programului în conformitate cu BPM-ul specificat în matrice. Dacă SOUND_BPM nu este comentat, durata notelor este calculată în etapa de compilare, pe baza valorii acestei constante, iar toate melodiile vor fi redate la același tempo. Acest lucru limitează funcționalitatea, dar salvează câțiva octeți de cod.

Numărul de repetări. Poate lua valori 1 ... 254 și LOOP (255). LOOP - înseamnă că melodia se va repeta la nesfârșit până când este dată comanda SOUND_STOP sau SOUND_PAUSE.

Notă durata– timpul în care se generează un anumit ton sonor sau se menține o pauză. Poate fi specificat în ms, folosind macro-ul ms(x), sau ca valori standard ale notei - note a opta, note a șaisprezecea etc. Mai jos este o listă de durate acceptate. Dacă este nevoie de anumite durate exotice, le puteți adăuga oricând în fișierul tone.h

n1 - nota intreaga

n2 - jumătate de notă

n4 - sfert

n8 - al optulea

n3 - a opta tripletă

n16 - al șaisprezecelea

n6 - sextole

n32 - treizeci și secunde

Notă pasul este specificat folosind constante simbolice descrise în fișierul tone.h, de exemplu C2, A1 etc. De asemenea, înălțimea notelor poate fi specificată în Hertz folosind macro-ul f(x).

Programul are restricții privind frecvența minimă și maximă a sunetului!

Marcator de sfârșit de melodie. Valoarea ultimului element al matricei trebuie să fie zero.

Folosind modulul de sunet

La începutul main, trebuie să apelați funcția SOUND_Init(). Această funcție setează pinul de ieșire al microcontrolerului, configurează temporizatorul T2 și inițializează variabilele modulului.

Apoi trebuie să setați indicatorul de activare a întreruperii - __enable_interrupt(), deoarece modulul folosește timer overflow T2 și întreruperi de coincidență.

După aceasta, puteți începe să cântați melodii.

De exemplu, așa:

SOUND_SetSong(2);

SOUND_Com(SOUND_PLAY); //reda melodie

//setează indicatorul la a doua melodie

//și începe redarea

SUNET_PlaySong(2);

Redarea melodiei poate fi oprită în orice moment prin lansarea comenzii SOUND_STOP.
De asemenea, puteți întrerupe melodia folosind comanda SOUND_PAUSE. Emiterea ulterioară a comenzii SOUND_PLAY reia redarea melodiei din punctul în care a fost oprită.

În principiu, această funcționalitate nu este deosebit de necesară (tocmai am inventat-o) și când lucrezi cu modulul, funcția SOUND_PlaySong(unsigned char numSong) este suficientă;

Fișiere

Puteți descărca exemple de utilizare a modulului de sunet din linkurile de mai jos. Nu am desenat o diagramă pentru că totul este simplu acolo. conectat la pinul PB0, butonul de pornire a melodiilor este conectat la pinul PD3. Sunt 4 melodii definite în proiecte. Apăsarea butonului începe o nouă melodie de fiecare dată. Se folosește microcontrolerul atmega8535. Inițial am vrut să mă deranjez cu un proiect cu patru butoane - PLAY, STOP, PAUSE și NEXT, dar apoi am crezut că nu este necesar.

PS: Modulul nu a fost supus unor teste extinse și este furnizat „ca atare”. Dacă există propuneri raționale, să o finalizăm.

În acest articol, vom analiza cum să redăm tonuri și să învățăm cum să cântăm o melodie monofonică.

Pregătirea de muncă

Programul declară două matrice. Matrice cu note note conține o listă simplă de note. Aceste note se potrivesc cu durata sunetului din matrice bate. Durata în muzică este determinată de divizorul unei note în raport cu întreaga notă. Valoarea luată ca o notă întreagă este 255 . Jumătățile, sferturile, optimile se obțin prin împărțirea acestui număr.
Vă rugăm să rețineți că durata primei note nu se obține prin împărțirea 255 la o putere de doi. Aici va trebui să treci la teoria muzicii. Notele melodiei originale pot fi vizualizate. Aceste note sunt combinate în triplete. Atunci când sunt combinate în acest fel, trei note a opta sună la fel ca o notă un sfert. Prin urmare, durata lor relativă este de 21.
De asemenea, utilizatorul trebuie să specifice în mod explicit numărul de note din secvența cu directiva:

# definiți SEQU_SIZE 19

În programul principal, în primul rând, matricele de frecvență sunt recalculate și durata în perioade de semnale și durata notelor.
Cu perioade de semnal (matrice perioada_semnal) totul este simplu. Pentru a obține durata perioadei în microsecunde, împărțiți pur și simplu 1.000.000 la frecvența semnalului.
Pentru a calcula durata absolută a notelor, trebuie specificat tempo-ul lucrării muzicale. Acest lucru se face prin directivă

# definiți TEMPO 108

Tempo în muzică este numărul de note sferturi pe minut. În linie

# definește WHOLE_NOTE_DUR 240000 / TEMPO

Se calculează durata unei note întregi în milisecunde. Acum este suficient să recalculăm valorile relative din matrice folosind formula bate la matrice absolută durată_notă.
În bucla principală, variabila timpul scurs este incrementat după fiecare perioadă a semnalului redat cu durata acestei perioade până când depășește durata notei. Merită să acordați atenție acestei intrări:

în timp ce(timpul_trecut< 1000 * ((uint32_t) note_duration[ i] ) )

Variabil timpul scurs 32 de biți și elementele matricei note_duration pe 16 biți. Dacă un număr de 16 biți este înmulțit cu 1000, atunci se garantează o depășire și variabila timpul scurs va fi comparat cu gunoiul. Modificator (uint32_t) convertește un element de matrice durată_note[i]într-un număr de 32 de biți nu există depășire.
Puteți vedea o altă caracteristică în bucla audio. Funcția nu va fi posibilă _delay_us(), deoarece argumentul său nu poate fi o variabilă.
Pentru a crea astfel de întârzieri, utilizați funcția VarDelay_us(). În ea, o buclă cu o întârziere de 1 μs este derulată de un număr specificat de ori.

void VarDelay_us(uint32_t takt) ( în timp ce (takt- - ) ( _delay_us(1 ) ; ) )

Când redați o melodie, sunt folosite încă două întârzieri. Dacă notele sunt redate fără pauze, ele se vor îmbina într-una singură. Pentru a face acest lucru, se introduce o întârziere de 1 ms între ele, specificată de directivă:

# definește NOTES_PAUSE 1

După fiecare ciclu complet de redare a melodiei, programul se întrerupe timp de 1 secundă și începe redarea din nou.
Drept urmare, am primit un cod în care este ușor să schimbați tempo-ul, să reglați durata sau să rescrieți complet melodia. Pentru a face acest lucru, va fi suficient să transformați doar partea din program cu directive și declarații de variabile.

Sarcini individuale

  1. În melodia propusă, încercați să schimbați tempo-ul și întrerupeți 5 secunde între repetări.
  2. Elemente de matrice bate acceptă numai valori de la 0 la 255. Schimbați lățimea de biți a elementelor matricei și căutați în rezultatul compilatorului pentru a vedea cum afectează acest lucru cantitatea de memorie ocupată de program.
  3. Acum încercați să schimbați singur melodia. De exemplu, iată „Marșul imperial” din același film: 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); int bătăi = ( 50 , 20 , 50 , 20 , 50 , 20 , 40 , 5 , 20 , 5 , 60 , 10 , 40 , 5 , 20 , 5 , 60 , 80 , 50 , 0, 5 , 0, 5 , 0, 5 20, 40, 5, 20

    Dacă mașina dvs. nu are instalată o sirenă de sunet și încă nu vă puteți decide pe care să cumpărați și să instalați, atunci acest articol este doar pentru dvs. De ce să cumpărați alarme scumpe dacă le puteți asambla singur într-un mod destul de simplu?

    Vă prezint două dintre acestea circuite simple pe microcontrolerele AVR ATmega8 și Attiny2313 sau, mai degrabă, același circuit este pur și simplu implementat pentru a funcționa pe aceste două microcontrolere. Apropo, în arhivă veți găsi două versiuni de firmware pentru microcontrolerul Atmega8, dintre care prima reproduce un sunet similar cu alarma auto, iar al doilea sunet este similar cu o alarmă de securitate a clădirii (semnal rapid și ascuțit).

    Puteți descărca tot firmware-ul de mai jos în arhivă (toți sunt semnați), în arhivă veți găsi și o simulare de circuite în Proteus, ceea ce înseamnă că după ce ascultați toate melodiile puteți alege din listă ce vă place cel mai mult .

    Mai jos este diagrama de semnalizare pentru Atmega8

    Lista componentelor radio utilizate în circuitul Atmega8

    U1- Microcontroler AVR ATmega8-16PU pe 8 biți, cantitate 1,
    R1- Rezistor cu o valoare nominală de 47 Ohmi, nr. 1,
    R2, R3 - Rezistor cu o valoare nominală de 270 Ohmi, nr. 2,
    D2,D3-LED, nr. 2,
    Difuzor LS1, nr. 1,
    S1-senzor.

    Și în circuitul de semnalizare de pe Attiny2313, doar MK a fost schimbat.
    U1- Microcontroller AVR 8-bit ATtiny2313-20PU, nr. 1.

    Placă de circuit imprimat pentru Atmega8 arată astfel:

    După cum puteți vedea, circuitul este foarte simplu, există doar un microcontroler, 3 rezistențe, 2 LED-uri și încă un difuzor. În loc de un buton, puteți folosi un comutator lamelă sau alt contact.

    Principiul de funcționare este următorul. De îndată ce aplicăm alimentarea, LED-ul (în circuitul D3) se aprinde imediat sau începe să clipească (în funcție de firmware), iar dacă nu atingem senzorul, alarma va fi silențioasă. Acum, dacă senzorul este declanșat, va funcționa și sirena, și LED-ul va clipi, dar D2.

    Dacă doriți ca farurile mașinii să clipească când alarma funcționează, atunci pentru a face acest lucru trebuie să conectați pinul microcontrolerului 24 PC1 la releu printr-un tranzistor și releul însuși la faruri. Pentru a opri sirena, trebuie să opriți și să porniți din nou dispozitivul sau pur și simplu să apăsați butonul. Pentru a opera microcontrolerul, aveți nevoie de un oscilator intern de 8 MHz,

    Dacă doriți să îmbunătățiți cumva sunetul alarmei, puteți asambla un amplificator cu tranzistori și îl puteți conecta la circuit. Exact asta am făcut, dar nu l-am descris în această diagramă.

    Să trecem la circuitul de pe Attiny 2313, așa cum am spus mai devreme, are toate aceleași detalii și același principiu de funcționare, doar MK-ul a fost schimbat și, ca urmare, pinii conectați.Acest microcontroler funcționează de la un oscilator intern de 4 MHz, deși poate fi flash la 1 MHz.

    Mai jos este diagrama de conectare deja pe Attiny2313

    Pentru acest MK am scris o singură versiune a firmware-ului, am asamblat totul pe placa de circuit, l-am verificat, totul funcționează bine.
    Și siguranțele trebuie setate așa cum se arată mai jos:





Top