Atmega8 zvana signāli. Vienkāršas skaņas sirēnas uz MK AVR. Izmantojot skaņas moduli

Rakstā ir aprakstīti mūzikas sintēzes principi AVR. Iekļautā programmatūra ļauj pārvērst jebkuru midi failu par avots C formātā AVR mikrokontrolleriem, lai pievienotu mūzikas fragmentu atskaņošanu gataviem uzlabojumiem. Tiek aplūkots programmatūras izmantošanas piemērs mūzikas kastē.

Pirmkārt, īss video par to, kā tas viss darbojas:

Ko programmatūra atļauj

Datora programmatūra ļauj iegūt CodeVision AVR C avotu, kas atskaņo atlasīto midi failu:

1. Savienojiet common\hxMidiPlayer.h, common\hxMidiPlayer.c ar savu projektu. Kopējiet veidnes ATMega8Example\melody.h, ATMega8Example\melody.c, ATMega8Example\hxMidiPlayer_config.h un izveidojiet savienojumu.
2. Palaidiet MidiToC.exe
3. Ielādējiet Midi failu.
4. Iestatiet atskaņotāju: iztveršanas biežumu, kanālu skaitu, viļņu formu utt. Programmatūra atskaņo melodiju tādā pašā veidā, kā atskaņos AVR.
5. Noklikšķiniet uz “Izveidot atskaņotāja konfigurāciju” un ielīmējiet avotu hxMidiPlayer_config.h.
6. Noklikšķiniet uz “Izveidot melodijas kodu” un ielīmējiet avotu melody.c
7. Mūsu projektā mēs ieviešam Player_Output() metodi, lai izvadītu skaņu caur PWM vai ārēju DAC.
8. Iestatiet taimeri uz Sampling rate un izsauciet Player_TimerFunc() no pārtraukuma.
9. Izsauciet Player_StartMelody(&s_melody, 0).

Melodija tiek atskaņota no taimera pārtraukuma. Tas nozīmē, ka atskaņošanas laikā mikrokontrolleris var veikt arī noderīgu darbu.

Kā tas strādā

Pārējā raksta daļā mēģināšu īsi paskaidrot, kā tas viss tiek īstenots. Diemžēl tas nebūs ļoti īss – materiālu ir daudz. Ja jūs neinteresē, varat nekavējoties doties uz sadaļām “Programmatūras apraksts” un “Atskaņotāja API”.

Kas ir mūzika

Mūzika ir dažādas frekvences un ilguma skaņu virkne. Skaņas pamatharmonikas frekvencei jāatbilst noteiktas nots frekvencei. Ja skaņu vibrācijas frekvence atšķiras no nošu frekvencēm, mums šķiet, ka mūziķis ir “noskaņots”.

Tabula. Piezīme frekvences, Hz.

Visas notis ir sadalītas oktāvās, 7 notis katrā + 5 pustoņi (melni taustiņi uz klavierēm). Blakus esošo oktāvu nošu frekvences atšķiras tieši 2 reizes.

Vienkāršākajā mūzikas atskaņotājā ir tabula ar melodijas nošu secību (notis + ilgums) un tabula ar nošu frekvencēm. Skaņas sintezēšanai tiek izmantots viens no taimera kanāliem, kas veido līkumu:

Diemžēl šādam primitīvam atskaņotājam ir fiksēta viļņu forma (kvadrātvilnis), kas nav īpaši līdzīga īstiem mūzikas instrumentiem, un vienlaikus var atskaņot tikai vienu noti.

Īsta melodija satur vismaz divas daļas (solo + bass), un, atskaņojot uz klavierēm, iepriekšējā nots joprojām turpina skanēt, kad sākusies nākamā. To ir viegli saprast, atceroties klavieru uzbūvi – katra nots atbilst atsevišķai stīgai. Mēs varam likt skanēt vairākām stīgām vienlaikus, palaižot roku pār taustiņiem.

Dažiem mikrokontrolleriem ir vairāki taimera kanāli, kurus var izmantot, lai vienlaikus atskaņotu vairākas notis. Taču parasti šie kanāli ir vērtīgs resurss, un nav ieteicams tos visus izmantot. Ja vien mēs, protams, negatavojam tikai mūzikas kastīti.
Kopumā, lai iegūtu polifoniju un dažādas mūzikas instrumentu skaņas, ir jāizmanto skaņas sintēze.

Skaņas sintēze uz AVR

hxMidiPlayer izmanto audio sintēzi un var atskaņot polifoniju ar dažādām viļņu formām. Atskaņotājs aprēķina izejas signāla amplitūdu taimera pārtraukumu apstrādātājā ar frekvenci 8-22 KHz (cik procesora jaudas pietiek; atkarīgs arī no viļņu formas un kanālu skaita).

Skaņas sintēzes principu var izskaidrot, izmantojot sinusoīdu sintēzes piemēru.

Ņemsim 64 izmēra tabulu, kuras katrā šūnā sinusa amplitūdas vērtības ir ierakstītas punktu indeksā * 2 * PI / 64 (viens periods):

