Forum: Mikrocontroller und Digitale Elektronik MSP430G2553 PWM flackert beim Verstellen der Pulsweite


von Storch_Heiner (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich benutze die hardware-PWM vom MSP430G2553 mit dem TIMER_A1 um die
Leuchtstärke von LEDs zu regeln. Das funktioniert für konstante
Leuchtstärken auch gut. Der PWM duty-cycle ist 800hz.

Füge ich allerdings den zweiten Timer Timer_A0 hinzu und erhöhe/senke
die Leuchtstärke (mit Abständen von ~10hz), dann flackert die LED
manchmal sichtbar - in nicht deterministischen Abständen.

Was könnte das sein? Ich ändere die Leuchtstärke durch setzen des
capture/compare für den Timer. Da würde ich denken, dass die LED beim
Ändern des capture/compare höchstens für 1/800s kurz aufleuchtet bzw 
dunkel bleibt was ja nicht wirklich sichtbar sein sollte.

Habt ihr eine Idee?
Code ist im Anhang wer schauen möchte.

Grüße
Heiner

von Outmode (Gast)


Lesenswert?

Storch_Heiner schrieb:
> Habt ihr eine Idee?

Ja, das solltest du einmal ganz genau betrachten:
1
float brightness;
2
...
3
TA1CCR1 = (int) brightness;

Und wozu das hier?
  skipStepCounter++;
  if(skipStepCounter > SKIP_STEPS) {
    skipStepCounter = 0;
  }
Warum nicht das Timerintervall erhöhen und die ISR weniger häufig 
aufrufen?

von Storch_Heiner (Gast)


Lesenswert?

> float brightness;
> TA1CCR1 = (int) brightness;

Das verstehe ich nicht. Nach meinem Wissen ist das eine legale 
Operation?

Also zB. 5.90852098232 wird zu 5?

Den Loop habe ich drin weil ich die Timerclock nicht ändern wollte. Ich 
lasse alles auf der SMCLK laufen und die ist schnell.

von lucifer (Gast)


Lesenswert?

Hallo

Bin mich gerade in das MSP430FR4133 Launchpad am einarbeiten. Gleiches 
Fehlerbild & Lösung gefunden, hatte deinen Post im Kopf. Du veränderst 
den Duty Cycle zu schnell, warte länger. Bei meinem Code funktioniert 
das inkrementieren sauber, beim dekrementieren flackert es. Müsste das 
ganze zeitlich mal nachrechnen...


1
#include <msp430.h>
2
3
4
volatile unsigned int dutyCycle = 0;
5
6
7
int main(void)
8
{
9
    WDTCTL = WDTPW | WDTHOLD;        // Stop watchdog timer
10
    PM5CTL0 &= ~LOCKLPM5;          // Disable the GPIO power-on default high-impedance mode
11
                        // to activate previously configured port settings
12
    CSCTL1 |= DCORSEL2;            // DCO Range = 16 MHz
13
  
14
                        // PWM an P1.7 aufsetzen
15
    P1DIR |= BIT7;              // P1.7 ist Output
16
    P1SEL0 |= BIT7;              // P1.7 gehört zu PWM
17
    TA0R = 0;                // TMR_A0 löschen
18
    TA0CTL |= TASSEL1;            // Taktquelle = SMCLK
19
    TA0CCR0 = 0xffff;            // Periodenregister: 2^16 Schritte
20
    TA0CCR1 = 0;              // Zu Begin Duty Cycle = 0
21
    TA0CCTL1 |= OUTMOD0 + OUTMOD1 + OUTMOD2;// Output Mode: set/reset
22
    TA0CTL |= MC0;              // up mode, 0 - TA0CCR0
23
  
24
    while(1)
25
    {
26
      while(dutyCycle < 0xffff)      // Helligkeit erhöhen
27
      {
28
        TA0CCR1 = dutyCycle;      // Neuen Duty cycle setzen
29
        dutyCycle++;          // Duty cycle erhöhen
30
        _delay_cycles(100);        // warte LANG
31
      }
32
  
33
      while(dutyCycle > 0)        // Helligkeit verringern
34
      {
35
        TA0CCR1 = dutyCycle;      // Neuen Duty cycle setzen
36
        dutyCycle--;          // Duty cycle verringern
37
        _delay_cycles(10);        // warte KURZ
38
      }
39
    }
40
}

von lucifer (Gast)


Lesenswert?

Oops, Vorposter hatge die Lösung auch schon. Wer lesen kann...

von Outmode (Gast)


Lesenswert?

Bei Inkrement wird der neue Wert garantiert innerhalb einer Periode 
erreicht. Dass kann sogar zweimal passieren, schadet aber nicht.
Bei Dekrement sieht es anders aus. Hier wird u. U. das TAxCCR unter TAR 
gesetzt und das EQUx ändert sich nicht.

Siehe einmal nach Hinweisen zum Schreiben der Register im FUG.

von Outmode (Gast)


Lesenswert?

Ach ja, man könnte den Dutycycle immer genau bei Timerüberlauf setzen, 
das wäre sicher.

von lucifer (Gast)


Lesenswert?

Hm, mal allgemein eine Frage. Bei den mitgelieferten 
Projekten/Beispielen findet man Funktionen wie
1
ADC_disableConversions(ADC_BASE,ADC_COMPLETECONVERSION);

oder
1
 ADC_init(ADC_BASE,ADC_SAMPLEHOLDSOURCE_2,ADC_CLOCKSOURCE_ADCOSC,ADC_CLOCKDIVIDER_1);

Werden die von professionellen Entwicklern auch verwendet? Ich (22, 
Greenhorn) schreibe lieber alles selber, dann weiss ich auch, wo was 
geht. Wie seht ihr das?

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.