Fórum témák

» Több friss téma
Cikkek » Nyolc lábbal AVR IV. rész
Nyolc lábbal AVR IV. rész
Szerző: Topi, ZsirosDani, idő: Dec 19, 2008, Olvasva: 45843, Oldal olvasási idő: kb. 2 perc
Lapozás: OK   4 / 5

Íme egy kis karácsonyi díszvilágítás a dolgozóasztalunkra, persze nyolc lábbal. A kiválasztott mikrokontrollerünk kivételesen az ATtiny13 amiben csak 1K flash található.
 Az ő mottója a "mindenből egyet".
 
 A kapcsolás se több, se kevesebb:

Működés közben: hungarocell darabka a jobb láthatóság végett

A videó megtekintéséhez Flash lejátszó szükséges!

 
Már csak a forráskód hiányzik..Íme:

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3.  
  4. //____________________________________________________
  5. volatile unsigned char R_counter , B_counter , G_counter;  // számlámó
  6. volatile unsigned char R_duty , B_duty, G_duty;               // kitöltés
  7. unsigned char TimerCounter;
  8.  
  9. //----------------------------------------------------
  10. void Init(void) {
  11. //----------------------------------------------------
  12.     TCCR0B |=  (0<<CS02)  //64-as előosztás timer 0-re
  13.             |  (0<<CS01)
  14.             |  (1<<CS00);
  15.  
  16.     TIMSK0     |= (1<<TOIE0) ;  //enable interrupt
  17.  
  18.     sei();
  19.  
  20.     DDRB     |= (1<<PINB0)     //kimeneteink
  21.             |  (1<<PINB1)
  22.             |  (1<<PINB2);    
  23. }
  24.  
  25. //----------------------------------------------------
  26. SIGNAL(SIG_OVERFLOW0) {
  27. //----------------------------------------------------
  28.     TimerCounter--;
  29.     if(TimerCounter==0) {                     // Tehát F_CPU/64/255
  30.         R_counter = R_duty;
  31.         G_counter = G_duty;
  32.         B_counter = B_duty;
  33.    
  34.         PORTB     |= (1<<PINB0)
  35.                    |     (1<<PINB1)
  36.                  |    (1<<PINB2);
  37.     }    
  38.  
  39.     if(R_counter) R_counter--;
  40.     if(G_counter) G_counter--;
  41.     if(B_counter) B_counter--;
  42.  
  43.     if(R_counter==0) PORTB &= ~(1<<PINB0);
  44.     if(G_counter==0) PORTB &= ~(1<<PINB1);
  45.     if(B_counter==0) PORTB &= ~(1<<PINB2);
  46. }
  47.  
  48. //----------------------------------------------------
  49. int main(void) {
  50. //----------------------------------------------------
  51.     unsigned char val = 1;       //belessen az 1. case-be.
  52.     Init();
  53.     R_duty = 128;     //kezdoertekek
  54.     G_duty = 30;    
  55.     B_duty = 200;
  56.  
  57.     for(;;) {     // vegtelen ciklus
  58.            
  59.         switch(val) {                    // színek fadelése
  60.             case 1:    if(R_duty<0xFF) R_duty++;
  61.                     else val = 2;
  62.                     break;
  63.             case 2:    if(B_duty) B_duty--;
  64.                     else val = 3;
  65.                     break;
  66.             case 3:    if(G_duty<0xFF) G_duty++;
  67.                     else val = 4;
  68.                     break;           // break!! Különben továbbmegy..
  69.             case 4:    if(R_duty) R_duty--;
  70.                     else val = 5;
  71.                     break;
  72.             case 5:    if(B_duty<0xFF) B_duty++;
  73.                     else val = 6;
  74.                     break;
  75.             case 6:    if(G_duty) G_duty--;
  76.                     else val = 1;
  77.                     break;
  78.         }
  79.         _delay_ms(50);
  80.     }
  81.  
  82.     return 0;
  83. }

A programban nem használok semmilyen nem gyári header-t.  Rövid működése a következő:
Az init függvényünkben első lépésként beállítjuk az  egyetlen timerünk (Timer0) előosztását 64-re, majd engedélyezzük a megfelelő regiszterben (Timsk0) a timer owerflow interruptot.

Ezt még 256-al osztjuk (256.-ra csordul túl) az overflow miatt, majd a TimerCounter változó dekrementálásával még 256-al.  Tehát: F_CPU/64/256/256. F_CPU jelen esetben 9 600 000 Hz. Programozásnál is ezt az órajelet válasszuk ki (Fuses)

Ne felejtsük el, engedélyezni globálisan is az interruptokat, ezt a sei()-paranccsal tehetjük meg! A signal egy olyan függvény, ami tartalma az interrupt beesésekor hajtódik végre! Igyekezzünk, itt  semmilyen nagyobb műveletet végrehajtatni processzorunkkal, hisz rendkívül időkritikus. Jelen esetben itt adjuk át a végtelen ciklusban számolt kitöltési tényezőt (az x_duty-t) az x_counterünknek. Fontos még, hogy ezek a változók volatile-ok legyenek, hisz az értékük bármelyik pillanatban változhat. Ha ezt elfelejtenénk, nem futna a software-es PWM-ünk. A végtelen ciklusunkban csak a színek fadelését végzem. Növelem az aktuális színt (azaz a kitöltési tényezőjét), ameddig el nem éri az értéke 0xFF-et. Ha eléri, akkor ugrok a következő esetre és ezeket kombinálom, így keverednek a színek. Remélem mindenki tetszését elnyeri. Sikeres után építést kívánok!

Ha kérdésetek van, szívesen segítek!

Köszönet Topinak, hogy megszerettette velem az AVR-t!

ZsirosDani


A cikk még nem ért véget, lapozz!
Következő: »»   4 / 5
É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