Forum: Mikrocontroller und Digitale Elektronik PWM unterbrechen


von Stefan K. (klinggone)


Lesenswert?

Hallo,
ich programmiere gerade einen Taster um eine RGB-Led zu schalten. Ein 
Zustand ist einPWM Signal, die anderen schalten lediglich ein/ aus.

-StartZustand PWM - LED dimmt grün
-Taste wird gedrückt
-LED leuchtet blau
-Taste wird gedrückt
-LED leuchtet rot
-Taste wird gedrückt
-StartZustand PWM - LED dimmt grün
...
Alles funktioniert aber den PWM Zustand kann ich bloss per Taster 
unterbrechen wenn ich die Taste beim höchsten oder niedrigsten OCR-Wert 
drücke.
Wieso ist das so und wie kann ich den PWM auch mitten während des 
Dimmvorgangs unterbrechen?
Für andere Lösungsvorschläge was das Weiterschalten per Taster angeht 
würde ich mich auch freuen ;)
----------------------------------
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
  DDRC = (1<<PINC3) | (1<<PINC5);

  TCCR1A =(1<<WGM11)|(1<<WGM10);  // PWM, Phase Correct, 10-bit; zählt 
bis 1023
  TCCR1A |= (1<<COM1A1);  // Compare Output Mode: clear on OCR1A at 
bottom
  TCCR1B =(1<<CS10);  // no prescaling
  int a =1023;
  int d_time = 200;  // delay time

  DDRC &= ~(1<<PC1);    //TASTER Pullup
  PORTC |= (1<<PC1);

  uint8_t next = 1;
  while(1)
  {
    if(next == 1){
      _delay_ms(d_time);
      PORTC &= ~(1<<PINC3);
      PORTC &= ~(1<<PINC5);
      DDRB |= (1<<PINB1);

      while(a<1023){
        OCR1A=a;
        _delay_ms(1);
        a++;
        }
      while(a>0){
        OCR1A=a;
        _delay_ms(1);
        a--;
      if(bit_is_clear(PINC, PINC1)){
        next = 2;
      }
      }
    }
    if(next == 2){
      _delay_ms(d_time);
      DDRB &= ~ (1<<PINB1);
      if(bit_is_set(PINC,PINC1)){
        PORTC |= (1<<PINC3);
      }
      else{
        PORTC &= ~(1<<PINC3);
        next = 3;
      }
    }
    if(next == 3){
      _delay_ms(d_time);
      PORTC &= ~(1<<PINC3);
      if(bit_is_set(PINC,PINC1)){
        PORTC |= (1<<PINC5);
      }
      else{
        PORTC &= ~(1<<PINC5);
        next = 1;
      }
    }
  }
}

von M. K. (sylaina)


Lesenswert?

Stefan K. schrieb:
> Wieso ist das so und wie kann ich den PWM auch mitten während des
> Dimmvorgangs unterbrechen?

Das zugehörige PWM-Register einfach entsprechend laden und dabei darauf 
achten, dass dann kein anderer das Register wieder umbeschreibt. So 
mache ich es jedenfalls immer.

von Tom M. (Gast)


Lesenswert?

Stefan K. schrieb:
> Wieso ist das so

... weil es so programmiert wurde. Ergänz mal den Code um einige 
Kommentare, v.a. da wo die Taste abgefragt wird!

> und wie kann ich den PWM auch mitten während des
> Dimmvorgangs unterbrechen?

Du könntest einen Interrupt verwenden, der auf Tastendruck anspringt. 
Entprellung beachten. Dazu gibt's hier im Wiki etliche Artikel.

von Wolfgang (Gast)


Lesenswert?

Stefan K. schrieb:
> Für andere Lösungsvorschläge was das Weiterschalten per Taster angeht
> würde ich mich auch freuen ;)

Wie wäre es, wenn ein paar Kommentare über Sinn und Zweck in den ganzen 
if-Konstrukte zu verteilen. So ist das etwas dröge zu lesen ...

von Stefan K. (klinggone)


Lesenswert?

Danke für Euer Feedback. Ich habe jetzt einfach beim Abfragen der Taste 
die Variable a für den OCRA1 Wert auf 0 gesetzt. Damit wird das PWM auch 
unterbrochen.
...das nachste mal wird besser kommentiert ;)

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.