Static const flash uint8_t s_sineTable[ 64 ] = ( 0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x9,0,0x9,0 0x95, 0x95, 0x95, 0x94 , 0x93, 0x93, 0x91, 0x90, 0x8F, 0x8D, 0x8C, 0x8A, 0x88, 0x86, 0x84, 0x82, 0x80, 0x7E, 0x7C, 0x7,0,0x7,0x7,0 0x71, 0x70, 0x6F, 0x6D, 0x6D, 0x6C, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6C, 0x6D, 0x6D, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x73, 0x74, 0x73, 0x74, 0x76,07,07,0x76,0x76;

128 (0x80) atbilst nullei, 255 (0xff) lielākajam pozitīvajam punktam, 0 lielākajam negatīvajam punktam.

Tagad pieņemsim, ka mēs izvadīsim vērtības no tabulas uz ārēju DAC taimera pārtraukumā, kas tiek izsaukts ar frekvenci 1000 Hz:

Statiskā uint8_t s_index = 0; // Timer1 izvades salīdzināšana Pārtraukšanas pakalpojuma rutīnas pārtraukums void timer1_compa_isr(void) ( SetDac(s_sineTable[ s_index]); if (s_index == 63) ( s_index = 0; ) else ( s_index++; ) )

Ko mēs rezultātā iegūsim? Iegūsim sinusoidālās svārstības ar frekvenci 1000/64 Hz.

Tagad palielināsim indeksu pārtraukumā nevis par 1, bet par diviem.
Acīmredzot izejas svārstību frekvence jau būs 1000/64 * 2 Hz.

Kopumā, lai iegūtu frekvenci F, tabulā ir jāpalielina indekss:
pievienot = F / 1000 * 64

Šis skaitlis var būt daļskaitlis, bet, lai iegūtu lielu ātrumu, tiek izmantota fiksētā punkta aritmētika.

Ierakstu skaits tabulā un taimera frekvence ietekmē sintezētās skaņas kvalitāti. Mūsu gadījumā pietiek ar 64 ierakstiem tabulā vienā periodā, un taimera frekvence ir 12kHz. Minimālā pieļaujamā taimera frekvence ir 8 kHz, ideālā ir 44 kHz.

Acīmredzot ar taimera frekvenci 12 kHz mēs varam ģenerēt ne vairāk kā 6 kHz kvadrātveida viļņus, jo mums ir jāveic vismaz divi slēdži katrā periodā. Tomēr augstākas frekvences joprojām būs atpazīstamas, ja izvades stāvoklis ir pareizi aprēķināts katrā taimera atzīmēšanas reizē.

Tabulā varat ievadīt vērtības nesinusoidālo svārstību periodam un iegūt atšķirīgu skaņu.

Vājināšanās

Ja mūzikas instrumenta pamatā ir stīgas (piemēram, klavieres), tad pēc taustiņa nospiešanas skaņa vienmērīgi izdziest. Lai iegūtu dabiskāku sintezatora skaņu, pēc nots sākuma vienmērīgi jāsamazina vibrāciju amplitūda (vibrācijas “ietīt” vājinājuma formā – “aploksnē”).

Spēlētājs satur samazinājuma tabulu, ko tas izmanto, lai samazinātu sinusa (vai citas viļņu formas) amplitūdu no nots sākuma brīža.
Šādā apvalkā “iesaiņots” “sinuss” atgādina mehāniskas mūzikas kastes skaņu.

Meander sintēze

Mehāniskā viļņa īpašā forma ļauj būtiski vienkāršot sintēzi. Tabulas šajā gadījumā netiek izmantotas. Pietiek, lai aprēķinātu, kādam stāvoklim (1 vai 0) jābūt izvadei noteiktā frekvencē pie pašreizējā taimera atzīmes. Tas tiek darīts, izmantojot veselu skaitļu aritmētiku, un tas darbojas ļoti ātri, kas izskaidro kvadrātviļņu izmantošanas popularitāti, lai atskaņotu melodijas 8 bitu televizora pierīcēs.

Piemērs: skaitītāja deklarēšana:

Statiskais uint16_t s_skaitītājs = 0;

kuru mēs palielināsim par 0x8000 katrā taimera pārtraukumā, un nozīmīgākais skaitītāja bits tiks izvadīts portā:

// Timer1 izvades salīdzināšana Pārtraukšanas pakalpojuma rutīnas pārtraukums void timer1_compa_isr(void) ( PORTA.0 = (s_counter >> 15) & 1; s_counter += 0x8000; )

Tā kā 0x8000 + 0x8000 = 0x10000, mainīgais s_counter pārplūst, 17. bits tiek atmests un mainīgajam tiek ierakstīts 0x0000.
Tādējādi ar taimera frekvenci 8KHz izeja būs 4KHz kvadrātveida vilnis.
Ja palielināsiet skaitītāju par 0x4000, jūs iegūsit 2KHz kvadrātveida vilni.

Parasti frekvenci F var iegūt, pievienojot:
pievienot = F / 8000 * 0x10000

Piemēram, lai iegūtu kvadrātveida vilni ar frekvenci 1234Hz, jāpievieno 0x277C. Faktiskais biežums nedaudz atšķirsies no dotā, jo mēs noapaļojam terminu līdz veselam skaitlim. Sintezatorā tas ir pieņemami.

Īstu instrumentu skaņu sintēze

Varat digitalizēt nots skaņu pirms klavierēm (izmantojot ADC, lai ar regulāriem intervāliem atmiņā saglabātu skaņas amplitūdas vērtības):
un pēc tam atskaņojiet skaņu (izmantojot DAC, lai regulāri izvadītu ierakstītās vērtības).

Kopumā, lai sintezētu bungas, ir jāieraksta bungu skaņas un jāatskaņo tās īstajā brīdī. 8 bitu konsolēs bungu skaņu vietā tiek izmantots “baltais troksnis”. “Baltā trokšņa” amplitūdas vērtības tiek iegūtas, izmantojot ģeneratoru nejauši skaitļi. Atmiņas izmaksas ir minimālas.
hxMidiPlayer bungu sintēzei izmanto “balto troksni”.

Kanālu sajaukšana

Skaņas amplitūda pie noteiktā taimera atzīmes tiek aprēķināta katram kanālam atsevišķi. Lai iegūtu galīgo amplitūdas vērtību, jums jāpievieno visu kanālu vērtības. Pareizi ir jākoriģē summa, jo uztvertais skaļums pakļaujas logaritmiskai atkarībai, taču tik vienkāršā sintezatorā būs jāiztiek ar vienkāršu saskaitīšanu. Tāpēc katra kanāla maksimālā amplitūda ir 255/N.

Skaņas izvadīšana no AVR

Pēc visu nepieciešamo aprēķinu veikšanas atskaņotājs saņem signāla līmeni, kas jāpārvērš analogā. Šiem nolūkiem varat izmantot ārējo DAC vai PWM.
Te gan jāatzīmē, ka abos gadījumos vēlams saņemto signālu filtrēt – noņemt augstfrekvences troksni, kas rodas sintēzes un noapaļošanas zemās frekvences dēļ.

Izeja uz ārējo paralēlo DAC

Tā kā nav jēgas izmantot precīzas DAC mikroshēmas, šādi projekti parasti iztiek ar R2R matricu:

Izmantojot šo shēmu, mēs vienkārši izvadām aprēķināto amplitūdu uz portu:

PORTB = paraugs;

Trūkumi:
1) ir arī R2R matricas izvade vājš signāls, analogā pastiprinātāja izmantošana ir obligāta;
2) nepieciešams izmantot vismaz 5 tapas (un vēlams 8);
Šī metode ir pamatota tikai tad, ja nav brīvu PWM kanālu.

(lai saglabātu tapas, varat izmantot ārējo ADC ar SPI interfeisu).

PWM

Ja ir brīvs PWM kanāls, tad vienkāršākais veids ir izmantot šo metodi.

PWM inicializācija (ATMega8):

// Timer/Counter 2 inicializācija // Pulksteņa avots: System Clock // Pulksteņa vērtība: 20000.000 kHz // Režīms: Fast PWM top=0xFF // OC2 izeja: Neapgriezts PWM ASSR=0x00; TCCR2=0x69; TCNT2=0x00; OCR2=0x00; Un parauga izvade: void Player_Output(uint8_t paraugs) (OC2 = paraugs.)

Parastā PWM izmantošanas prakse ietver izejas signāla izlīdzināšanu, izmantojot RC filtru:

Diemžēl pēc filtrēšanas signāls ir pārāk vājš, tāpēc skaļruņa pievienošanai ir jāizveido analogais pastiprinātājs.

Lai vienkāršotu shēmu, labāk ir palikt “digitālam” līdz pašam skaļrunim. Tā kā lēts skaļrunis joprojām nevar reproducēt frekvences, kas pārsniedz 30 kHz, tās nav jāfiltrē. Pats difuzors "izfiltrēs" augstās PWM frekvences.

Ja jums ir nepieciešams iegūt vairāk strāvas, varat izmantot tranzistora pastiprinātāju. R1 ir izvēlēts, lai nodrošinātu skaļrunim nepieciešamo strāvu.

Šādi varat savienot mazus skaļruņus no rotaļlietām:

