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
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 | }
|
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
danke für die antwort werde es gleich mal ausprobieren
kannst du mir einen tipp geben wie ich den timer einzustellen habe. ich bekomme das irgentwie nicht hin. mfg mesut
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
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
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
Ersetze mal alle TACCTL2 durch TACCTL0 und TACCR2 durch TACCR0.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.