Forum: Mikrocontroller und Digitale Elektronik ATmega32 Timer0 PWM will nicht so recht


von Dead D. (deaddealer)


Lesenswert?

Moin,

Ich teste im Moment ein bischen die ganzen Sachen aus, die man mit den 
Timern machen kann. Für den Anfang wollte ich eine pulsierende LED 
haben. Die LED hängt nicht an OC0, daher setze ich bei einen 
Compare-Match PB0 auf low und bei einen Overflow auf high.
Im Moment sieht es aber so aus, dass die LED erst heller wird und beim 
runterdimmen bei niedrigster Helligkeit einmal kurz aufblitzt, sofort 
wieder dunkel wird und dann wieder langsam heller wird usw. Der Wechsel 
von heller zu dunkler macht nicht diesen Fehler. Hier der Code:

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <util/delay.h>
4
5
#define LED_MAX 254
6
#define LED_MIN 1
7
8
uint8_t dimm = LED_MIN;
9
10
11
int main(void)
12
{
13
  // LED Ausgang
14
  DDRB |= (1 << PB0);
15
  PORTB |= (1<< PB0);
16
17
  // PWM, kein Vorteiler
18
  TCCR0 |= (1 << WGM00) | (1 << CS00);
19
20
  // Setze Timer 0 Interrupts
21
  TIMSK |= (1 << OCIE0) | (1 << TOIE0);
22
23
  // aktiviere globale Interrupts
24
  sei();
25
26
27
  while(1)
28
  {
29
    while (dimm < LED_MAX)
30
    {
31
      dimm++;
32
      OCR0 = dimm;
33
      _delay_ms(2);
34
    }
35
    while (dimm > LED_MIN)
36
    {
37
      dimm--;
38
      OCR0 = dimm;
39
      _delay_ms(2);
40
    }
41
  }
42
}
43
44
ISR(TIMER0_COMP_vect)
45
{
46
  PORTB &= ~(1 << PB0);
47
}
48
49
ISR(TIMER0_OVF_vect)
50
{
51
  PORTB |= (1 << PB0);
52
}

von Spess53 (Gast)


Lesenswert?

Hi

Mache die OCR-Updates in einem der beiden Interrupts. Asynchron wird das 
nichts.

MfG Spess

von Spess53 (Gast)


Lesenswert?

Hi

Nachtrag: Im Overflow-Interrupt.

MfG Spess

von Dead D. (deaddealer)


Lesenswert?

Spess53 schrieb:
> Hi
>
> Nachtrag: Im Overflow-Interrupt.
>
> MfG Spess

Das bringt es auch nicht wirklich ... was mich grad wurmt ... setze ich 
z.B. OCR0 = 16, ist die LED dunkel. Senke ich den Wert nun schrittweise 
gegen 0, wird die LED heller o_O
Habe vorsichtshalber die beiden Schleifen raußgeworfen, so dass das 
Programm in der while(1); fröhlich nichts tut. OCR0 setze ich nun direkt 
beim Overflow-Interrupt.

von Spess53 (Gast)


Lesenswert?

Hi

Der Timer läuft auch während des Interrupts weiter. Wenn er dann den 
neuen OC-Wert schon überschritten hat leuchtet deine LED bis zum 
nächsten Overflow.

Vielleicht reicht es, den Timer langsamer zu machen. Jetzt läuft er ja 
mit Vorteiler 1.

MfG Spess

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.