This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:examples:digi:sound [2014/09/29 11:24] – raivo.sell | et:examples:digi:sound [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ~~PB~~ | + | < |
| ====== Heligeneraator ====== | ====== Heligeneraator ====== | ||
| //Vajalikud teadmised: | //Vajalikud teadmised: | ||
| - | [HW][[et: | + | [HW][[et: |
| - | [AVR][[et: | + | [AVR][[et: |
| [LIB][[et: | [LIB][[et: | ||
| ===== Teooria ===== | ===== Teooria ===== | ||
| - | [{{ :et:examples:digi:homelab_buzzer.png?220|Kodulabor II buzzer}}] | + | [{{ :examples:sound:piezo.jpg?200|Piesoheligeneraator}}] |
| - | [{{ :et:examples:digi:speaker.jpg?220|Kodulabor III kõlar koos võimendiga}}] | + | [{{ :examples:sound:kingstate-kssg3108.jpg?200|Kõlar}}] |
| - | Taimerite üheks praktiliseks rakenduseks on heligeneraatori juhtimine. Heligeneraator on tihti kasutusel juhtpaneelides, | + | Taimerite üheks praktiliseks rakenduseks on heligeneraatori |
| - | Piesoelektriline | + | Piesoelektriline |
| - | Elektromagnetiline | + | Elektromagnetiline |
| - | Üldiselt on piesoelektrilised | + | Üldiselt on piesoelektrilised |
| - | ~~CL~~ | + | Kõlarite juhtimiseks ei piisa tavaliselt digitaalväljundist vaid vaja on analoogsignaali. Selleks on kõige mugavam rakendada digitaal-analoog muundurit (inglise keeles // |
| - | ~~PB~~ | + | |
| - | ===== Praktika | + | < |
| + | ===== Praktika ===== | ||
| - | Kodulabori kasutajaliidese plaadil | + | Kodulabor II Kasutajaliidese moodulil |
| + | Heligeneraatori kasutamiseks on Kodulabori teegis olemas funktsioon // | ||
| - | Kõlari kasutamiseks on Kodulabori teegis olemas funktsioon buzzer_sound, | + | <code c> |
| + | // Valitud sageduse | ||
| + | void buzzer_sound (unsigned char freq, unsigned int length) | ||
| + | { | ||
| + | // Heligeneraatori viigu määramine | ||
| + | pin buzzer = PIN(G,5); | ||
| - | XMega kontrolleriga | + | // Heligeneraatori viigu väljundiks seadistamine |
| + | pin_setup_output(buzzer); | ||
| + | |||
| + | // Timer 0 kiire PWM režiimi seadistamine koos OCR0A ja COM0B1 väljundiga | ||
| + | TCCR0A |= (1 << COM0B1); | ||
| + | TCCR0A |= ((1 << WGM01)|(1 << WGM00)); | ||
| + | TCCR0B |= (1 << WGM02); | ||
| + | OCR0A = freq; | ||
| + | // Timer 0 käivitamine koos jaguriga 1024 | ||
| + | TCCR0B |= ((1 << CS02)|(1 << CS00)); | ||
| + | |||
| + | // Heli pikkus | ||
| + | sw_delay_ms(length); | ||
| + | |||
| + | // Taimeri ehk heli genereerimise peatamine | ||
| + | timer0_stop(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Kodulabor III Kasutajaliidese moodulil asub koos lihtsa võimendiga kõlar, mis on ühendatud kontrolleri DAC1 kanaliga 1. | ||
| + | |||
| + | Kõlari kasutamiseks Kodulabori teegis olev funktsioon // | ||
| + | |||
| + | Xmega kontrolleriga | ||
| <code c> | <code c> | ||
| Line 38: | Line 67: | ||
| if( CH1_Output == 1) | if( CH1_Output == 1) | ||
| { | { | ||
| - | // Sea väljundpinge | + | // Väljundpinge määramine |
| DAC_Channel_Write( &DACB, volume, CH1); | DAC_Channel_Write( &DACB, volume, CH1); | ||
| CH1_Output = 0; | CH1_Output = 0; | ||
| } | } | ||
| + | |||
| else | else | ||
| { | { | ||
| - | // Sea väljundpinge 0V | + | // Väljundpinge määramine 0 V |
| DAC_Channel_Write( &DACB, 0, CH1); | DAC_Channel_Write( &DACB, 0, CH1); | ||
| CH1_Output = 1; | CH1_Output = 1; | ||
| Line 50: | Line 80: | ||
| } | } | ||
| - | // | + | // Genereeritakse |
| - | // Genereeri | + | // kui length = 0, siis jäädaksegi |
| - | // kui length = 0, siis jäägi | + | |
| - | // | + | |
| void buzzer_sound (uint16_t freq, unsigned int length) | void buzzer_sound (uint16_t freq, unsigned int length) | ||
| { | { | ||
| // DAC seadistamine | // DAC seadistamine | ||
| - | // AVCC Pingereferentsiks | + | // AVCC on pingereferentsiks |
| DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc; | DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc; | ||
| - | // Vali kanalid | + | // Kanali valimine |
| DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_DUAL_gc; | DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_DUAL_gc; | ||
| - | // Käivita kanal 1 ning DACB moodul | + | // Kanal 1 ning DACB mooduli käivitamine |
| DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm; | DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm; | ||
| // Taimeri E0 seadistamine | // Taimeri E0 seadistamine | ||
| - | // Luba ületäituvuse | + | // Ületäituvuse |
| TCE0.INTCTRLA = ( TCE0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc; | TCE0.INTCTRLA = ( TCE0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc; | ||
| - | // Sea taimeri | + | // Taimeri |
| TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc; | TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc; | ||
| - | // Luba keskmise | + | // Keskmise |
| PMIC.CTRL |= PMIC_MEDLVLEN_bm; | PMIC.CTRL |= PMIC_MEDLVLEN_bm; | ||
| sei(); | sei(); | ||
| - | // Sea Taimeri | + | // Taimeri |
| TCE0.PER = (uint32_t)250000/ | TCE0.PER = (uint32_t)250000/ | ||
| - | // Kontrolli, kas on vaja taimer | + | // Kontroll, kas on vaja taimer välja lülitada, ning vajadusel |
| if(length) | if(length) | ||
| { | { | ||
| Line 82: | Line 110: | ||
| TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc; | TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc; | ||
| } | } | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ===== Praktika Kodulabor II generatsiooni moodulitel ===== | ||
| - | |||
| - | Kodulabori kasutajaliidese plaadil asub piesoelektriline buzzer koos võimenduslülitusega. Heligeneraatorit juhitakse viiguga G5. | ||
| - | |||
| - | Heligeneraatori kasutamiseks on Kodulabori teegis olemas funktsioon buzzer_sound, | ||
| - | |||
| - | <code c> | ||
| - | |||
| - | // | ||
| - | // Valitud sageduse ja pikkusega helisignaali genereerimine. | ||
| - | // | ||
| - | void buzzer_sound (unsigned char freq, unsigned int length) | ||
| - | { | ||
| - | // Seadista heligeneraatori viik | ||
| - | pin buzzer = PIN(G,5); | ||
| - | |||
| - | // Seadista heligeneraatori viik väljundiks | ||
| - | pin_setup_output(buzzer); | ||
| - | |||
| - | // Seadista Timer 0 kiire PWM režiimi koos OCR0A ja COM0B1 väljundiga | ||
| - | TCCR0A |= (1 << COM0B1); | ||
| - | TCCR0A |= ((1 << WGM01)|(1 << WGM00)); | ||
| - | TCCR0B |= (1 << WGM02); | ||
| - | OCR0A = freq; | ||
| - | // Käivita Timer 0 koos preskaleriga 1024 | ||
| - | TCCR0B |= ((1 << CS02)|(1 << CS00)); | ||
| - | |||
| - | // Heli pikkus | ||
| - | sw_delay_ms(length); | ||
| - | |||
| - | // Peata taimer ehk heli genereerimine | ||
| - | timer0_stop(); | ||
| } | } | ||
| </ | </ | ||
| Line 122: | Line 115: | ||
| Järgmine näide illustreerib heligeneraatori teegi kasutamist. Kuuldavale tuuakse 500 millisekundi pikkune piiksatus. | Järgmine näide illustreerib heligeneraatori teegi kasutamist. Kuuldavale tuuakse 500 millisekundi pikkune piiksatus. | ||
| <code c> | <code c> | ||
| + | // Kodulabori heligeneraatori kasutamise näidisprogramm | ||
| + | // Genereeritakse 500 ms pikkune piiksatus | ||
| #include < | #include < | ||
| - | + | ||
| + | // Põhiprogramm | ||
| int main (void) | int main (void) | ||
| { | { | ||
| - | buzzer_sound(50, | + | // Kodulabor III helivaljususe |
| - | } | + | buzzer_volume(1000); |
| - | </code> | + | |
| - | + | ||
| - | Muusika mängimiseks, | + | |
| - | + | ||
| - | Uute nootide defineerimine on näiteprogrammis lihtne. Analoogselt olemasolevatele nootidele tuleb, kasutades //#define// direktiivi, kirjeldada uue noodi nimi. Noodi nime järele tuleb lisada noodi sagedus hertsides. Sammuti tuleb lisada definitsioon, | + | |
| - | + | ||
| - | Näiteprogramm mängib lühikese muusikapala peale nupu S1 vajutamist. | + | |
| - | + | ||
| - | <code c> | + | |
| - | #include < | + | |
| - | #include < | + | |
| - | #include < | + | |
| - | #include < | + | |
| - | + | ||
| - | + | ||
| - | // Timer0 ületäitumisi sekundis | + | |
| - | #define INT_PER_SEC 31250 | + | |
| - | + | ||
| - | // Nootide sagedused (Hz) | + | |
| - | #define F_FSH_4 370 | + | |
| - | #define F_A_4 440 | + | |
| - | #define F_B_4 494 | + | |
| - | #define F_E_4 330 | + | |
| - | #define F_CSH_5 554 | + | |
| - | #define F_D_5 587 | + | |
| - | #define F_FSH_5 740 | + | |
| - | #define F_CSH_4 277 | + | |
| - | #define F_GSH_4 415 | + | |
| - | + | ||
| - | // Timer0 ületäitumisi noodi kohta | + | |
| - | #define REST -1 // special case | + | |
| - | #define FSH_4 INT_PER_SEC/ | + | |
| - | #define A_4 INT_PER_SEC/ | + | |
| - | #define B_4 INT_PER_SEC/ | + | |
| - | #define E_4 INT_PER_SEC/ | + | |
| - | #define CSH_5 INT_PER_SEC/ | + | |
| - | #define D_5 INT_PER_SEC/ | + | |
| - | #define FSH_5 INT_PER_SEC/ | + | |
| - | #define CSH_4 INT_PER_SEC/ | + | |
| - | #define GSH_4 INT_PER_SEC/ | + | |
| - | + | ||
| - | #define SEMIQUAVER_TIME 60 // ms | + | |
| - | #define BREATH_TIME 20 // ms | + | |
| - | + | ||
| - | volatile uint32_t intrs = 0; | + | |
| - | volatile int32_t curNote = REST; | + | |
| - | + | ||
| - | + | ||
| - | // Nupu viik | + | |
| - | pin button1 = PIN(C, 0); | + | |
| - | + | ||
| - | // Heligeneraatori viik | + | |
| - | pin buzzer = PIN(G, 5); | + | |
| - | + | ||
| - | + | ||
| - | // Taimer 0 katkestuse programmilõik | + | |
| - | ISR(TIMER0_OVF_vect) | + | |
| - | { | + | |
| - | if (curNote == REST) | + | |
| - | { | + | |
| - | intrs = 0; | + | |
| - | } | + | |
| - | else | + | |
| - | { | + | |
| - | intrs++; | + | |
| - | if (intrs >= curNote) | + | |
| - | { | + | |
| - | pin_toggle(buzzer); | + | |
| - | + | ||
| - | intrs = 0; | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | // Mängi nooti etteantud aeg | + | |
| - | void play(int32_t note, uint32_t len) | + | |
| - | { | + | |
| - | int i; | + | |
| - | curNote = note; | + | |
| - | + | ||
| - | for (i = 0; i< len; i++) | + | |
| - | { | + | |
| - | sw_delay_ms(SEMIQUAVER_TIME); | + | |
| - | } | + | |
| - | + | ||
| - | curNote = REST; | + | |
| - | sw_delay_ms(BREATH_TIME); | + | |
| - | } | + | |
| - | + | ||
| - | int main(void) | + | |
| - | { | + | |
| - | + | ||
| - | unsigned char new_value1, old_value1 = 0; | + | |
| - | + | ||
| - | // Seab nupu töökorda | + | |
| - | pin_setup_input_with_pullup(button1); | + | |
| - | + | ||
| - | // Heligeneraatori viigu väljundiks | + | |
| - | | + | |
| - | + | ||
| - | // Taimer 0 normaalreziimi seadistamine. Selles reziimis loendab | + | |
| - | // taimer 255-ni (kaasa arvatud) ja ainuke tekkiv sündmus on ületäitumine. | + | |
| - | // Jagurit ei kasutata. | + | |
| - | timer0_init_normal(TIMER0_NO_PRESCALE); | + | |
| - | + | ||
| - | // Taimer 0 ületäitumise katkestuse lubamine | + | |
| - | timer0_overflow_interrupt_enable(true); | + | |
| - | + | ||
| - | // Taimer 0 väärtuse nullimine | + | |
| - | timer0_set_value(0); | + | |
| - | + | ||
| - | // Globaalne katkestuste lubamine | + | |
| - | sei(); | + | |
| - | + | ||
| - | while (1) | + | |
| - | { | + | |
| - | // Loeb nuppude väärtused. | + | |
| - | new_value1 = pin_get_debounced_value(button1); | + | |
| - | + | ||
| - | // Nupp S1 alla vajutatud. Registreeritakse ainult üks vajutus. | + | |
| - | if((!new_value1) && (old_value1)) | + | |
| - | { | + | |
| - | // Mängi järgnev lugu | + | |
| - | play(FSH_4, 2); | + | |
| - | play(REST, 2); | + | |
| - | play(A_4, 3); | + | |
| - | play(FSH_4, 2); | + | |
| - | play(FSH_4, 1); | + | |
| - | play(B_4, 2); | + | |
| - | play(FSH_4, 2); | + | |
| - | play(E_4, 2); | + | |
| - | play(FSH_4, 2); | + | |
| - | play(REST, 2); | + | |
| - | play(CSH_5, 3); | + | |
| - | play(FSH_4, 2); | + | |
| - | play(FSH_4, 1); | + | |
| - | play(D_5, 2); | + | |
| - | play(CSH_5, 2); | + | |
| - | play(A_4, 2); | + | |
| - | play(FSH_4, 2); | + | |
| - | play(CSH_5, 2); | + | |
| - | play(FSH_5, 2); | + | |
| - | play(FSH_4, 1); | + | |
| - | play(E_4, 2); | + | |
| - | play(E_4, 1); | + | |
| - | play(CSH_4, 2); | + | |
| - | play(GSH_4, 2); | + | |
| - | play(FSH_4, 6); | + | |
| - | play(REST, 12); | + | |
| - | + | ||
| - | // Viide | + | |
| - | sw_delay_ms(2); | + | |
| - | } | + | |
| - | | + | // 1 kHz 0,5 s pikkuse heli genereerimine |
| - | | + | buzzer_sound(1000, |
| - | } | + | |
| } | } | ||
| </ | </ | ||