Lielākiem skaļruņiem labāk ir montēt disku, izmantojot 2 tranzistorus, un uzstādīt LC filtru, lai noņemtu troksni:

Kondensators C1 kalpo, lai ierobežotu strāvu caur skaļruni, kad PWM nedarbojas. Arī sērijveida kondensatora iekļaušanas dēļ skaļruni sasniedz signāls, kas ir simetrisks par nulli. Tādējādi skaļruņa konuss pārvietosies attiecībā pret centrālo “atslābināto” pozīciju, kas pozitīvi ietekmē skaņas kvalitāti.
Šajā gadījumā tranzistori darbojas pārslēgšanas režīmā, tāpēc nav nepieciešams kompensēt bāzes nobīdi.

PWM, divu kontaktu savienojums

Pirmo divu ķēžu trūkums ir tāds, ka skaļrunim tiek piegādāta strāva vienā virzienā. Ja mainām strāvas virzienu, skaļumu var palielināt 2 reizes, nepārsniedzot pieļaujamo jaudu. Lai to izdarītu, skaļrunis ir savienots ar divām mikrokontrollera tapām - neapgrieztām un apgrieztām, piemēram, OC1A un /OC1A. Ja nav neapgrieztas izejas, varat izmantot otro kanālu apgrieztā režīmā (OC1B):

// Timer/Counter 1 inicializācija // Pulksteņa avots: System Clock // Pulksteņa vērtība: 24500 000 kHz // Režīms: Fast PWM top=0x00FF // OC1A izeja: Non-Inv. // OC1B izeja: apgriezta // Trokšņu slāpētājs: Izslēgts // Ievades tveršana uz krītošās malas // Timer1 pārplūdes pārtraukums: izslēgts // Ievades uztveršanas pārtraukums: izslēgts // Salīdzināt A atbilstības pārtraukums: izslēgts // Salīdzināt B atbilstības pārtraukums: izslēgts 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 paraugs) ( OCR1A = paraugs; OCR1B = paraugs; )

PWM, divas tapas, D klases pastiprinātājs

Piedāvāto ķēžu trūkums ir strāvas patēriņš klusuma laikā.
“Klusums” mums atbilst signāla līmenim 128, tas ir, PWM ar 50% pildījumu - strāva vienmēr plūst caur skaļruni!

Nedaudz mainot programmatūru, jūs varat iegūt diezgan jaudīgu programmatūras un aparatūras D klases pastiprinātāju:

