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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.