This shows you the differences between two versions of the page.
| en:examples:digi:sound [2015/03/26 17:32] – created heikopikner | en:examples:digi:sound [2026/02/19 11:30] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | < | ||
| + | ====== Sound generator ====== | ||
| + | //Required knowledge: | ||
| + | [HW][[et: | ||
| + | [AVR][[et: | ||
| + | [LIB][[et: | ||
| + | |||
| + | ===== Theory ===== | ||
| + | |||
| + | [{{ : | ||
| + | [{{ : | ||
| + | |||
| + | One practical use of timers is driving a sounder or a speaker. Sounders are often used in control panels, alarm devices, and elsewhere to make button presses or signal tones audible. Such a sounder is often simply called a speaker, a beeper, or a //buzzer//. | ||
| + | By operating principle, sounders can be divided into piezoelectric and electromagnetic. | ||
| + | |||
| + | A piezoelectric sounder consists of a metal plate with a piezoceramic element attached. The piezoceramic element changes its dimensions according to the applied voltage, causing the metal plate to bend. Applying a square wave or AC signal produces vibration and thus sound. | ||
| + | |||
| + | An electromagnetic sounder is similar in principle to a loudspeaker. A coil is placed in a magnetic field with a metal diaphragm above it. When audio-frequency current flows through the coil, the diaphragm moves due to the magnetic fields of the coil and permanent magnet. Like the piezoelectric sounder, this produces sound. | ||
| + | |||
| + | In general, piezoelectric sounders have higher sound pressure, lower current consumption, | ||
| + | |||
| + | To drive speakers, a digital output is usually not enough; you need an analog signal. The easiest way is to use a digital-to-analog converter (DAC). A DAC works opposite to an ADC and allows a microcontroller to generate an analog output. Cheaper and simpler microcontrollers (including ATmega128 and ATmega2560) do not have an integrated DAC. In that case you can use an external chip or generate an analog signal using an RC filter and amplification circuitry. This requires additional components and therefore makes using a speaker with a microcontroller more complex compared to other digital components (switches, LEDs, sensors, etc.). | ||
| + | |||
| + | < | ||
| + | ===== Practice ===== | ||
| + | |||
| + | The HomeLab II User Interface module includes a piezo sounder with an amplifier circuit. The sounder is driven by pin PG5. | ||
| + | To use the sounder, the HomeLab library provides the function // | ||
| + | |||
| + | <code c> | ||
| + | // Generate a sound signal with selected frequency and length | ||
| + | void buzzer_sound (unsigned char freq, unsigned int length) | ||
| + | { | ||
| + | // Select the sounder pin | ||
| + | pin buzzer = PIN(G,5); | ||
| + | |||
| + | // Configure the sounder pin as output | ||
| + | pin_setup_output(buzzer); | ||
| + | |||
| + | // Timer 0 fast PWM mode with OCR0A and COM0B1 output | ||
| + | TCCR0A |= (1 << COM0B1); | ||
| + | TCCR0A |= ((1 << WGM01)|(1 << WGM00)); | ||
| + | TCCR0B |= (1 << WGM02); | ||
| + | OCR0A = freq; | ||
| + | // Start Timer 0 with prescaler 1024 | ||
| + | TCCR0B |= ((1 << CS02)|(1 << CS00)); | ||
| + | |||
| + | // Sound length | ||
| + | sw_delay_ms(length); | ||
| + | |||
| + | // Stop timer and sound generation | ||
| + | timer0_stop(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The HomeLab III User Interface module includes a speaker with a simple amplifier connected to controller DAC1 channel 1. | ||
| + | |||
| + | To use the speaker, the HomeLab library function // | ||
| + | |||
| + | With an Xmega controller, a software PWM signal is generated to drive the DAC module output between 0 V and the voltage level specified by // | ||
| + | |||
| + | <code c> | ||
| + | // Timer E0 overflow interrupt | ||
| + | ISR(TCE0_OVF_vect) | ||
| + | { | ||
| + | static uint8_t CH1_Output = 0; | ||
| + | |||
| + | if( CH1_Output == 1) | ||
| + | { | ||
| + | // Set output voltage according to volume = 1 | ||
| + | DAC_Channel_Write( &DACB, volume, CH1); | ||
| + | CH1_Output = 0; | ||
| + | } | ||
| + | |||
| + | else | ||
| + | { | ||
| + | // Set output voltage to 0 V | ||
| + | DAC_Channel_Write( &DACB, 0, CH1); | ||
| + | CH1_Output = 1; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Generate sound with frequency freq (8 Hz - 500 kHz) and length length (ms) | ||
| + | // if length = 0, sound is generated continuously | ||
| + | void buzzer_sound (uint16_t freq, unsigned int length) | ||
| + | { | ||
| + | // DAC setup | ||
| + | // AVCC as DAC reference | ||
| + | DACB.CTRLC = ( DACB.CTRLC & ~DAC_REFSEL_gm) | DAC_REFSEL_AVCC_gc; | ||
| + | // Select channel | ||
| + | DACB.CTRLB = ( DACB.CTRLB & ~DAC_CHSEL_gm ) | DAC_CHSEL_DUAL_gc; | ||
| + | // Enable channel 1 and DACB module | ||
| + | DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm; | ||
| + | |||
| + | // Timer E0 setup | ||
| + | // Enable overflow interrupt with medium priority | ||
| + | TCE0.INTCTRLA = ( TCE0.INTCTRLA & ~TC0_OVFINTLVL_gm ) | TC_OVFINTLVL_MED_gc; | ||
| + | // Set Timer E0 frequency to 32 MHz/64 = 500 kHz | ||
| + | TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV64_gc; | ||
| + | // Enable medium-level interrupts | ||
| + | PMIC.CTRL |= PMIC_MEDLVLEN_bm; | ||
| + | sei(); | ||
| + | |||
| + | // Set timer frequency | ||
| + | TCE0.PER = (uint32_t)250000/ | ||
| + | |||
| + | // Check if timer should be stopped, and wait if needed | ||
| + | if(length) | ||
| + | { | ||
| + | sw_delay_ms(length); | ||
| + | TCE0.CTRLA = ( TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_OFF_gc; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The next example illustrates use of the sounder library. It generates a 500 millisecond beep. | ||
| + | <code c> | ||
| + | // HomeLab sounder usage example program | ||
| + | // Generate a 500 ms beep | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main (void) | ||
| + | { | ||
| + | // Set HomeLab III volume | ||
| + | buzzer_volume(1000); | ||
| + | |||
| + | // Generate 1 kHz tone for 0.5 s | ||
| + | buzzer_sound(1000, | ||
| + | } | ||
| + | </ | ||