Forum: Mikrocontroller und Digitale Elektronik Problme mit Clock für PWM (MSP430-F2013)


von Nicco (Gast)


Lesenswert?

Hallo Leute,

Nach erfolgreiches Test von alle einzelne Funktionen (auf meinen eZ430 
Development Tool), bin ich jetzt auf meinen PWM blockiert.

für einen Motor, muss ich einen PWM mit Periode 200us, und einen duty 
cycle von bis zu 170us (spricht 85%).
da ich in für den ADC sowieso ein SMCLK von 1MHz habe, dachte ich dies 
für mein PWM zu verwenden.

Ich habe so TACCR0 bei 200 gesetzt (=200 clock pulses von je 1/1MHz=1us)
und TACCR1 als Anfang bei 100 (später soll es variabel sein).

jetzt. Solange ich den Clock source (TASSEL) auf ACLK behalte, ist alles 
gut... ich sehe den Puls mit augen (led) und Oszilloskop.
jetzt setze ich der TASSEL auf 2 = SMCLK... geht nichts mehr! heisst, 
ich komme in meine ISR nicht mehr.

Kann jemand mir helfen? was habe ich übersehen? oder gibt es eine 
fürchterliches Fehler? In Bücher und Family user guide habe ich nichts 
gelesen dass SMCLK ein Problem sein soll.
Arbeite seit einen Monat mit diesen uC, bin also ein 'Anfänger'

Hier ist mein Code:
1
// working on a MSP430 F2013 (eZ430 Development Tool)
2
//----------------------------------------------------------------------
3
#include <io430x20x3.h>      // Specific device
4
#include <intrinsics.h>      // Intrinsic functions
5
#include <stdint.h>          // Integers of defined sizes
6
//----------------------------------------------------------------------
7
void main (void)
8
{
9
  WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer
10
// Select clocks
11
  BCSCTL1 = CALBC1_8MHZ;       // Set range for calibrated DCO at 8MHz
12
  DCOCTL = CALDCO_8MHZ;        // Set DCO tap and modulation
13
        BCSCTL3 = LFXT1S_2;    // ACLK from VLO (12KHz)
14
        BCSCTL2 = DIVS_3;      // SMCLK = DCO/8 = 1Mhz
15
// Set up Timer_A for PWM on active high LED, channel 1
16
  TACCR0 = 200;                // should be 200us
17
  TACCR1 = 100;                // Duty cycle D = 0.5 initially (will be variable in the future)
18
  TACCTL0 = CCIE;              // Interrupts on compare to update PWM
19
  TACCTL1 = OUTMOD_7 | CCIE;   // Reset/set (positive PWM), interrupts
20
// Configure ports 1 and 2 with pull resistors on unused pins
21
  P1OUT = 0;                   // Preclear output buffer
22
  P1DIR = BIT0;                // Set P1.0 to output, others input
23
  P1REN = 0xFF & ~BIT0;        // Pull resistors on P1[7:1]
24
  P2SEL = 0;                   // Digital i/o rather than crystal
25
  P2REN = BIT6 | BIT7;         // Pull resistors on pins that exist
26
// Start timer from ACLK, no division, Up mode, clear, with interrupts
27
  TACTL = TASSEL_2 | ID_0 | MC_1 | TACLR | TAIE;
28
  for (;;) {                   // Loop forever
29
    __low_power_mode_3();      // Enter LPM3 between interrupts
30
  }
31
}
32
//----------------------------------------------------------------------
33
// Interrupt service routine for CCIFG1 and TAIFG; share vector
34
//----------------------------------------------------------------------
35
#pragma vector = TIMERA1_VECTOR
36
__interrupt void TIMERA1_ISR (void)  // ISR for CCIFG1 and TAIFG
37
{
38
  switch (__even_in_range(TAIV, 10)) {
39
  case 0:                      // No interrupt pending
40
    break;                     // No action
41
  case 2:                      // Vector 2: CCIFG1
42
    P1OUT_bit.P1OUT_0 = 0;     // End of duty cycle: Turn off LED
43
    break;
44
  case 10:                     // Vector A: TAIFG, last value possible
45
    P1OUT_bit.P1OUT_0 = 1;     // Start of PWM cycle: Turn on LED
46
    break;
47
  default:                     // Should not be possible
48
    for (;;) {                 // Loop here for ever
49
    }
50
  }
51
}

von Alex (Gast)


Lesenswert?

Hallo,

bin jetzt nicht alles durchgegangen. Mir fehlt allerdings ein
1
__enable_interrupt();
bevor du in den LPM gehtst.

mfg Alex

von Stefan (Gast)


Lesenswert?

LPM3 -> SMCLK deaktiviert !!!

von Stefan (Gast)


Lesenswert?

Nachtrag:

Wundert mich, dass es mit ACLK funktioniert...
CCR0 IRQ ist aktiviert aber es fehlt die entsprechende ISR dazu.
Sollte eigentlich 'n crash geben (nach Murphy)

von Christian R. (supachris)


Lesenswert?

Der Kompiler erzeugt wahrscheinlich für alle fehlenden ISRs ein RETI.

Das Hauptproblem ist wie schon beschrieben, dass du das Taktsystem vom 
MSP430 nicht verstanden hast. Beim LPM3 ist nur noch der ACLK aktiv, 
alle anderen Takte sind aus.

von Stefan (Gast)


Lesenswert?

>Der Kompiler erzeugt wahrscheinlich für alle fehlenden ISRs ein RETI.
Das wäre mir neu, dass der IAR das macht...

von Nicco (Gast)


Lesenswert?

Hallo,

danke viel mal, das hatte ich übersehen... werde es morgen neu testen!

allerdings, die zweite ISR gibt's schon... habe die nicht rein kopiert, 
weil die nicht Problematisch ist.

Alex, die intrinsic Funktion _low_power_mode_3(); beinhaltet schon die 
Aktivierung von GIE.

Greetz

von Stefan (Gast)


Lesenswert?

>allerdings, die zweite ISR gibt's schon...
OK, sie macht aber hier gar keinen Sinn!

Du hast einmal den CCR0-IRQ, der aufgerufen wird wenn der Timer den Wert 
CCR0 = 200 erreicht und zum anderen den Timer-IRQ, der aufgerufen wird 
wenn der Timer von 200 auf 0 zurückspringt... also zwei IRQs die nur 
einen Clock auseinander liegen! Die kannst Du auch zusammenfassen, 
entweder CCR0-IRQ oder Timer-IRQ

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.