Atmega8: Mehrere LEDs faden?

OP #1500200
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 :-)
#1500421
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.
OP #1500590
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 :-/
Gast #1500594
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);
OP #1502432
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 ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren