Fórum témák

» Több friss téma
Cikkek » Nyolc lábbal AVR I. rész
Nyolc lábbal AVR I. rész
Szerző: Topi, idő: Aug 26, 2008, Olvasva: 77039, Oldal olvasási idő: kb. 1 perc
Lapozás: OK   5 / 7

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:

  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. //-------------------------------------
  5. void m_delay_10ms(unsigned long val) {
  6. //-------------------------------------
  7.     while(val--) _delay_ms(10);
  8. }
  9.  
  10. //-------------------------------------
  11. void do_delay(uint16_t ms_delay, uint16_t num_ms, uint16_t us_delay, uint16_t num_us)  {
  12. //-------------------------------------
  13.  uint16_t i;
  14.  
  15.  for(i=0;i<num_ms;i++) _delay_ms(250);
  16.  for(i=0;i<ms_delay;i++) _delay_ms(1);
  17.  for(i=0;i<num_us;i++) _delay_us(250);
  18.  for(i=0;i<us_delay;i++) _delay_us(1);
  19. }
  20.  
  21.  
  22. //-------------------------------------
  23. void generate_tone(uint16_t frequency, uint16_t duration)
  24. //-------------------------------------
  25. {
  26.    uint32_t total_delay_time;
  27.    uint16_t total_ms_delay_time, total_us_delay_time;
  28.    uint16_t num_us_delays, num_ms_delays, ms_delay_time, us_delay_time;
  29.    uint16_t num_periods;
  30.  
  31.    total_delay_time = (1000000/frequency)/2-10;
  32.  
  33.    total_ms_delay_time = total_delay_time/1000;
  34.    num_ms_delays = total_ms_delay_time/250;
  35.    ms_delay_time = total_ms_delay_time%250;
  36.  
  37.    total_us_delay_time = total_delay_time%1000;
  38.    num_us_delays = total_us_delay_time/250;
  39.    us_delay_time = total_us_delay_time%250;
  40.  
  41.    num_periods = ((uint32_t)duration*1000)/(1000000/frequency);
  42.  
  43.    while((num_periods--) != 0)
  44.    {
  45.       do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
  46.       PORTB |=  (1<<PINB3);
  47.       do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
  48.       PORTB &= ~(1<<PINB3);
  49.    }
  50.  
  51.    return;
  52. }
  53.  
  54. //-------------------------------------
  55. int main(void) {
  56. //-------------------------------------
  57.     DDRB = (1<<PINB3)|(1<<PINB4); //csak a PB3 és a PB4 kimenet
  58.     while(1) {
  59.         generate_tone(1000,200);
  60.         generate_tone(1200,200);
  61.         generate_tone(1400,200);
  62.         generate_tone(1200,200);
  63.         generate_tone(1000,200);
  64.  
  65.         if(PORTB & (1<<PINB4)) PORTB &= ~(1<<PINB4);
  66.                           else PORTB |=  (1<<PINB4);
  67.         m_delay_10ms(250); //100*10ms = 1s
  68.     }
  69.     return 0;
  70. }

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!
Következő: »»   5 / 7
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem