This is an old revision of the document!


 

Heligeneraator

Teooria

Kodulabor II buzzer
Kodulabor III kõlar koos võimendiga

Taimerite üheks praktiliseks rakenduseks on heligeneraatori juhtimine. Heligeneraator on tihti kasutusel juhtpaneelides, alarmseadmetes ja mujal nupuvajutuste või signaalhelide kuuldavaks toomiseks. Sellist heligeneraatorit kutsutakse tihti lihtsalt kõlariks, piiksujaks, või siis buzzeriks, mis on üle võetud inglise keelest. Tööpõhimõttelt võib buzzerid jagada kaheks piesoelektrilisteks ja elektromagnetilisteks.

Piesoelektriline buzzer koosneb metallplaadist ja sellele kinnitatud piesokeraamilisest materjalist elemendist. Piesokeraamiline element muudab vastavalt pinge suurusele oma mõõtmeid. Selle tagajärjel metallplaat paindub. Rakendades buzzerile nelikantsignaali või vahelduvvoolu tekib võnkumine ehk heli.

Elektromagnetiline buzzer sarnaneb oma tööpõhimõttelt valjuhääldile. Ka siin on magnetväljas pool, mille kohale on paigutatud metallist membraan. Kui lasta helisageduslik vool läbi pooli, hakkab membraan tekkiva magnetvälja ja püsimagneti välja koosmõjul liikuma. Analoogselt piesoelektrilise buzzeriga tekib heli.

Üldiselt on piesoelektrilised buzzerid võrdluses elektromagnetilistega suurema helirõhu, väiksema voolutarbe ja kõrgema võimaliku helisagedusega. Kõige tugevama heli kõige väiksema voolutugevuse korral saab siis, kui buzzer töötab oma resonantssagedusel. Sellisel juhul on membraani amplituud kõige suurem.

Praktika Kodulabor III generatsiooni moodulitel

Kodulabori kasutajaliidese plaadil asub koos lihtsa võimendiga kõlar, mis on ühendatud kontrolleri DAC1 kanaliga 1.

Kõlari kasutamiseks on Kodulabori teegis olemas funktsioon buzzer_sound, mis toob kuuldavale valitud pikkuse ja sagedusega helisignaali. Helisadegus andtakse ette hertsides ning kestvus millisekundites. Lisaks on võimalik käsuga buzzer_volume muuta heli valjusust vahemikus 0-4095, mis on realiseeritud DACi amplituudiga.

XMega kontrolleriga kenereeritakse tarkvaraline PWM, millega juhitakse DAC mooduli pinge väljundit 0V ja volüümiga määratud pingenivoo vahel.

// Taimer E0 ületäituvuse katkestus
ISR(TCE0_OVF_vect)
{
	static uint8_t CH1_Output = 0;
 
	if( CH1_Output == 1)
	{
		// Sea väljundpinge vastavalt volüümile 1
		DAC_Channel_Write( &DACB, volume, CH1);
		CH1_Output = 0;
	}
	else
	{
		// Sea väljundpinge 0V
		DAC_Channel_Write( &DACB, 0, CH1);
		CH1_Output = 1;
	}
}
 
//
// Genereeri heli sagedusega freq (8Hz - 500kHz) ja pikkusega length (ms)
// kui length = 0, siis jäägi heli väljastama
//
void buzzer_sound (uint16_t freq, unsigned int length)
{
	// DAC seadistamine
	// AVCC Pingereferentsiks DAC moodulile
	DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc;
	// Vali kanalid
	DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_DUAL_gc;
	// Käivita kanal 1 ning DACB moodul
	DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm;
 
	// Taimeri E0 seadistamine
	// Luba ületäituvuse katkestus keskmise prioriteediga
	TCE0.INTCTRLA = ( TCE0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc;
	// Sea taimeri E0 sageduseks 32MHz/64 = 500kHz
	TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc;
	// Luba keskmise taseme katkestused
	PMIC.CTRL |= PMIC_MEDLVLEN_bm;
	sei();
 
	// Sea Taimeri tekitatav sagedus
	TCE0.PER = (uint32_t)250000/freq;
 
	// Kontrolli, kas on vaja taimer ka välja lülitada, ning vajadusel oota.
	if(length)
	{
		sw_delay_ms(length);
		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, mis toob kuuldavale valitud pikkuse ja sagedusega helisignaali. Heli sagedus antakse ette suhtelistes ühikutes 1-255. Heli kestvus on millisekundites.

//
// 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();
}

Järgmine näide illustreerib heligeneraatori teegi kasutamist. Kuuldavale tuuakse 500 millisekundi pikkune piiksatus.

#include <homelab/module/buzzer.h>
 
int main (void)
{
	buzzer_sound(50,500);
}

Muusika mängimiseks, kasutades noodistikku, on vaja teada iga heli sagedust. Järgmine näide õpetab ilma buzzer.h teeki kasutamata keerulisemate muusikapalade loomist. Kasutusel on taimer 0, mille ületäitumise korral tekib katkestus. Katkestuse funktsioonis on muutuja intrs, mida suurendatakse iga katkestuse täitmise korral. Samal ajal võrreldakse seda muutujat noodi sagedusest arvutatud ületäitumiste arvuga. Kui muutuja intrs ja noodi ületäitumiste arv on saanud võrdseks, siis inverteeritakse heligeneraatori viigu väärtus. Tekib ristkülikukujuline signaal, mille sagedus on määratud noodi sagedusega.

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, mitu taimeri ületäitumist leiab aset noodi kohta. Peale seda on uus noot kasutusvalmis.

Näiteprogramm mängib lühikese muusikapala peale nupu S1 vajutamist.

#include <homelab/pin.h>
#include <homelab/delay.h>
#include <homelab/timer2561.h>
#include <avr/interrupt.h>
 
 
// 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/F_FSH_4
#define A_4 INT_PER_SEC/F_A_4
#define B_4 INT_PER_SEC/F_B_4
#define E_4 INT_PER_SEC/F_E_4
#define CSH_5 INT_PER_SEC/F_CSH_5
#define D_5 INT_PER_SEC/F_D_5
#define FSH_5 INT_PER_SEC/F_FSH_5
#define CSH_4 INT_PER_SEC/F_CSH_4
#define GSH_4 INT_PER_SEC/F_GSH_4
 
#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 määramine
    pin_setup_output(buzzer);
 
    // 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);  
        }
 
        // Jätab eelmise nupu väärtuse meelde
        old_value1 = new_value1;        
    }
}
et/examples/digi/sound.1411989910.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0