MXP430 DCO UART

Gast #636527
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.
Gast #636605
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;
#636629
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren