Hallo, ich möchte gerne einen Wert im Speicher des MSP430F247 ablegen, der allerdings nichtflüchtig ist. (Ähnlich wie beim Atmel im internen EEPROM). Hierfür bietet der MSP (möglicherweise?) einen Bereich, der sich "TLV structure" nennt. Ich schaffe es allerdings nur in die Register zu schreiben, in denen die Werte für die interne Takterzeugung und den ADC stehen. Diese Werte möchte ich ungerne überschreiben. Hat jemand damit bereits Erfahrung/Tipps gesammelt? Danke für eure Hilfe.
Hallo, dein MSP hat 256 Byte Configuration Flash. Da kann man es reinspeichern. Ich weiß nur nicht, ob das zur Laufzeit geht, die Antwort darauf liefert aber bestimmt der Family Guide. Aber ich denke, du möchtest es zur Laufzeit speichern, sonst könntest du es ja schon im Programm als const deklarieren. Gruß, Peter
Hallo, also ich habe das im MSPx1232 mal so realisiert. Funzt auch mit zugriff ausser main(). Den Bereich 0x1000 musst du im Handuch noch mal nachschauen ist bei jedem MSP anders.
1 | struct InfoBlock |
2 | {
|
3 | .......
|
4 | .......
|
5 | };
|
6 | |
7 | // daten im flash des Speichers ablegen!!!
|
8 | const struct InfoBlock *const infoBlock = (const struct InfoBlock *)0x1000; |
greetz
Dazu benutzt man das Information Memory. Dein MSP hat davon 4 Segmente a 64 Byte. Das ganze ist selbstverständlich auch zur Laufzeit beschreibbar, allerdings -wie bei Flash-Speicher so üblich- muss erst ein komplettes Segment gelöscht werden, bevor man Daten darin neu schreiben kann. User-Guide, Kapitel 7 "Flash Memory Controller". Codebeispiele wie immer bei TI Wenn Du mehr Daten zu speichern hast, kannst Du das auch im Programm-Flash ablegen. Zwischen Programm-Flash und Info-Flash gibt es, bis auf die Segmentgröße keinen Unterschied. Oder andersrum, kann man auch Programmcode ins Info ablegen! Das kann man im Linker-File einstellen.
Danke für die Antworten. Ich habe jetzt versucht mit dem Codebeispiel msp430x24x_flashwrite_01.c von TI auf das SegmentC zu schreiben. Sobald ich die Versorgungsspannung (nach Programmdurchlauf) wieder wegnehme und erneut anschließe, steht wieder nur 0xff im Speicher von SegmentC. PS: meine Versorgungspannung beträgt 3V (also mehr als die benötigten 2,2V) hier noch der Code:
1 | //******************************************************************************
|
2 | // MSP-430F22x4 Demo - Flash In-System Programming, Copy SegC to SegD
|
3 | //
|
4 | // Description: This program first erases flash seg C, then it increments all
|
5 | // values in seg C, then it erases seg D, then copies seg C to seg D. Starting
|
6 | // addresses of segments defined in this code: Seg C-0x1040, Seg D-0x1000.
|
7 | // ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
|
8 | // //* Set Breakpoint on NOP in the Mainloop to avoid Stressing Flash *//
|
9 | //
|
10 | // MSP430F249
|
11 | // -----------------
|
12 | // /|\| XIN|-
|
13 | // | | |
|
14 | // --|RST XOUT|-
|
15 | // | |
|
16 | //
|
17 | // B. Nisarga
|
18 | // Texas Instruments Inc.
|
19 | // September 2007
|
20 | // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A
|
21 | //******************************************************************************
|
22 | #include "msp430x24x.h" |
23 | |
24 | char value; // 8-bit value to write to seg C |
25 | |
26 | // Function prototypes
|
27 | void write_SegC(char value); |
28 | void read_SegC(void); |
29 | |
30 | void main(void) |
31 | {
|
32 | WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer |
33 | if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) |
34 | {
|
35 | while(1); // If calibration constants erased |
36 | // do not load, trap CPU!!
|
37 | }
|
38 | BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz |
39 | DCOCTL = CALDCO_1MHZ; |
40 | FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator |
41 | value = 0; // initialize value |
42 | |
43 | while(1) // Repeat forever |
44 | {
|
45 | read_SegC(); |
46 | write_SegC(BIOS_value++); // Write segment C, increment value |
47 | }
|
48 | }
|
49 | |
50 | void read_SegC(void) |
51 | {
|
52 | char value; |
53 | char *Flash_ptr; // Flash pointer |
54 | unsigned int i; |
55 | |
56 | Flash_ptr = (char *)0x1040; // Initialize Flash pointer |
57 | |
58 | for (i = 0; i < 64; i++) |
59 | {
|
60 | value = *Flash_ptr++; // Write value to flash |
61 | }
|
62 | }
|
63 | |
64 | void write_SegC(char value) |
65 | {
|
66 | char *Flash_ptr; // Flash pointer |
67 | unsigned int i; |
68 | |
69 | Flash_ptr = (char *)0x1040; // Initialize Flash pointer |
70 | FCTL3 = FWKEY; // Clear Lock bit |
71 | FCTL1 = FWKEY + ERASE; // Set Erase bit |
72 | *Flash_ptr = 0; // Dummy write to erase Flash seg |
73 | |
74 | FCTL1 = FWKEY + WRT; // Set WRT bit for write operation |
75 | |
76 | for (i = 0; i < 64; i++) |
77 | {
|
78 | *Flash_ptr++ = value; // Write value to flash |
79 | }
|
80 | |
81 | FCTL1 = FWKEY; // Clear WRT bit |
82 | FCTL3 = FWKEY + LOCK; // Set LOCK bit |
83 | }
|
Hallo, was steht denn drin, wenn du das geschriebene ausließt, ohne zwischenzeitlich die Spannung abzuschalten? Vielleicht wird ja garnichts geschrieben. Peter
Hallo, warum schreibst du eigentlich 64 Byte mit dem gleichen Wert value voll, einer würde doch zum Testen ausreichen. Wo gibst du value überhaupt aus? Über den Degugger? Es kann sein, dass mit dem Degubber keine Flashoperationen zulässig sind, bzw. das Timing nicht stimmt. Peter
Das obige Programm kann überhaupt gar nicht funktionieren. "BIOS_value" ist nirgends definiert, der Compiler müsste mit Fehler abbrechen!
@ Peter Diener: Wenn ich nach dem Schreiben die Adressen erneut auslese, sehe ich auch meine geschriebenen Werte. Nach einem Reset steht wieder 0xff drin. Das ich gleich die ganzen 64 Byte schreibe habe ich gemacht, da ich den Beispielcode von TI möglichst unverändert übernehmen wollte. Die Variable "value" lasse ich mir beim debuggen direkt anzeigen. @ Stefan : Sorry, den Wert "BIOS_value" habe ich vergessen wieder zurück zu ändern. Um Verwirrung zu vermeiden, wollte ich nicht meinen ganzen Code ins Forum einfügen.
Hallo, prinzipiell solte das aber funktionieren. Ich kann mir aber vorstellen, dass das Timing nicht stimmt. Im User Guide steht: The flash timing generator operating frequency, fFTG, must be in the range from ~ 257 kHz to ~ 476 kHz Außerdem verändert deine Read Segment Funktion value nicht, dort ist es ja neu definiert. Werf die Definition raus! Peter
Riesen DANKESCHÖN an euch. Peter Diener hatte Recht. Es lag daran, dass ich mir die Werte im Debugg-Modus angesehen habe. Im Run-Modus funktioniert jetzt endlich alles. War mittlerweile echt am verzweifeln.
Hallo, freut mich, dass es funktioniert. Was mir gerade noch aufgefallen ist: Wenn du nicht im Debugmodus arbeitest, ist dieser code sehr gefährlich:
1 | while(1) // Repeat forever |
2 | {
|
3 | read_SegC(); |
4 | write_SegC(BIOS_value++); // Write segment C, increment value |
5 | }
|
Das schreibt beliebig oft das Flash, daduch wird es auf Dauer zerstört, es sind nur etwa 10000 Löschzyklen zulässig. Aber vielleicht hast du das ja schon nicht mehr drin. Viele Grüße, Peter
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.