Void Player_Output(uint8_t paraugs) ( if (sample >= 128) ( TCCR2=0x21; //normāls, notīrīt salīdzināšanas atbilstību TCCR2=0x21 | 0x80; //CLEAR OC2 PORTC.0 = 0; TCCR2=0x69; //non -inverting PWM OCR2 = (sample-128) * 2; ) else // if (sample< 128) { TCCR2=0x31; //normal, set on compare match TCCR2=0x31 | 0x80; //SET OC2 PORTC.0 = 1; TCCR2=0x79; //inverting PWM OCR2 = (128-sample) *2; } }

Šajā gadījumā viens tranzistoru pāris ir pievienots PWM izejai, otrais - parastajai digitālajai izejai.

Kā redzams no koda, signālu virs 128 mēs uzskatām par strāvu, kas vērsta vienā virzienā, un signālu zem 128 par strāvu, kas vērsta otrā virzienā. Pie 128 abas skaļruņa tapas ir savienotas ar vienu un to pašu barošanas avota tapu, un nav strāvas. Atkāpjoties no 128. līmeņa, PWM piepildījums palielinās, un caur skaļruni plūst atbilstošas ​​polaritātes strāva.

Svarīgs punkts realizācijā ir PWM izejas piespiedu pārslēgšana uz vēlamo stāvokli otrās (parastās digitālās) tapas (PORTC.0) pārslēgšanas brīdī. Rakstīšana OCR2 reģistrā tiek buferizēta, lai novērstu PWM traucējumus. Mums nekavējoties jāpārslēdz PWM izeja, negaidot perioda beigas.

Pēdējā shēma ir IMHO labākais risinājums vienkāršības, enerģijas taupīšanas un jaudas ziņā.

Skaņas izvade ar SquareWave viļņu formu

Sintezējot meanderu, tiek izmantoti vienkāršoti algoritmi.

Katrs kanāls (ieskaitot bungas) izvada 0 vai 1. Tādējādi 3 kanālu atskaņotājs izvada vērtības diapazonā no 0...3. Tāpēc, izmantojot PWM, izvades procedūra izskatās šādi:

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

Ja neizmantojat PWM, tad, lai izvadītu 3 kanālu melodiju, pietiek ar divām parastajām digitālajām izejām un 2 bitu R2R matricu.

MIDI formāts

Ja paskatās uz iegūto melodijas kodu, varat viegli redzēt, ka masīvs izmanto atkārtotus skaitļus no neliela diapazona. Tas ir saprotams: melodijā tiek izmantots ierobežots nošu skaits 1-2 oktāvu robežās, melodijas temps ir fiksēts - vienādi aizkaves, kanālu skaits ir robežās no 0..15.
Tas viss nozīmē, ka iegūto masīvu var ievērojami samazināt, pielietojot kaut kādu kompresijas algoritmu.
Algoritmi, piemēram, ZIP, nodrošina labu saspiešanu, bet arī prasa daudz atmiņas, lai darbotos (ZIP vārdnīca - 64Kb). Mēs varam izmantot ļoti vienkāršu saspiešanas metodi, kas praktiski neprasa atmiņu, kuras būtība ir šāda.

Vienā baitā visi skaitļi ir vienmērīgi sadalīti diapazonā no 0...255, un katrs skaitlis ir attēlots ar 8 bitiem. Mūsu gadījumā daži skaitļi ir daudz izplatītāki nekā citi. Ja kodējat bieži sastopamus skaitļus ar mazāku bitu skaitu un retāk sastopamos skaitļus ar vairāk, varat iegūt atmiņas pieaugumu.

Mēs izvēlamies fiksētu kodēšanas metodi: bitu 000 001 un 010 kombinācijas (garums - 3 biti) attēlos 3 visbiežāk sastopamos skaitļus. Bitu kombinācijas 0110, 0111 (garums – 4 biti) – nākamie 2 biežākie skaitļi utt.:

//000..010 - 0..2 //011 x 3..4 //100 xx 5..8 //101 xxx 9..16 //110 xxx 17..24 //111 tūlītēja

Kombinācija, kas sākas ar 111 (garums – 11 biti), iekodēs visus pārējos skaitļus.
Bitu kodēšanas metode var būt atšķirīga. Es izmēģināju vairākas metodes un izvēlējos šo, kas sniedz vislabākos rezultātus šādiem datiem.

Kompresijas procedūra izskatās šādi:
1. Aprēķiniet kopējo skaitļa X skaitu straumē, ja X = .
2. Kārtot, samazinot parādīšanās biežumu straumē.
3. Ņemiet pirmos 25 skaitļus. Tie tiks kodēti mazākos bitos.
4. Kodējiet ievades straumi.

Izvade ir 25 visbiežāk sastopamo skaitļu masīvs un bitu straume.
Šī saspiešana ļauj sasniegt 50% saspiešanu ar minimālām atmiņas un veiktspējas izmaksām. Diemžēl tas palielina atskaņotāja kodu, tāpēc saspiešana nav ieteicama īsām melodijām.

Piezīmju frekvences saglabāšana

Saglabāt visu piezīmju frekvences tabulā no atmiņas ir diezgan dārgi. Faktiski ir formula nots biežuma noteikšanai pēc tās midi skaitļa:

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

Bet dalītās jaudas aprēķināšana ir diezgan sarežģīta. Tā vietā atskaņotājs augšējā oktāvā saglabā 12 nošu frekvences. Nošu frekvences zemākajās oktāvās nosaka, samazinot frekvenci vēl 2^Y reizes, kur Y ir oktāvu skaits uz leju.

Kompresijas tālāka attīstība

Melodija bieži satur atkārtojošus fragmentus (“korus”, “pantus”). Atrodot atkārtojošos fragmentus un melodiju prezentējot fragmentu veidā, jūs varat samazināt melodiju vēl par 50%, gandrīz netērējot laiku RAM un produktivitāti. Es šādu algoritmu neieviesu, lai nesarežģītu projektu.

Programmatūras apraksts

Pārveidotāja programmas galvenais logs:

Poga Load Midi ļauj ielādēt midi failu. Programma nekavējoties sāk atskaņot failu ar pašlaik atlasītajiem parametriem, imitējot skaņu, kas būs aparatūrā.

Informācijas logā (4) tiek parādīts:
– Length – izvēlētā melodijas fragmenta garums ms;
– Max Active sintezatora kanāli – maksimālais vienlaicīgi aktīvo sintezatora kanālu skaits;
– Max active drum channels – maksimālais vienlaicīgi aktīvo sintezatora kanālu skaits, kas atveido “bungas”;
– Max aktīvās stereo piezīmes – maksimālais kanālu skaits, kas atskaņo vienu un to pašu noti (skatīt zemāk);
– Paredzamais lielums, baiti – melodijas lielums baitos. Režīmā “Pielāgots paraugs” lielums tiek parādīts kā A+B, kur A ir melodijas lielums, B ir izlases lielums. Spēlētāja koda lielums šeit nav norādīts.

Progresa logā tiek parādīta pašreizējā atskaņošanas pozīcija.
Varat noklikšķināt uz progresa joslas, lai sāktu atskaņošanu no norādītā punkta.
Ievades lodziņi kreisajā un labajā pusē ļauj norādīt melodijas fragmenta sākumu un beigas ms.

Sarkanā iezīme “Nav pietiekami daudz kanālu, lai atskaņotu melodiju” norāda, ka nav pietiekami daudz sintezatora kanālu, lai atskaņotu melodiju ar pašreizējiem iestatījumiem. Ja atskaņotājs neatrod bezmaksas kanālu, tas izslēdz vecāko noti. Daudzos gadījumos tas darbosies labi. Palielināt kanālu skaitu ir jēga tikai tad, ja melodija ausij skan nepareizi.

Iestatījumus var iedalīt atskaņotāja iestatījumos un midi failu apstrādes iestatījumos. Atskaņotājs varēs atskaņot iegūto melodijas kodu, ja atskaņotāja konfigurācija un melodijas kods tika izveidoti ar vienādiem atskaņotāja iestatījumiem. Turklāt atskaņotājs varēs atskaņot melodiju, kuras kods tika izveidots atskaņotājam ar mazāku (bet ne lielāku) kanālu skaitu.

Atskaņotāja aparatūras iestatījumos ietilpst:

– Sampling Rate – sintēzes frekvence. Maksimālo saplūšanas biežumu nosaka eksperimentāli. Pamatojoties uz Atmega 16MHz, varat sākt ar 12000 Hz atskaņotājam ar 6 kanāliem un palielināt to pēc vēlēšanās, līdz aparatūras atskaņotājā kļūst pamanāmi melodijas traucējumi. Maksimālā frekvence ir atkarīga no kanālu skaita, viļņu formas un pašas melodijas sarežģītības.

– Viļņu forma – viļņu forma:
– Kvadrātveida vilnis – meander;
– Sine – sinusa;
– Sine + Envelope – sinusa ar vājinājumu;
– Waveform * + Envelope – dažādas iespējas nesinusoidālajiem viļņiem ar un bez vājinājuma;
– Custom Sample – izmantojiet instrumenta paraugu.

Poga “Ielādēt paraugu” ļauj ielādēt paraugu no WAV faila. WAV failam ir jābūt PCM 8 bitu mono, 4173 Hz, C-5. Padoms: varat palielināt frekvenci un pazemināt noti, bet atskaņotāja iestatījumos mainīt augstumu. Formātu pārbaudes netiek veiktas – ja formāts atšķiras, skaņa netiks atskaņota pareizi.
Pitch – ļauj mainīt skaņas augstumu. Piemēram, lai atskaņotu par 1 oktāvu augstāk, jāiestata Pitch +12.

Izmantojiet saspiešanu – izmantojiet melodijas saspiešanu.
Iespējot bungu sintezatoru — iespējojiet bungu sintezatoru.

Atskaņotāja kanāli: sintezatora kanālu skaits (maksimālais nošu skaits, kas skanēs vienlaicīgi).

Midi failu apstrādes iestatījumos ietilpst:

Parasti šāda precīza regulēšana nav nepieciešama. Šos iestatījumus var atstāt kā noklusējuma iestatījumus.

Player API

Atskaņotāja ieviešana atrodas failos Common\hxMidiPlayer.c un Common\hxMidiPlayer.h. Šie faili ir jāiekļauj projektā. Tāpat jāizveido fails hxMidiPlayer_config.h, kurā jāievieto konfigurācija.
Atskaņotājs ir rakstīts C valodā bez montāžas ieliktņiem, kas ļauj ērti to portēt uz citiem mikrokontrolleriem.

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

Sāciet atskaņot melodiju. _delay iestata sākotnējo aizkavi pirms atskaņošanas, 255 vienības = 1 sekunde.

Void Player_Stop();

Pārtrauciet atskaņot melodiju.

Extern bool Player_IsPlaying();

Atgriež false, ja melodijas atskaņošana ir beigusies.

Extern void Player_WaitFinish();

Pagaidiet, līdz melodijas atskaņošana ir pabeigta.

Extern void Player_TimerFunc();

Šī funkcija ir jāizsauc taimera pārtraukumā ar konfigurācijā norādīto iztveršanas ātrumu. Kad melodijas atskaņošana ir beigusies, jums nav jāveic zvani.

Extern void Player_Output(uint8_t paraugs);

Jāievieš lietotājam. Spēlētājs izsauc, kad ir jāizvada nākamais paraugs.

Extern void Player_Started();

Jāievieš lietotājam. Izsauc, kad atskaņotājs sāk atskaņot melodiju. Var izmantot, lai konfigurētu taimera pārtraukumus.

Extern void Player_Finished();

Jāievieš lietotājam. Izsauc, kad spēlētājs ir beidzis atskaņot melodiju. Var izmantot, lai atspējotu taimera pārtraukumus vai sāktu atskaņot citu melodiju.

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

Ja piezīmju tabulai, sinusa tabulai un vājinājuma tabulai ir jāatrodas eeprom, šīs rindas ir jāatbrīvo no komentāriem failā hxMidiPlayer_config.h.

Projektu piemēri

ATMega644Example – projekts ATMega644, 25MHz, PWM izeja uz PB3.

Atmiņas prasības

Tabula. Atskaņotāja lielums un melodijas zibspuldzē.

*pievienojot atskaņotāju esošam netukšam projektam, koda izmērs būs mazāks

** nav pietiekami daudz kanālu normālai melodijas atskaņošanai

1. melodija: bach_minuet_in_g.mid, 35 sek
2. melodija: yiruma-river_flows_in_you.mid, 165 sek.
3. melodija: Francs Šūberts – Serenāde.vid., 217 sek

Kā redzat no tabulas, minimālajā konfigurācijā jūs varat izspiest diezgan garu melodiju pat ATTiny2313. Saspiešana var samazināt melodiju vairāk nekā divas reizes, bet atskaņotāja koda lielums palielinās par ~600 baitiem.

Sinusa un samazināšanās piezīmju tabulas var ievietot EEPROM, ietaupot attiecīgi aptuveni 16, 50 un 100 baitu zibatmiņas.

Izmantojot paraugu no wav faila, atskaņotāja koda lielumam jāpievieno izlases lielums baitos.

Lietošanas piemērs

Kā atskaņotāja izmantošanas piemēru apskatīsim mūzikas kastes izveides procesu.

Mēs ņemam gatavu MDF kasti:

Kā mikrokontrolleri ņemam ATTiny85 SO-8 pakotnē kā lētāko ar pietiekami lielu atmiņas apjomu. Mēs to pārtaktēsim līdz 27MHz, lai iegūtu 18KHz sintēzes frekvenci ar 4 Sine+Envelope kanāliem.

Pastiprinātājs būs D klases ar 4 tranzistoriem, lai taupītu baterijas.

Tranzistori darbojas komutācijas režīmā un var būt jebkura veida. Induktors L1 un kondensators C6 ir izvēlēti pēc garšas, lai iegūtu skaņu bez augstfrekvences trokšņiem. R1 un R2 var palielināt līdz 2K, lai samazinātu skaļumu un samazinātu skaļruņu atlēcienu.

Ierobežošanas slēdzis no diskdziņa der lieliski, it kā tas būtu īpaši izveidots kastītei (strādā, lai atvērtu - atverot vāku, dēlim tiek piegādāta strāva):

Programmaparatūras avoti atrodas ATTiny85MusicBox direktorijā.

8Kb der:
1) atskaņotājs: 18000Hz, 4 kanāli, Sine+Envelope, Pitch+12, kompresija, atskaņo melodijas pa vienai (pēdējā tiek saglabāta EEPROM)
2) Yiruma — upe plūst tevī
3) Francs Šūberts – Serenāde
4) P.I. Čaikovskis "Oktobris"

