Forum: Compiler & IDEs PWM Schwelle kurzzeitig erhöhen


von Locke (Gast)


Lesenswert?

Hej,

ich hab mir mit einem Atmega8 eine PWM mit Timer1 gebastelt und möchte 
nun, dass ich diese per Knopfdruck für einen kurzen Zeitraum erhöhen 
kann.

Das Erhöhen an sich ist kein Problem, dazu setze ich beim Knopfdruck 
einfach OCR1A entsprechend neu. Nun möchte ich aber gerne, dass OCR1A 
nach ca. 1 Sekunde wieder auf den alten Wert zurück geht. Wie mache ich 
das?

Mein erster Gedanke war ein weiterer Timer. Allerdings funktioniert der 
nicht, wie ich es gerne hätte.
1
// main:
2
TIMSK = (1<<OCIE2);      //Interrupt für timer/counter an schalten
3
TCCR2 = (1<<WGM21) | (1<<CS22) | (1<<CS21);  //CTC, Prescale=256
4
OCR2 = (F_CPU/256)-1;      //alle 1 sec ein Interrupt
5
sei();
6
7
...
8
9
ISR(TIMER2_COMP_vect)
10
{
11
  PORTC ^= (1<<PC5); // Test-LED soll blinken
12
  // Hier würde dann das Rücksetzen von OCR1A passieren.
13
}

Nur leider geht die LED sofort beim Start an und geht nie wieder aus.

Ich weiß leider nicht ganz, wo da der Fehler liegt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Locke schrieb:

> Mein erster Gedanke war ein weiterer Timer.

Einen "System-Timer" benutzen, und an den all die länger laufenden
Timeouts anflanschen.  Der "tickt" dann vielleicht alle 10 ms und
zählt die verschiedenen pseudo-parallelen Timer herunter.  Wenn er
triggert, wird ein callback aufgerufen, entweder direkt aus der
ISR (dann muss der callback seh schnell arbeiten), oder indem man
ein Flag setzt und dieses in der main loop auswertet.

> OCR2 = (F_CPU/256)-1;      //alle 1 sec ein Interrupt

Hast du mal nachgerechnet?

Wenn du nicht gerade einen extrem langsamen CPU-Takt hast, wirst
du nicht bis auf 1 Hz herunter kommen.

> Nur leider geht die LED sofort beim Start an und geht nie wieder aus.

Wenn du mal schnell genug guckst (also bspw. mit einem Oszi), dann
wird sie wohl nur sehr schnell blinken ...

von Locke (Gast)


Lesenswert?

Jörg Wunsch schrieb:
>> OCR2 = (F_CPU/256)-1;      //alle 1 sec ein Interrupt
>
> Hast du mal nachgerechnet?
>
> Wenn du nicht gerade einen extrem langsamen CPU-Takt hast, wirst
> du nicht bis auf 1 Hz herunter kommen.

Ich wünschte, so einfach wäre es, allerdings habe ich mich nicht 
verrechnet.
Das Ding läuft mit 8MHz, der Prescaler ist auf 256, das heißt, der Timer 
läuft mit 31250Hz und zählt von 0 bis 31249. => 1Hz

>Einen "System-Timer" benutzen, und an den all die länger laufenden
>Timeouts anflanschen.  Der "tickt" dann vielleicht alle 10 ms und
>zählt die verschiedenen pseudo-parallelen Timer herunter.  Wenn er
>triggert, wird ein callback aufgerufen, entweder direkt aus der
>ISR (dann muss der callback seh schnell arbeiten), oder indem man
>ein Flag setzt und dieses in der main loop auswertet.

Kapier ich spontan nicht ganz. Du meinst also, ich kann mein gewünschtes 
Verhalten an timer1 von der PWM anhängen? Werd mich da mal etwas schlau 
machen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Locke schrieb:

> Das Ding läuft mit 8MHz, der Prescaler ist auf 256, das heißt, der Timer
> läuft mit 31250Hz und zählt von 0 bis 31249. => 1Hz

Und wie machst du das mit einem 8-bit-Timer?

> Kapier ich spontan nicht ganz. Du meinst also, ich kann mein gewünschtes
> Verhalten an timer1 von der PWM anhängen?

Im Prinzip sogar das, aber einen extra Timerkanal neben der PWM
kannst du dir natürlich schon noch leisten. ;-)  Du kannst ja auch
den Timer 2 dafür nehmen, musst halt nur dran denken, dass der nur
bis 255 zählen kann.  Also beispielsweise einen Prescaler von 512,
und dann im CTC-Modus bis 155 zählen.  Das gibt einen "system tick"
von knap 10 ms (9,984 ms).  Wenn du davon 100 gezählt hast in der
ISR, ist eine Sekunde vergangen.

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.