Forum: Mikrocontroller und Digitale Elektronik MSP430F2274 DCO Daten über externen Taktgeber kalibrieren


von mesut (Gast)


Lesenswert?

hallo,

ich habe aus versehen die DCO kaliebrierungsdaten gelöscht und die PINs 
2.6 & 2.7 also XIN und XOUT schon auf dem SMD-Board als Signalausgänge 
für was anderes fest verdrahtet.

Ich habe auch schon die Suchfunktion benutzt und wie verückt gegooglet. 
ich finde aber immer nur das Beispielprogramm von TI 
msp430x22x4_dco_flashcal.c was ich leider nicht benutzen kann, da ich ja 
keinen Uhrenquarz mehr an XIN und XOUT anschließen kann.
Ich habe ein Osziloskop und auch Taktquellen mit 1Mhz und anderen 
Frequenzen zur Verfügung.
Als freie PINs habe ich nur noch die Ports P2.0 bis P2.4.

Ist vielleicht jemand so fit und kann mir Hilfestellung geben um das 
Beispielprogramm von TI zur kalibrierung eventuell so anzupassen, dass 
ich das mit meinen freien Ports zur kalibrierung verwenden kann. Wie 
erwähnt es stehen mir ein Oszi und auch eine Taktgenerator zur 
Verfügung.

Für Tipps oder Codeschnipsel wäre ich euch echt sehr dankbar oder kann 
man eventuell den quarz nich an einen der freien PINs hängen?

mfg mesut

von mesut (Gast)


Lesenswert?

hallo,

hat keiner einen Rat?
Ich habe den CODE von thomas, der hat wohl so ein ähnliches bzw. gleiche 
Problem TOPIC: (Beitrag "Flashspeicher Segment A bei ez430-rf2500 gelöscht wie wiederherstellen?") etwas 
modifiziert und P2.1 an den Taktgeber mit 135,14 KHz angeschlossen.
und mir die Funktion SETDCO() von den MSP430F20xx Code Examples genommen 
und als Quelle für den Timer einfach INCLK (TASSEL_3) genommen.

Nur kommt das Programm nur bis zur Zeile:
 while (!(CCIFG & TACCTL0)); // Wait until capture occured

mit einer anderen Frequenz wie z.B. 32Khz usw. ist das Problem immer 
noch da. das heißt er erkennt das Signal nicht.

Weiß jemand Rat?