Rezultāts video:

Tālāka attīstība

Principā atskaņotāju var attīstīt tālāk, nogādājot to līdz pilnvērtīgam Midi vai MOD atskaņotājam. Es personīgi domāju, ka, lai iegūtu augstas kvalitātes melodiju, būtu vieglāk pievienot SD karti un atskaņot no tās jebkurus WAV failus ar daudz vairāk vislabākā kvalitāte nekā parasti ir iespējams iegūt ar programmatūras sintēzi. Un šāds atskaņotājs ir daudz vienkāršāks programmatūras un aparatūras ziņā. HxMidiPlayer niša jau gataviem projektiem pievieno labu skaņu, kad zibspuldzē ir palikušas pāris kājas un maz vietas. Tas ar šo uzdevumu tiek galā “lieliski” jau esošajā formā.

Es domāju, ka tas var aizvērt jautājumu par visu veidu mūzikas kastīšu/zvaniņu izveidi AVR :)

Nodarbības turpinājums prasīja ilgu laiku, kas ir saprotams, man bija jāapgūst darbs ar atmiņas kartēm un failiem FAT sistēma. Bet tomēr tas notika, nodarbība ir gatava - patiesībā Jaungada brīnums.

Lai rakstu nepārslogotu ar informāciju, wav faila formāta struktūru neaprakstīšu, informācijas meklētājos ir vairāk nekā pietiekami. Pietiek pateikt, ka, atverot failu ar kādu Hex redaktoru, tad pirmajos 44 baitos ir visa informācija par faila tipu, paraugu ņemšanas ātrumu, kanālu skaitu utt. Ja nepieciešams analizēt failu, izlasiet šo galvene, un jūs būsiet laimīgs.

Lietderīgās slodzes dati sākas ar 44 baitiem, kas būtībā satur sprieguma līmeņus, kas veido skaņu. Mēs jau runājām par sprieguma līmeņiem nodarbības pēdējā daļā. Tādējādi viss ir vienkārši, šīs darbības ir jāizvada skaļrunim ar faila iztveršanas frekvenci.

Kā fiziski likt skaļrunim satricināt? Šie sprieguma līmeņi ir jāizvada, izmantojot PWM, vai izmantojiet R2R. Jebkurā gadījumā tas ir ļoti vienkārši lietojams, izlasiet numuru, ievietojiet to OCR vai PORTx. Pēc tam pēc noteikta laika es aizstāju nākamo vērtību un tā tālāk līdz faila beigām.

Piemērs, noteikts wav fails, dati nāk no baitiem 44=0x2C, tur rakstīts cipars 0x80, atveidojam skaņu, piemēram, ar pirmā taimera PWM, rakstām OCR1A=0x80; Pieņemsim, ka paraugu ņemšanas frekvence ir 8 kHz, tāpēc pārtraukumam jābūt iestatītam uz tādu pašu frekvenci. Pārtraukumā aizstājiet nākamo vērtību 0x85 pēc 1/8000 = 125 µs.

Kā iestatīt pārtraukumu uz 8 kHz? Atcerēsimies, ja taimeris darbojas ar frekvenci 250 kHz, tad pārtraukumu salīdzināšanas reģistrs ir jāaizstāj (250/8)-1=31-1 vai 0x1E. Ar PWM viss ir arī vienkārši; jo augstāka ir tā darbības frekvence, jo labāk.

Lai programmaparatūra darbotos, vienosimies, ka zibatmiņas disks ir formatēts FAT32, izmantojot PetitFat lib no 23.2 nodarbības. Fails ir wav formātā, 8kHz vai 22.050kHz, mono. Faila nosaukums 1.wav. Analizēsim programmaparatūru.

