Forum: Compiler & IDEs Probleme mit PWM bei Atmega8


von Andreas G. (cpl)


Angehängte Dateien:

Lesenswert?

Hi!

Mit dem folgenden Programm will ich die Leuchtstärke einer LED, die an 
einem ATMega8 (am PB1) hängt verringern. Der PWM-Codeteil wird immer 
dann aufgerufen, wenn der Taster nicht gerdrückt ist; drücke ich ihn, so 
wird der Ausgang einfach als I/0 Port gesehen und "ein-"geschaltet.
Die zweite LED ist nur zur Kontrolle da, dass der Druck auf den Taster 
auch tatsächlich eine Reaktion auslöst (funktioniert).

Im angehängten Bild habe ich mal skizziert wie ich mir die Funktion des 
Programms vorstelle:
Der timercounter stratet bei BOTTOM, Ausgang ist geschaltet. dann wird 
hochgezählt bis MAX (OCR1A) erreicht ist, Ausgang wird abgeschaltet, 
dann weitergezählt bis TOP (hier 1024 bzw. 1023 bei einer 10-bit PWM), 
nun Ausgang wieder angeschaltet und von 0 aus wieder hochgezählt, und so 
fort.

Da ich OCR1A auf 0xa setzte (=10), bei 10 bit aber 1023 Stufen lang 
hochgezählt wird, sollte die LED grob geschätzt 1/100 der Energie 
bekommen, die sie bei einfach auf "I/OEin" geschaltetem Port bekommt- 
und damit bei nicht-gedrücktem Taster deutlich dunkler sein als bei 
gedrücktem.

Das ist jedoch nicht der Fall, die LED leuchtet immer mit konstanter 
Stärke, selbst wenn ich OCR1A= 0x0 setze. Was läuft da schief?


grüße,
CPL
1
#include <avr/io.h>
2
#include <stdint.h>       
3
#include <stdlib.h>
4
5
uint8_t EINGELESENEBITS;  
6
int16_t zaehle;
7
8
9
int main (void) 
10
  {
11
        ////////////////////////*Leuchtdiode schalten*/////////////////////////////
12
    DDRC |= (1<<DDC5);                
13
       ////////////////////////*Taster lesen*////////////////////////////////////              
14
       DDRD  = 0x00;                     
15
  ///////////////////////////////* PWM Pulsweitenmodulation*///////////////////////////////////////////////
16
  
17
  DDRB = (1<<PB1);    //PB1 = OC1A als Ausgang
18
19
  while(1)
20
    {     
21
       if (PIND & 0x4)  //falls Taster nicht gedrückt
22
         {
23
          //die eine LED aus
24
          PORTC |= (1<<PC5);   
25
          
26
          
27
             TCCR1A = (1<<WGM12)|(1<<WGM11)|(1<<WGM10);   //Fast PWM 10-Bit (Obergrenze 1023, Frequenz fTC1/1024)  
28
          TCCR1A = (1<<COM1A1); //nicht Invertierende PWM: löschen beim raufzählen, setzen beim runterzählen
29
          TCCR1B = (1<<CS10); //no prescaling
30
              OCR1A = 0xa;  //Compare Wert definiert Pulslänge  
31
        }     
32
        
33
      else   //falls taster gedrückt
34
        {   
35
          //beide LEDs auf volle Leuchtstärke EIN           
36
          PORTB &= ~(1<<PB1); 
37
          PORTC &= ~(1<<PC5);  
38
        }  
39
    }
40
41
42
  ///////////////////////////////*                         *///////////////////////////////////////////////
43
44
  while(1) 
45
    {
46
        //leere schleife   
47
    }
48
  //wird nie erreicht
49
50
  return 0;                   
51
}

von Oliver (Gast)


Lesenswert?

1
TCCR1A = (1<<WGM12)|(1<<WGM11)|(1<<WGM10);   //Fast PWM 10-Bit (Obergrenze 1023, Frequenz fTC1/1024)
2
TCCR1A = (1<<COM1A1); //nicht Invertierende PWM: löschen beim raufzählen, setzen beim runterzählen

Da ist ein Fehler in der 2. Zeile. Ich spende ein |.

Oliver

von Andreas G. (cpl)


Lesenswert?

Der Teufel steckt im detail...

Danke! Läuft jetzt..

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.