please, bitte,  por favor, per favore, 不客气 [不客氣
1
//******************************************************************************
2
//           MSP430F22x4
3
//         ---------------
4
//     /|\|            XIN|-
5
//      | |               | 32kHz
6
//      --|RST        XOUT|-
7
//        |               |
8
//        |           P1.0|--> LED
9
//        |           P1.4|--> SMLCK = target DCO
10
//        |           P2.1|<-- INCLK  mit 135,14KHz
11
//
12
//  A. Dannenberg
13
//  Texas Instruments Inc.
14
//  April 2006
15
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
16
//******************************************************************************
17
#include "msp430x22x4.h"
18
19
#define DELTA_1MHZ    999
20
#define DELTA_8MHZ    8000
21
#define DELTA_12MHZ   11995
22
#define DELTA_16MHZ   15990
23
24
unsigned char CAL_DATA[8];                  // Temp. storage for constants
25
volatile unsigned int i;
26
int j;
27
char *Flash_ptrA;                           // Segment A pointer
28
void Set_DCO(unsigned int Delta);
29
30
void main(void)
31
{
32
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
33
  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization
34
  P1OUT = 0x00;                             // Clear P1 output latches
35
  P1SEL = 0x10;                             // P1.4 SMCLK output
36
  P1DIR = 0x11;                             // P1.0,4 output
37
  P2SEL |= 0x02;                            // Select P2.1 INCLK options
38
39
  j = 0;                                    // Reset pointer
40
41
  Set_DCO(DELTA_16MHZ);                     // Set DCO and obtain constants
42
  CAL_DATA[j++] = DCOCTL;
43
  CAL_DATA[j++] = BCSCTL1;
44
45
  Set_DCO(DELTA_12MHZ);                     // Set DCO and obtain constants
46
  CAL_DATA[j++] = DCOCTL;
47
  CAL_DATA[j++] = BCSCTL1;
48
49
  Set_DCO(DELTA_8MHZ);                      // Set DCO and obtain constants
50
  CAL_DATA[j++] = DCOCTL;
51
  CAL_DATA[j++] = BCSCTL1;
52
53
  Set_DCO(DELTA_1MHZ);                      // Set DCO and obtain constants
54
  CAL_DATA[j++] = DCOCTL;
55
  CAL_DATA[j++] = BCSCTL1;
56
57
  Flash_ptrA = (char *)0x10C0;              // Point to beginning of seg A
58
  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
59
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
60
  FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits
61
  *Flash_ptrA = 0x00;                       // Dummy write to erase Flash seg A
62
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
63
  Flash_ptrA = (char *)0x10F8;              // Point to beginning of cal consts
64
  for (j = 0; j < 8; j++)
65
    *Flash_ptrA++ = CAL_DATA[j];            // re-flash DCO calibration data
66
  FCTL1 = FWKEY;                            // Clear WRT bit
67
  FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit
68
69
  while (1)
70
  {
71
    P1OUT ^= 0x01;                          // Toggle LED
72
    for (i = 0; i < 0x4000; i++);           // SW Delay
73
  }
74
}
75
76
void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
77
{
78
  unsigned int Compare, Oldcapture = 0;
79
80
  BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
81
  TACCTL0 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
82
  TACTL = TASSEL_3 + MC_2 + TACLR;          // INCLK, cont-mode, clear
83
84
  while (1)
85
  {
86
    while (!(CCIFG & TACCTL0));             // Wait until capture occured
87
    TACCTL0 &= ~CCIFG;                      // Capture occured, clear flag
88
    Compare = TACCR0;                       // Get current captured SMCLK
89
    Compare = Compare - Oldcapture;         // SMCLK difference
90
    Oldcapture = TACCR0;                    // Save current captured SMCLK
91
92
    if (Delta == Compare)
93
      break;                                // If equal, leave "while(1)"
94
    else if (Delta < Compare)
95
    {
96
      DCOCTL--;                             // DCO is too fast, slow it down
97
      if (DCOCTL == 0xFF)                   // Did DCO roll under?
98
        if (BCSCTL1 & 0x0f)
99
          BCSCTL1--;                        // Select lower RSEL
100
    }
101
    else
102
    {
103
      DCOCTL++;                             // DCO is too slow, speed it up
104
      if (DCOCTL == 0x00)                   // Did DCO roll over?
105
        if ((BCSCTL1 & 0x0f) != 0x0f)
106
          BCSCTL1++;                        // Sel higher RSEL
107
    }
108
  }
109
  TACCTL0 = 0;                              // Stop TACCR0
110
  TACTL = 0;                                // Stop Timer_A
111
  BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
112
}

von Stefan (Gast)


Lesenswert?

Quelle für den Timer muss SMCLCK bleiben.
Was verändert werden muss ist das Capture Compare Signal. Statt des 
internen ACLCK, was hier nicht verfügbar ist, muss ein externes Signal 
genutzt werden. CCI0B an P2.2 sollte nutzbar sein.
Mit 4096 Hz an P2.2 können die DELTA_xMHz Werten aus dem 
Beispielprogramm unverändert bleiben.
Bei höheren Frequenzen an P2.2 müssen die DELTA_xMHz entsprechend 
kleiner werden und der DCO lässt sich nur noch grob einstellen.
Bei z.B. 32KHz müssten statt
#define DELTA_1MHZ    244    // 244 x 4096 Hz = 999424 Hz
entweder
#define DELTA_1MHZ    30     // 30 x 32768 Hz = 983040 Hz
oder
#define DELTA_1MHZ    31     // 31 x 32768 Hz =1015808 Hz
genutzt werden

von mesut (Gast)


Lesenswert?

danke für die antwort werde es gleich mal ausprobieren

von mesut (Gast)


Lesenswert?

kannst du mir einen tipp geben wie ich den timer einzustellen habe. ich 
bekomme das irgentwie nicht hin.

mfg mesut

von mesut (Gast)


Lesenswert?

ich habe das jetzt so umgesetzt:
1
//******************************************************************************
2
//
3
//           MSP430F22x4
4
//         ---------------
5
//     /|\|            XIN|-
6
//      --|RST        XOUT|-
7
//        |               |
8
//        |           P1.0|--> LED
9
//        |           P2.1|--> SMLCK = target DCO
10
//        |           P2.2|<-- 4096 Hz
11
//
12
//  A. Dannenberg
13
//  Texas Instruments Inc.
14
//  April 2006
15
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
16
//******************************************************************************
17
#include "msp430x22x4.h"
18
19
#define DELTA_1MHZ    244                   // 244 x 4096Hz = 999.4Hz
20
#define DELTA_8MHZ    1953                  // 1953 x 4096Hz = 7.99MHz
21
#define DELTA_12MHZ   2930                  // 2930 x 4096Hz = 12.00MHz
22
#define DELTA_16MHZ   3906                  // 3906 x 4096Hz = 15.99MHz
23
24
unsigned char CAL_DATA[8];                  // Temp. storage for constants
25
volatile unsigned int i;
26
int j;
27
char *Flash_ptrA;                           // Segment A pointer
28
void Set_DCO(unsigned int Delta);
29
30
void main(void)
31
{
32
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
33
  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization
34
  P1OUT = 0x00;                             // Clear P1 output latches
35
  P1DIR = 0x01;                             // P1.0 output
36
  P2SEL |= BIT2;                            // P2.1 SMCLK output
37
  P2DIR |= 0x02;                            // P2.1 output
38
39
  j = 0;                                    // Reset pointer
40
/*
41
  Set_DCO(DELTA_16MHZ);                     // Set DCO and obtain constants
42
  CAL_DATA[j++] = DCOCTL;
43
  CAL_DATA[j++] = BCSCTL1;
44
45
  Set_DCO(DELTA_12MHZ);                     // Set DCO and obtain constants
46
  CAL_DATA[j++] = DCOCTL;
47
  CAL_DATA[j++] = BCSCTL1;
48
49
  Set_DCO(DELTA_8MHZ);                      // Set DCO and obtain constants
50
  CAL_DATA[j++] = DCOCTL;
51
  CAL_DATA[j++] = BCSCTL1;
52
*/
53
  Set_DCO(DELTA_1MHZ);                      // Set DCO and obtain constants
54
  CAL_DATA[j++] = DCOCTL;
55
  CAL_DATA[j++] = BCSCTL1;
56
57
  Flash_ptrA = (char *)0x10C0;              // Point to beginning of seg A
58
  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
59
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
60
  FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits
61
  *Flash_ptrA = 0x00;                       // Dummy write to erase Flash seg A
62
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
63
  Flash_ptrA = (char *)0x10F8;              // Point to beginning of cal consts
64
  for (j = 0; j < 8; j++)
65
    *Flash_ptrA++ = CAL_DATA[j];            // re-flash DCO calibration data
66
  FCTL1 = FWKEY;                            // Clear WRT bit
67
  FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit
68
69
  while (1)
70
  {
71
    P1OUT ^= 0x01;                          // Toggle LED
72
    for (i = 0; i < 0x4000; i++);           // SW Delay
73
  }
74
}
75
76
void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
77
{
78
  unsigned int Compare, Oldcapture = 0;
79
80
  BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
81
  TBCCTL2 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
82
  TBCTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear
83
84
  while (1)
85
  {
86
    while (!(CCIFG & TBCCTL2));             // Wait until capture occured
87
    TBCCTL2 &= ~CCIFG;                      // Capture occured, clear flag
88
    Compare = TBCCR2;                       // Get current captured SMCLK
89
    Compare = Compare - Oldcapture;         // SMCLK difference
90
    Oldcapture = TBCCR2;                    // Save current captured SMCLK
91
92
    if (Delta == Compare)
93
      break;                                // If equal, leave "while(1)"
94
    else if (Delta < Compare)
95
    {
96
      DCOCTL--;                             // DCO is too fast, slow it down
97
      if (DCOCTL == 0xFF)                   // Did DCO roll under?
98
        if (BCSCTL1 & 0x0f)
99
          BCSCTL1--;                        // Select lower RSEL
100
    }
101
    else
102
    {
103
      DCOCTL++;                             // DCO is too slow, speed it up
104
      if (DCOCTL == 0x00)                   // Did DCO roll over?
105
        if ((BCSCTL1 & 0x0f) != 0x0f)
106
          BCSCTL1++;                        // Sel higher RSEL
107
    }
108
  }
109
  TBCCTL2 = 0;                              // Stop TACCR2
110
  TBCTL = 0;                                // Stop Timer_A
111
  BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
112
}

nur ist da irgent etwas falsch.
als taktquelle habe 4096Hz an P2.2

von Stefan (Gast)


Lesenswert?

Die Änderungen auf Timer_B sind falsch.
P2.2 kann als Timer_A.CCI0B genutzt werden wenn diese Funktion per P2SEL 
ausgewählt wird, sonst ist Timer_A.CCI0B intern mit ACLK verbunden.
Das Originalprogramm müsste mit nur einer kleinen Änderung laufen:
P2SEL |= 0x06;        // P2.1 SMCLK output, P2.2  CCI0B input

von mesut (Gast)


Lesenswert?

hallo stefan,

ich habe die zeile :
1
  P2SEL |= 0x02;                            // P2.1 SMCLK output

gegen diese ausgetauscht:
1
P2SEL |= 0x06;        // P2.1 SMCLK output, P2.2  CCI0B input

leider bleibt das programm nach wie vor an der zeile:
1
while (!(CCIFG & TACCTL0)); // Wait until capture occured
hängen und läuft nicht weiter.
habe ich an den einstellungen was falsch.


ich poste nochmal den ganzen code mit der veränderten zeile:
1
//******************************************************************************
2
//  MSP430F22x4 Demo - DCO Calibration Constants Programmer
3
//
4
//
5
//           MSP430F22x4
6
//         ---------------
7
//     /|\|            XIN|-
8
//      | |               | 32kHz
9
//      --|RST        XOUT|-
10
//        |               |
11
//        |           P1.0|--> LED
12
//        |           P2.1|--> SMLCK = target DCO
13
//
14
//  A. Dannenberg
15
//  Texas Instruments Inc.
16
//  April 2006
17
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
18
//******************************************************************************
19
#include "msp430x22x4.h"
20
21
#define DELTA_1MHZ    244                   // 244 x 4096Hz = 999.4Hz
22
#define DELTA_8MHZ    1953                  // 1953 x 4096Hz = 7.99MHz
23
#define DELTA_12MHZ   2930                  // 2930 x 4096Hz = 12.00MHz
24
#define DELTA_16MHZ   3906                  // 3906 x 4096Hz = 15.99MHz
25
26
unsigned char CAL_DATA[8];                  // Temp. storage for constants
27
volatile unsigned int i;
28
int j;
29
char *Flash_ptrA;                           // Segment A pointer
30
void Set_DCO(unsigned int Delta);
31
32
void main(void)
33
{
34
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
35
  for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization
36
  P1OUT = 0x00;                             // Clear P1 output latches
37
  P1DIR = 0x01;                             // P1.0 output
38
  P2SEL |= 0x06;                            // P2.1 SMCLK output, P2.2  CCI0B input
39
  P2DIR |= 0x02;                            // P2.1 output
40
41
  j = 0;                                    // Reset pointer
42
43
  Set_DCO(DELTA_16MHZ);                     // Set DCO and obtain constants
44
  CAL_DATA[j++] = DCOCTL;
45
  CAL_DATA[j++] = BCSCTL1;
46
47
  Set_DCO(DELTA_12MHZ);                     // Set DCO and obtain constants
48
  CAL_DATA[j++] = DCOCTL;
49
  CAL_DATA[j++] = BCSCTL1;
50
51
  Set_DCO(DELTA_8MHZ);                      // Set DCO and obtain constants
52
  CAL_DATA[j++] = DCOCTL;
53
  CAL_DATA[j++] = BCSCTL1;
54
55
  Set_DCO(DELTA_1MHZ);                      // Set DCO and obtain constants
56
  CAL_DATA[j++] = DCOCTL;
57
  CAL_DATA[j++] = BCSCTL1;
58
59
  Flash_ptrA = (char *)0x10C0;              // Point to beginning of seg A
60
  FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
61
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
62
  FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits
63
  *Flash_ptrA = 0x00;                       // Dummy write to erase Flash seg A
64
  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
65
  Flash_ptrA = (char *)0x10F8;              // Point to beginning of cal consts
66
  for (j = 0; j < 8; j++)
67
    *Flash_ptrA++ = CAL_DATA[j];            // re-flash DCO calibration data
68
  FCTL1 = FWKEY;                            // Clear WRT bit
69
  FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit
70
71
  while (1)
72
  {
73
    P1OUT ^= 0x01;                          // Toggle LED
74
    for (i = 0; i < 0x4000; i++);           // SW Delay
75
  }
76
}
77
78
void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
79
{
80
  unsigned int Compare, Oldcapture = 0;
81
82
  BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
83
  TACCTL2 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
84
  TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear
85
86
  while (1)
87
  {
88
    while (!(CCIFG & TACCTL2));             // Wait until capture occured
89
    TACCTL2 &= ~CCIFG;                      // Capture occured, clear flag
90
    Compare = TACCR2;                       // Get current captured SMCLK
91
    Compare = Compare - Oldcapture;         // SMCLK difference
92
    Oldcapture = TACCR2;                    // Save current captured SMCLK
93
94
    if (Delta == Compare)
95
      break;                                // If equal, leave "while(1)"
96
    else if (Delta < Compare)
97
    {
98
      DCOCTL--;                             // DCO is too fast, slow it down
99
      if (DCOCTL == 0xFF)                   // Did DCO roll under?
100
        if (BCSCTL1 & 0x0f)
101
          BCSCTL1--;                        // Select lower RSEL
102
    }
103
    else
104
    {
105
      DCOCTL++;                             // DCO is too slow, speed it up
106
      if (DCOCTL == 0x00)                   // Did DCO roll over?
107
        if ((BCSCTL1 & 0x0f) != 0x0f)
108
          BCSCTL1++;                        // Sel higher RSEL
109
    }
110
  }
111
  TACCTL2 = 0;                              // Stop TACCR2
112
  TACTL = 0;                                // Stop Timer_A
113
  BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
114
}

kannst du mir bitte nochmal einen tipp geben?

mfg mesut

von Stefan (Gast)


Lesenswert?

Ersetze mal alle TACCTL2 durch TACCTL0 und TACCR2 durch TACCR0.

von mesut (Gast)


Lesenswert?

hallo stefan,

hat alles wunderbar geklappt, bis auf die 16MHz kalibrierung da hängt 
sich das programm auf.ich brauche aber eh nur die 1MHz und 8Mhz daher 
reicht das für mich alle mal.

vielen dank nochmals du hast echt fett ein gut bei mir. wenn du um die 
gegend köln um rum wohnst, würde ich dir gerne ein ausgeben oder mich 
sonstig erkenntlich zeigen. Ohne dich hätte ich das wohl erst nach 
einigen Dutzend Nächten hinbekommen und bei meiner diplomarbeit hinke 
ich schon zeitlich gut hinterher.

mfg mesut

von Stefan (Gast)


Lesenswert?

Freut mich, dass ich helfen konnte.
Ich habe selbst bisher nur mit den kleineren MSP430 auf dem Launchpad 
gearbeitet und konnte daher keine fertige Lösung liefern sondern nur ein 
paar Hinweise geben. Dafür brauchst du mir keinen auszugeben. Köln ist 
dafür außerdem zu weit weg.
Dass die 16 MHz Kalibrierung nicht klappt könnte an einer zu niedrigen 
Versorgungsspannung für diese Taktfrequenz liegen.

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.