#iekļauts #include "diskio.h" #include "pff.h" unsigned char buffer[ 512 ] ; /* buferis, kurā informācija tiek kopēta no zibatmiņas diska */ gaistošs unsigned int skaits; //nokopēts datu skaitītājs pārtraukt [TIM2_COMP] void timer2_comp_isr(void) //pārtraukums, kurā vērtības tiek aizstātas( OCR1A = buferis[ skaits] ; // izvada skaņu skaļrunī ja (++ skaits >= 512 ) //palielināt skaitītāju skaits = 0; //ja 512 ir atiestatīts) void main(void) ( unsigned int br; /* failu lasīšanas/rakstīšanas skaitītājs */ neparakstīts char buf = 0 ; //mainīgais, kas nosaka, kura bufera daļa tiek nolasīta FATFS fs; /* Darbvieta (failu sistēmas objekts) loģiskajiem diskdziņiem */ PORTB= 0x00; DDRB= 0x02; //lēkt shim ocr1a // Taimera/skaitītāja 1 inicializācija// Pulksteņa avots: System Clock // Pulksteņa vērtība: 8000 000 kHz // Režīms: Fast PWM top=0x00FF // OC1A izeja: Non-Inv. TCCR1A= 0x81 ; TCCR1B= 0x09; TCNT1 = 0x00 ; OCR1A= 0x00 ; // Timer/Counter 2 inicializācija// Pulksteņa avots: System Clock // Pulksteņa vērtība: 250 000 kHz // Režīms: CTC top=OCR2 TCCR2= 0x0B ; TCNT2= 0x00 ; //OCR2=0x1E; // salīdzināšanas reģistra iestatīšana 8kHz OCR2 = 0xA ; //22kHz #asm("sei") // Taimera(-u)/skaitītāju(-i) Pārtraukuma(-u) inicializācija if (disk_initialize() == 0 ) //inicializējiet zibatmiņas disku( pf_mount(&fs) ; //mount failu sistēma pf_open("1.wav") ; //atver pavedienu pf_lseek(44) ; //pārvietojiet rādītāju uz 44 pf_read(buferis, 512 ,& br) ; //pirmo reizi norijam 512 baitus uzreiz TIMSK= 0x80 ; //ieslēdziet mūziku, kamēr (1) ( ja (! buf && count> 255 ) //ja tiek reproducēti vairāk nekā 255 baiti,( pf_read(& buferis[ 0 ], 256 ,& br) ; //tad mēs nolasām informāciju no zibatmiņas diska bufera pirmajā pusē buf=1; ja (br< 256 ) //ja buferis nesatur 256 vērtības, tas nozīmē faila beigas pārtraukums ; ) if (buf && count< 256 ) { pf_read(& buffer[ 256 ] , 256 ,& br) ; // lasīt bufera otrajā daļā no zibatmiņas diska buf = 0; ja (br< 256 ) break ; } } TIMSK = 0x00 ; //глушим все pf_mount(0x00 ) ; //nojaukt plīvuru) kamēr (1 ) ( ) )

#iekļauts #include "diskio.h" #include "pff.h" unsigned char buffer; /* buferis, kurā tiek kopēta informācija no zibatmiņas diska */ gaistošs unsigned int count; //nokopēto datu pārtraukuma skaitītājs void timer2_comp_isr(void) //pārtraukums, kurā vērtības tiek aizstātas ( OCR1A = buferis; //izvada skaņu skaļrunī, ja (++count >= 512) //palielināt skaitītāju skaitu = 0; //ja 512 atiestatīts ) void main(void) ( unsigned int br; /* faila lasīšanas/rakstīšanas skaitītājs */ neparakstīts char buf = 0; //mainīgais, kas nosaka, kura bufera daļa tiek lasīta FATFS fs; /* Darbojas apgabals (failu sistēmas objekts) loģiskajiem diskdziņiem */ PORTB=0x00; DDRB=0x02; //pārlēkt shim ocr1a // Timer/Counter 1 inicializācija // Pulksteņa avots: System Clock // Pulksteņa vērtība: 8000 000 kHz // Režīms: Fast PWM top=0x00FF // OC1A izeja: bez ieejas TCCR1A=0x81; TCCR1B=0x09; TCNT1=0x00; OCR1A=0x00; // Timer/Counter 2 inicializācija // Pulksteņa avots: sistēmas pulkstenis // Pulksteņa vērtība : 250 000 kHz // Režīms: CTC top= OCR2 TCCR2=0x0B; TCNT2=0x00; //OCR2=0x1E; //salīdzināšanas reģistra iestatīšana 8kHz OCR2=0xA; //22kHz #asm("sei") // Taimeris(-i)/skaitītājs(-i) Pārtraukt(-u) inicializāciju if(disk_initialize()==0) //inicializēt zibatmiņas disku ( pf_mount(&fs); //pievienojiet failu sistēmu pf_open("1.wav"); //atver filiāli pf_lseek(44); //pārvietot rādītāju uz 44 pf_read(buffer, 512,&br); //pirmo reizi norijam 512 baitus uzreiz TIMSK=0x80; //ieslēdziet mūziku while(1) ( if(!buf && count>255) //ja ir atskaņoti vairāk nekā 255 baiti, ( pf_read(&buffer, 256,&br);//pēc tam nolasiet informāciju no zibatmiņas iebraukt bufera pirmajā pusē buf=1 ; if (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) { } }

Lai pārbaudītu, mēs savienojam skaļruni ar OCR1A kontaktu, izmantojot 100 uF kondensatoru, “+” ar mikrokontrollera tapu, “-” ar skaļruni. “-” skaļrunis pret zemi, “+” pret kondensatoru.

Negaidiet skaļu signālu pie izejas; jums ir nepieciešams pastiprinātājs, lai skanētu skaļi. Tas ir skaidri redzams videoklipā. Pārbaudei gailīti ielādēju ar 8 kHz un trasi ar 22 kHz.

Tie, kas vēlas, var droši palielināt taimera2 frekvenci, lai atskaņotu 44 kHz failus, eksperimenti liecina, ka var sasniegt diezgan labu skaņas kvalitāti. Videoklipā skaņa vāja un kvalitāte slikta, bet patiesībā tas ir tāpēc, ka filmēju ar kameru.

Es arī ievietoju materiālus, kurus laipni nodrošina Apparatchik - GCC avota kodu, no kura tika rakstīta CAVR programmaparatūra.

Un video ar 44kHz atskaņošanu.

Es izmantoju šo iespēju, lai apsveiktu visus ar Jauno gadu, novēlu, lai visa programmaparatūra un ierīces darbojas jūsu labā :)

wav atskaņotāja projekts vietnē Atmega8

Es uzrakstīju programmatūras moduli, kas ļauj gandrīz jebkuram AVR mikrokontrollera projektam pievienot melodiju vai skaņu secību atskaņošanas funkciju.

Moduļa funkcijas:

Viegla integrācija ar gatavu projektu

Tiek izmantots tikai 8 bitu taimeris t2, bet joprojām ir iespējams to izmantot aptaujai vai laika intervālu veidošanai

Modulis ir regulējams gandrīz jebkurai pulksteņa ģeneratora frekvencei

Nošu augstums ir norādīts kā simboliskas konstantes (C0, A2 utt.) vai hercos

Ilgums tiek norādīts standarta formā (ceturtdaļas, astotdaļas utt.) vai milisekundēs

Ir iespējams iestatīt melodijas atskaņošanas tempu un atkārtojumu skaitu

Atskaņošanas laikā melodiju var apturēt


Skaņas moduļa pievienošana

1. Kopējiet visus moduļa failus (tone.h, sound.h, sound.c) projekta mapē.

2. Savienojiet failu sound.c ar projektu.

IAR a — ar peles labo pogu noklikšķiniet darbvietas logā un atlasiet Pievienot > Pievienot failus…

Attiecībā uz WINAVR tas ir aptuveni vienāds, makefile ir jāpievieno tikai sound.c:

SRC = $(MĒRĶIS).c sound.c

3. Iekļaujiet galvenes failu sound.h attiecīgajā modulī. Piemēram, galvenajā.c

#include "sound.h"

4. Iestatiet moduļa iestatījumus failā sound.h

//ja komentēsi, piezīmju ilgums būs

//aprēķināts no melodijā norādītā BPM

//ja pa kreisi, tad no tālāk norādītās vērtības

//#define SOUND_BPM 24

//pulksteņa frekvence μ

#define SOUND_F_CPU 16U

// mikrokontrollera izeja, uz kuras tiks ģenerēta skaņa

#define PORT_SOUND PORTB

#define PINX_SOUND 0

//norādīto melodiju skaits.

#define SOUND_AMOUNT_MELODY 4

5. Pievienojiet melodijas failam sound.c un ierakstiet melodiju nosaukumus melodiju masīvā.

Zvana signālu pievienošana

Melodija ir 16 bitu skaitļu masīvs, un tai ir šāda struktūra

BPM (ceturtdaļa notis minūtē) ir konstante, ko izmanto, lai aprēķinātu nošu ilgumu, un nosaka melodijas atskaņošanas ātrumu.

BPM var svārstīties no 1 līdz 24, kas atbilst attiecīgi 10 un 240 ceturtdaļas notīm minūtē.

Ja nošu/skaņu ilgums ir norādīts milisekundēs, tad masīvā ierakstītajam BPM jābūt vienādam ar 1.

Ja SOUND_BPM konstante ir komentēta galvenes failā sound.h, tad piezīmju ilgums tiek aprēķināts programmas izpildes laikā atbilstoši masīvā norādītajam BPM. Ja SOUND_BPM netiek komentēts, nošu ilgums tiek aprēķināts kompilācijas stadijā, pamatojoties uz šīs konstantes vērtību, un visas melodijas tiks atskaņotas tādā pašā tempā. Tas ierobežo funkcionalitāti, bet ietaupa dažus baitus koda.

Atkārtojumu skaits. Var ņemt vērtības 1 ... 254 un LOOP (255). LOOP - nozīmē, ka melodija atkārtosies bezgalīgi, līdz tiks dota komanda SOUND_STOP vai SOUND_PAUSE.

Piezīmes ilgums– laiks, kurā tiek ģenerēts dotais skaņas tonis vai tiek uzturēta pauze. Var norādīt ms, izmantojot makro ms(x), vai kā standarta piezīmju vērtības - astotās notis, sešpadsmitās notis utt. Tālāk ir sniegts atbalstīto ilgumu saraksts. Ja ir nepieciešami daži eksotiski ilgumi, tos vienmēr varat pievienot failā tone.h

n1 - visa nots

n2 - pusnotis

n4 - ceturksnis

n8 - astotais

n3 - astotais triplets

n16 - sešpadsmitais

n6 - sekstole

n32 - trīsdesmit otrais

Piezīme piķis tiek norādīts, izmantojot simboliskās konstantes, kas aprakstītas failā tone.h, piemēram, C2, A1 utt. Arī nošu augstumu var norādīt hercos, izmantojot makro f(x).

Programmai ir ierobežojumi minimālajai un maksimālajai skaņas frekvencei!

Melodijas beigu marķieris. Masīva pēdējā elementa vērtībai jābūt nullei.

Izmantojot skaņas moduli

Main sākumā jums ir jāizsauc funkcija SOUND_Init(). Šī funkcija iestata mikrokontrollera izvades tapu, konfigurē taimeri T2 un inicializē moduļa mainīgos.

Pēc tam jāiestata pārtraukuma iespējošana karodziņš - __enable_interrupt(), jo modulis izmanto T2 taimera pārpildes un sakritības pārtraukumus.

Pēc tam jūs varat sākt atskaņot melodijas.

Piemēram, šādi:

SOUND_SetSong(2);

SKAŅA_Com(SKAŅAS_ATSKAŅOŠANA); //spēlē melodiju

//iestatiet rādītāju uz 2. melodiju

//un sāciet atskaņošanu

SOUND_PlaySong(2);

Melodijas atskaņošanu var apturēt jebkurā laikā, izdodot komandu SOUND_STOP.
Varat arī apturēt melodiju, izmantojot komandu SOUND_PAUSE. Sekojoša komandas SOUND_PLAY izdošana atsāk melodijas atskaņošanu no vietas, kur tā tika apturēta.

Principā šī funkcionalitāte nav īpaši vajadzīga (es tikko izdomāju) un, strādājot ar moduli, pietiek ar funkciju SOUND_PlaySong(unsigned char numSong);

Faili

Skaņas moduļa izmantošanas piemērus varat lejupielādēt no tālāk esošajām saitēm. Es nezīmēju diagrammu, jo tur viss ir vienkārši. savienots ar tapu PB0, melodiju palaišanas poga ir savienota ar kontaktu PD3. Projektos ir definētas 4 melodijas. Nospiežot pogu, katru reizi tiek sākta jauna melodija. Tiek izmantots mikrokontrolleris atmega8535. Sākotnēji gribēju pamocīt ar projektu ar četrām pogām - PLAY, STOP, PAUSE un NEXT, bet tad likās, ka tas ir lieki.

PS: modulim nav veikta plaša pārbaude, un tas tiek nodrošināts "tāds, kāds ir". Ja ir kādi racionāli priekšlikumi, pabeigsim to līdz galam.

Šajā rakstā mēs apskatīsim, kā atskaņot toņus, un iemācīsimies atskaņot monofonisku melodiju.

Gatavošanās darbam

Programma deklarē divus masīvus. Masīvs ar piezīmēm piezīmes satur vienkāršu piezīmju sarakstu. Šīs notis tiek saskaņotas ar skaņas ilgumu masīvā sitieniem. Ilgumu mūzikā nosaka nots dalītājs attiecībā pret visu noti. Vērtība, kas ņemta kā vesela piezīme, ir 255 . Puses, ceturtdaļas, astotdaļas iegūst, dalot šo skaitli.
Lūdzu, ņemiet vērā, ka pirmās nots ilgums netiek iegūts, dalot 255 ar pakāpju divi. Šeit būs jāpāriet uz mūzikas teoriju. Oriģinālās melodijas notis var apskatīties. Šīs notis ir apvienotas trīskāršos. Šādi apvienojot, trīs astotās notis izklausās tāpat kā viena ceturtdaļnotis. Tāpēc to relatīvais ilgums ir 21.
Lietotājam ir arī skaidri jānorāda piezīmju skaits secībā ar direktīvu:

# definējiet SEQU_SIZE 19

Pamatprogrammā, pirmkārt, tiek pārrēķināti frekvenču masīvi un ilgums signālu periodos un nošu ilgums.
Ar signāla periodiem (masīvs signāla_periods) viss ir vienkārši. Lai iegūtu perioda ilgumu mikrosekundēs, vienkārši sadaliet 1 000 000 ar signāla frekvenci.
Lai aprēķinātu nošu skaņas absolūto ilgumu, ir jānorāda muzikālā darba temps. Tas tiek darīts pēc direktīvas

