Forum: Mikrocontroller und Digitale Elektronik Atmega8: Mehrere LEDs faden?


von P. M. (dot)


Lesenswert?

Hallo,

da die Tage mal wieder kürzer werden und somit mehr Zeit zum Basteln 
bleibt, beschäftige ich mich zurzeit mal wieder mit den kleinen Käfern 
(Atmega8) und insbesondere dem AVR Fading Tutorial ( 
http://www.mikrocontroller.net/articles/LED-Fading ). Das normale 
Ansteuern der digitalen I/O Ports funktioniert schon mal recht gut 
(Dauerleuchten, Blinken, mit Taster abfragen was gesetzt werden soll, 
etc.). Jetzt wollte ich mal die 3 PWM Pins zum gleichzeitigen Faden von 
LEDs nutzen. Leider bekomme ich nicht die Verbindung wie ich in die 
Register(?) der zwei weiteren Anschlüsse (PB2 + PB3) schreibe, dass sie 
ebenfalls angesprochen werden. Im Moment läuft nur PB1 wie gewünscht. 
Die beiden Anderen machen gar nichts.

1) In der main() muss ich doch einfach nur wie unten getan die Ausgänge 
PB2 und PB3 aktivieren?
2) Sind die zusätzlich gemachten Einträge (gekennzeichnet mit "// ???") 
in der pwm_16_256() richtig oder totaler Quatsch? Irgendwie habe ich die 
Vermutung das irgend eine Verbindung zu den"TCCRx" fehlt...

Die Suche hilft mir leider auch nach dutzenden von gelesenen Threads 
nicht weiter :-(

Aufbau:
Atmega8 (Betriebsspannung 5V)
An PB1, 2 und 3 hängen jeweils eine LED mit Vorwiderstand an GND (Die 
LEDs haben untereinander keine Verbindung).
1
/* Obere Codehälfte gekürzt -> Gleiche wie im Tutorial */
2
void pwm_16_256(uint16_t delay){
3
    int16_t tmp;
4
#if STK500
5
    TCCR1A = 0xC2;          // inverted PWM on OC1A, 16 Bit Fast PWM
6
#else
7
    TCCR1A = 0x82;          // non-inverted PWM on OC1A, 16 Bit Fast PWM
8
#endif
9
    TCCR1B = 0x18;
10
    ICR1 = 0xFFFF;          // TOP for PWM, full 16 Bit
11
 
12
    TCCR1B &= ~0x7;         // clear clk setting
13
    TCCR1B |= 1;            // precaler 1 -> ~122 Hz PWM frequency
14
 
15
    for(tmp=0; tmp<=255; tmp++){
16
      OCR1A = pgm_read_word(pwmtable_16+tmp);
17
      OCR1B = OCR1A; // ???
18
      OCR2 = OCR1A; // ???
19
      my_delay(delay);
20
    }
21
 
22
    for(tmp=255; tmp>=0; tmp--){
23
      OCR1A = pgm_read_word(pwmtable_16+tmp);
24
      OCR1B = OCR1A; // ???
25
      OCR2 = OCR1A; // ???
26
      my_delay(delay);
27
    }
28
}
29
30
int main(void) {
31
    int16_t i;
32
    int16_t step_time=400;      
33
 
34
    DDRB |= (1<<PB1);           // -> OC1A
35
    DDRB |= (1<<PB2);           // -> OC1B?
36
    DDRB |= (1<<PB3);           // -> OC2?
37
38
    while(1) {
39
      for(i=0; i<3; i++) pwm_16_256(step_time/16);
40
    };
41
    return 0; }

Danke im Voraus :-)

von kazoo (Gast)


Lesenswert?

was hast du bitte daran umgeändert, dass die Led nicht flackert?
Ist jetzt schon die 3te Routine die ich ausprobiere aber bei allen 
flackert die Led!
Echt schon ein bisschen komisch....


Gruß

von MeinerEiner (Gast)


Lesenswert?

In TCCR1A wird nur OCR1A "eingeschaltet"
TCCR2 für OCR2 wird überhaupt nicht konfiguriert.

von Karl H. (kbuchegg)


Lesenswert?

Tutorial alleine ist nicht genug.
Du brauchst auch das Datenblatt zu deinem Prozessor.
Dort liest du dir zuerst den Abschnitt über PWM durch.
Wenn du das Gefühl hast, halbwegs im Datenblatt verstanden zu haben, wie 
das funktioniert, nimmst du das originale Tut-Beispiel her und gehst 
damit nachmal das Datenblatt durch und versuchst zu verstehen, wie das 
Datenblattwissen im Beispiel umgesetzt wurde, welche Register genau 
welche Bits gesetzt haben und warum.

Und erst dann fängst du an, deine neue Vorgabe einzuflechten.

von P. M. (dot)


Lesenswert?

kazoo schrieb:
> was hast du bitte daran umgeändert, dass die Led nicht flackert?
> Ist jetzt schon die 3te Routine die ich ausprobiere aber bei allen
> flackert die Led!

Ich benutze das AVRStudio, dass vermutlich autoamtisch wie im Tutorial 
die beschriebenen Optimierungen inklusive der Taktfrequenzangabe 
berücksichtigt und mit kompiliert.

Um PB2 gleich wie PB1 faden zu lassen, war nur eine Änderung notwendig. 
Wenn man es weiß ist es einfach ;-)
1
TCCR1A = 0xA2;

Jetzt hänge ich aber am neuen Timer"2" für PB3 bzw. OCR2. Schade das man 
den anderen Timer nicht auch dafür anzapfen kann (so wie ich es 
verstanden hab).

Bis jetzt steht folgender Code:
1
TCCR2 = 0x68; // TCCR2: FOC2:0 / WGM20:1 / COM21:1 / COM20:0 / WGM21:1 / CSS2:0 / CS21:0 / CS20:0
2
TCNT2 = 0xFFFF; // 
3
TCCR2 &= ~0x7; // CS22:0 / CS21:0 / CS20:0
4
TCCR2 |= 1;

Die LED an PB3 fadet jetzt auch, nur am höschten Punkt fängt sie zu 
Flackern an und geht danach wieder normal Richtung dunkel. Ich vermute 
das TCNT2 das Problem ist. Vielleicht kann einer noch einen Tipp geben. 
Brauche jetzt erst einmal eine Pause :-/

von MeinerEiner (Gast)


Lesenswert?

Bei mir sieht die Initialisierung für die 3 PWM-Kanäle (jeweils 8 Bit, 0 
= Aus, 255 = Vollgas, ATmega8) so aus:
1
  // Init Pins
2
  PORTB &=~ ((1 << PB1)  | (1 << PB2)  | (1 << PB3));  
3
  DDRB  |=  ((1 << DDB1) | (1 << DDB2) | (1 << DDB3));  
4
5
  // Init PWM Systems
6
  TCCR1A |= (1 << COM1A1) | (1 << COM1A0) | (1 << COM1B1) | (1 << COM1B0) | (1 << WGM10);
7
  TCCR1B |= (1 << CS10);
8
  TCCR2  |= (1 << COM21) | (1 << COM20) | (1 << WGM20) | (1 << CS20);

von P. M. (dot)


Lesenswert?

Um das Ganze mal zum Abschluß zu bekommen. Das Flackern kam wohl auf 
Grund der fehlenden 16bit Unteratüzung vom Timer2 (-> OCR2) beim PWM 
zustande. Bei Nutzung der Funktion für 8bit funktionierte es so wie 
gewünscht. Vielleicht hilft es ja mal einem der hier ebenfalls nach dem 
Thema sucht ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.