Nagyjából az áramkörünk most sem lesz bonyolultabb. Szükségünk lesz egy kis piezo hangszóróra.
Egy kis videó a működéséről:
A videó megtekintéséhez Flash lejátszó szükséges!
Maga a kód:
#include <avr/io.h>
#include <util/delay.h>
//-------------------------------------
void m_delay_10ms(unsigned long val) {
//-------------------------------------
while(val--) _delay_ms(10);
}
//-------------------------------------
void do_delay(uint16_t ms_delay, uint16_t num_ms, uint16_t us_delay, uint16_t num_us) {
//-------------------------------------
uint16_t i;
for(i=0;i<num_ms;i++) _delay_ms(250);
for(i=0;i<ms_delay;i++) _delay_ms(1);
for(i=0;i<num_us;i++) _delay_us(250);
for(i=0;i<us_delay;i++) _delay_us(1);
}
//-------------------------------------
void generate_tone(uint16_t frequency, uint16_t duration)
//-------------------------------------
{
uint32_t total_delay_time;
uint16_t total_ms_delay_time, total_us_delay_time;
uint16_t num_us_delays, num_ms_delays, ms_delay_time, us_delay_time;
uint16_t num_periods;
total_delay_time = (1000000/frequency)/2-10;
total_ms_delay_time = total_delay_time/1000;
num_ms_delays = total_ms_delay_time/250;
ms_delay_time = total_ms_delay_time%250;
total_us_delay_time = total_delay_time%1000;
num_us_delays = total_us_delay_time/250;
us_delay_time = total_us_delay_time%250;
num_periods = ((uint32_t)duration*1000)/(1000000/frequency);
while((num_periods--) != 0)
{
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
PORTB |= (1<<PINB3);
do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
PORTB &= ~(1<<PINB3);
}
return;
}
//-------------------------------------
int main(void) {
//-------------------------------------
DDRB = (1<<PINB3)|(1<<PINB4); //csak a PB3 és a PB4 kimenet
while(1) {
generate_tone(1000,200);
generate_tone(1200,200);
generate_tone(1400,200);
generate_tone(1200,200);
generate_tone(1000,200);
if(PORTB & (1<<PINB4)) PORTB &= ~(1<<PINB4);
else PORTB |= (1<<PINB4);
m_delay_10ms(250); //100*10ms = 1s
}
return 0;
}
A lényeg annyi, hogy írtunk egy speciális időzítő rutint, és egy generate_tone függvényt. Ennek a függvénynek paraméterei: frekvencia, hossz ms-ben.
Mikor a függvény meghívásra kerül, rendkívül helypazarlón, de átláthatóan kiszámolja az időzítéseket, hogy a megadott frekvenciához és megadott hosszhoz hányszor kell lefutnia a ciklusnak. Nem a ciklusban számolunk, mert az befolyásolná a frekvenciát. Ugyanis a parancs végrehajtás is idő.
A kódból látszik, hogy kiadunk egy 1KHz-es 200ms hosszú hangot, majd egy ugyan ilyen hosszú 1,2KHz, 1,4KHz, újra 1,2KHz és végül újra egy 1KHz-es hangot. Ez a kis dallam "okozója".
Ha frekihez pl. 440Hz-et írsz (tehát 440) akkor szép zenei "A" hangot hallhatsz
Most pedig, a folytatásban közlekedjünk egy kicsit. Ez után a komolyabb feladatunk után, ez egy kis levezető.
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!