Macht diese PWM-Variante Sinn?

Gast #1303283
Ich habe damals mal folgenden PWM-Code programmiert:
(auf einem ATmega-Prozessor in AVR GCC)

Es war eine LED angehangen die gedimmt werden sollte von 0 - 100%
Der Aufruf erfolgte in der main mit:
1
PWM(128);
2
// Werte zwischen 0 für aus und 1023 für 100%
1
void PWM(uint16_t PWM_rate)
2
{
3
// OC1A is used
4
  if (PWM_rate == 0)
5
    {
6
    TCCR1B = 0;      // PWM-Timer anhalten
7
    TCCR1A = 0;      // normaler Ausgang -> kein PWM
8
    
9
    PORTB |= (1<<PB1); // für OC1A
10
    }
11
  else //{PWM_Init und Einstellen der PWM-Rate}
12
    {
13
    TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0);
14
    // Mode 7 - Fast PWM 10-Bit
15
    // PWM-Mode Timer 1 Ausg. A enabled (OC1A)
16
    // COM - Compare Output Mode: Clear on Compare match
17
    TCCR1B = (1<<WGM12) | (1<<CS10);
18
    // CS - Prescaler auf 8 = Clk / 8 (CS11=1)
19
    // CS - Prescaler auf 1 = Clk (CS10=1)
20
    
21
    OCR1A = PWM_rate;
22
    // set output OC1A, when Counter = OCR1A
23
    }
24
}

Ich unterscheide hier zwischen 0 für aus und die Dimmwerte.

Aber bei den Dimmwerten wird jedesmal der Timer initialisiert.

Das ist doch Quatsch! Aber bei 0% bzw aus reicht da nicht ein PWM-Wert 
von 0, also OCR1A = 0? Oder z.B. anhalten des Timers (CS alle 0)? Wieso 
habe ich das damals so gemacht? Scheinbar hab ich mir da was bei 
gedacht.
Die Schaltung habe ich leider nicht mehr.

Ich möchte jetzt wieder eine PWM programmieren und für PWM = 0 soll der 
Ausgang auf 0 bleiben. Wie ist es am sinnigsten?
M.B. schrieb:
> Aber bei 0% bzw aus reicht da nicht ein PWM-Wert
> von 0, also OCR1A = 0?

<Gedächtnis kram>
Die PWM erzeugt dann immer noch kurze Spikes.
OCR1A gleich 0 funktioniert hardwaremässig nicht.

> Oder z.B. anhalten des Timers (CS alle 0)? Wieso
> habe ich das damals so gemacht? Scheinbar hab ich mir da was bei
> gedacht.

Davon geh ich mal aus :-)

> Ich möchte jetzt wieder eine PWM programmieren und für PWM = 0 soll der
> Ausgang auf 0 bleiben. Wie ist es am sinnigsten?

Lass es doch so.
Mach noch rein
1
  ...
2

3
  else //{PWM_Init und Einstellen der PWM-Rate}
4
    {
5
    if( TCCR1A == 0 )   // war die PWM auf 0? -> Timer neu starten
6
      {  
7
      TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1A1) | (1<<COM1A0);
8
      // Mode 7 - Fast PWM 10-Bit
9
      // PWM-Mode Timer 1 Ausg. A enabled (OC1A)
10
      // COM - Compare Output Mode: Clear on Compare match
11
      TCCR1B = (1<<WGM12) | (1<<CS10);
12
      // CS - Prescaler auf 8 = Clk / 8 (CS11=1)
13
      // CS - Prescaler auf 1 = Clk (CS10=1)
14
      }
15

16
    OCR1A = PWM_rate;
17
    // set output OC1A, when Counter = OCR1A
18
    }
19
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.