Forum: Mikrocontroller und Digitale Elektronik MXP430 DCO UART


von Stefan (Gast)


Lesenswert?

Hallo,
ich Programmiere gerade den MSP430F179 mit einem externen Takt von 
32.768khz.
Ich möchte nun über die Uart0 eine Baudrate von 115200 baud erzeugen. 
Dazu brauch ich einen DCO takt von 1 Mhz. Mein Problem ist das ich die 
eingestellte DCO Frequenz nicht messen kann und somit auch die Register 
der Uart nicht richtig einstellen kann. Kann mir da jemand helfen in dem 
er mir die Registereinstellungen geben kann damit ich meine Baudrate 
erzeugen kann??

Danke schon mal.

von Jörg S. (Gast)


Lesenswert?

Einfach den Takt auf einem Portpin ausgeben lassen. Da es keinen F179 
gibt, hier mal der Code für einen F149:

SMCLK auf P5.5:
P5DIR |= BIT5;
P5SEL |= BIT5;

MCLK auf P5.4:
P5DIR |= BIT4;
P5SEL |= BIT4;

von Christian R. (supachris)


Lesenswert?

Du kannst den DCO auch vom Timer A automatisch auf ein ganzzahliges 
vielfaches der 32,768kHz einstellen.

Hier der Code: DELTA ist der Vervierfachungsfaktor:
1
//------------------------------------------------------------------------------
2
void Set_DCO (void)                         // Set DCO to selected frequency
3
//------------------------------------------------------------------------------
4
{
5
6
#define DELTA 125              // target DCO = DELTA*(32768) = 4096000
7
  unsigned int Compare, Oldcapture = 0;
8
  
9
  CCTL2 = CM_1 + CCIS_1 + CAP;              // CAP, ACLK
10
  TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear
11
12
  while (1)
13
  {
14
    while (!(CCIFG & CCTL2));               // Wait until capture occured
15
    CCTL2 &= ~CCIFG;                        // Capture occured, clear flag
16
    Compare = CCR2;                         // Get current captured SMCLK
17
    Compare = Compare - Oldcapture;         // SMCLK difference
18
    Oldcapture = CCR2;                      // Save current captured SMCLK
19
20
    if (DELTA == Compare) break;            // If equal, leave "while(1)"
21
    else if (DELTA < Compare)               // DCO is too fast, slow it down
22
    {
23
      DCOCTL--;
24
      if (DCOCTL == 0xFF)
25
      {
26
        if (!(BCSCTL1 == (XT2OFF)))
27
        BCSCTL1--;                          // Did DCO roll under?, Sel lower RSEL
28
      }
29
    }
30
    else
31
    {
32
      DCOCTL++;
33
      if (DCOCTL == 0x00)
34
        {
35
          if (!(BCSCTL1 == (XT2OFF + 0x07)))
36
          BCSCTL1++;                        // Did DCO roll over? Sel higher RSEL
37
        }
38
    }
39
  }
40
  CCTL2 = 0;                                // Stop CCR2
41
  TACTL = 0;                                // Stop Timer_A
42
}

Zu Beachten ist aber, dass der DCO einen schrecklichen Temperatur- und 
Betriebsspannungsdrift hat. Für so schnelle Kommunikation ist das dann 
ein ganz schönes Glücksspiel, vor allem, wenn sich mal die Temperatur 
ändert.
Am besten die o.g. Funktion zyklisch ausführen, z.B. alle 1 Min oder so.
Oder einen Quarz an XT2 anschließen.

von Jörg S. (Gast)


Lesenswert?

> Am besten die o.g. Funktion zyklisch ausführen, z.B. alle 1 Min oder so.
> Oder einen Quarz an XT2 anschließen.
Oder externen Oszillator Widerstand benutzen (ROSC).

von Stefan (Gast)


Lesenswert?

Danke für die Hilfe.
Läuft jetzt,nach ein bisschen tüfteln.

Stefan

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.