# definējiet TEMPO 108

Temps mūzikā ir ceturtdaļas nošu skaits minūtē. Rindā

# definējiet WHOLE_NOTE_DUR 240000 / TEMPO

Tiek aprēķināts veselas nots ilgums milisekundēs. Tagad pietiek pārrēķināt relatīvās vērtības no masīva, izmantojot formulu sitieniem uz absolūto masīvu note_duration.
Galvenajā cilpā mainīgais pagājušais_laiks tiek palielināts pēc katra atskaņotā signāla perioda par šī perioda ilgumu, līdz tas pārsniedz nots ilgumu. Ir vērts pievērst uzmanību šim ierakstam:

while(pagājušais_laiks< 1000 * ((uint32_t) note_duration[ i] ) )

Mainīgs pagājušais_laiks 32 bitu, un masīva elementi notes_duration 16 bitu. Ja 16 bitu skaitli reizina ar 1000, tiek garantēta pārpilde un mainīgais pagājušais_laiks tiks salīdzināts ar atkritumiem. Modifikators (uint32_t) pārvērš masīva elementu notes_duration[i] 32 bitu numurā nav pārpildes.
Audio cilpā varat redzēt citu funkciju. Funkciju nebūs iespējams izmantot _delay_us(), jo tā arguments nevar būt mainīgs.
Lai izveidotu šādas aizkaves, izmantojiet funkciju VarDelay_us(). Tajā cilpa ar 1 μs aizkavi tiek ritināta noteiktu skaitu reižu.

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

Atskaņojot melodiju, tiek izmantotas vēl divas aizkaves. Ja notis tiek atskaņotas bez pauzēm, tās saplūdīs vienā. Lai to izdarītu, starp tām tiek ievietota 1 ms aizkave, ko nosaka direktīva:

# definējiet NOTES_PAUSE 1

Pēc katra pilna melodijas atskaņošanas cikla programma aptur 1 s un atsāk atskaņošanu.
Rezultātā mēs saņēmām kodu, kurā ir viegli mainīt tempu, pielāgot ilgumu vai pilnībā pārrakstīt melodiju. Lai to izdarītu, pietiks tikai pārveidot tikai programmas daļu ar direktīvām un mainīgo deklarācijām.

Individuālie uzdevumi

  1. Piedāvātajā melodijā mēģiniet mainīt tempu un pauze starp atkārtojumiem 5 sekundes.
  2. Masīva elementi sitieniem pieņemt tikai vērtības no 0 līdz 255. Mainiet masīva elementu bitu platumu un skatiet kompilatora izvadi, lai redzētu, kā tas ietekmē programmas aizņemtās atmiņas apjomu.
  3. Tagad mēģiniet pats mainīt melodiju. Piemēram, šeit ir “Imperial March” no tās pašas filmas: 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 sitieni = ( 50 , 20 , 50 , 20 , 50 , 20 , 40 , 5 , 20 , 5 , 60 , 10 , 40 , 5 , 20 , 5 , 60 , 80 , 50, 5 20, 40, 5, 20

    Ja jūsu automašīnai nav uzstādīta skaņas sirēna un jūs joprojām nevarat izlemt, kuru iegādāties un uzstādīt, tad šis raksts ir tieši jums. Kāpēc pirkt dārgas signalizācijas, ja to visu var salikt pats diezgan vienkāršā veidā?

    Es piedāvāju divus no tiem vienkāršas shēmas uz AVR ATmega8 un Attiny2313 mikrokontrolleriem, vai drīzāk tā pati shēma ir vienkārši ieviesta, lai strādātu ar šiem diviem mikrokontrolleriem. Starp citu, arhīvā jūs atradīsit divas Atmega8 mikrokontrollera programmaparatūras versijas, no kurām pirmā atveido skaņu, kas līdzīga auto signalizācija, un otrā skaņa ir līdzīga ēkas apsardzes signalizācijai (ātrs un ass signāls).

    Jūs varat lejupielādēt visu zemāk esošo programmaparatūru arhīvā (tās visas ir parakstītas), arhīvā jūs atradīsit arī Proteus shēmu simulāciju, kas nozīmē, ka pēc visu melodiju noklausīšanās jūs varat izvēlēties no saraksta to, kas jums patīk vislabāk. .

    Zemāk ir Atmega8 signalizācijas diagramma

    Atmega8 ķēdē izmantoto radio komponentu saraksts

    U1- AVR mikrokontrolleris 8 bitu ATmega8-16PU, daudzums. 1,
    R1- Rezistors ar nominālo vērtību 47 omi, Nr. 1,
    R2, R3 - Rezistors ar nominālo vērtību 270 omi, Nr. 2,
    D2,D3-LED, Nr. 2,
    LS1 skaļrunis, Nr. 1,
    S1-sensors.

    Un Attiny2313 signalizācijas ķēdē ir mainīts tikai MK.
    U1- Mikrokontrolleris AVR 8-bit ATtiny2313-20PU, daudzums. 1.

    Iespiedshēmas plate Atmega8 izskatās šādi:

    Kā redzat, shēma ir ļoti vienkārša, ir tikai viens mikrokontrolleris, 3 rezistori, 2 gaismas diodes un vēl viens skaļrunis. Pogas vietā varat izmantot niedru slēdzi vai citu kontaktu.

    Darbības princips ir šāds. Tiklīdz tiek ieslēgta strāva, gaismas diode (ķēdē D3) nekavējoties iedegas vai sāk mirgot (atkarībā no programmaparatūras), un, ja nepieskaramies sensoram, trauksmes signāls klusēs. Tagad, ja iedarbinās sensors, darbosies arī sirēna, mirgos arī LED, bet D2.

    Ja vēlaties, lai automašīnas priekšējie lukturi mirgo, kad darbojas trauksme, tad, lai to izdarītu, mikrokontrollera 24 PC1 kontakts ir jāpievieno relejam caur tranzistoru, bet pats relejs - ar priekšējiem lukturiem. Lai izslēgtu sirēnu, ierīce ir jāizslēdz un vēlreiz jāieslēdz vai vienkārši jānospiež poga. Lai darbinātu mikrokontrolleri, nepieciešams iekšējs 8 MHz oscilators,

    Ja vēlaties kaut kā uzlabot trauksmes skaņu, varat salikt pastiprinātāju ar tranzistoriem un savienot to ar ķēdi. Tieši to es darīju, bet es to neattēloju šajā diagrammā.

    Pāriesim pie Attiny 2313 shēmas, kā jau teicu iepriekš, tam ir visas tās pašas detaļas un tāds pats darbības princips, ir mainīts tikai MK, un rezultātā pievienotās tapas. Šis mikrokontrolleris darbojas no iekšējais 4 MHz oscilators, lai gan to var mirgot ar 1 MHz.

    Zemāk ir savienojuma shēma jau vietnē Attiny2313

    Šim MK es uzrakstīju tikai vienu programmaparatūras versiju, saliku visu uz shēmas plates, pārbaudīju, viss darbojas labi.
    Un drošinātāji ir jāiestata, kā parādīts zemāk:





Tops