Forum: Mikrocontroller und Digitale Elektronik kann man nichtflüchtige Werte im MSP ablegen?


von Hans W. (hans_wurst)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

Das Zauberwort heisst Flash Speicher.

von Peter Diener (Gast)


Lesenswert?

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

von Stephan Pl. (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

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.

von Hans W. (hans_wurst)


Lesenswert?

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
}

von Peter Diener (Gast)


Lesenswert?

Hallo,

was steht denn drin, wenn du das geschriebene ausließt, ohne 
zwischenzeitlich die Spannung abzuschalten?

Vielleicht wird ja garnichts geschrieben.

Peter

von Peter Diener (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

Das obige Programm kann überhaupt gar nicht funktionieren.
"BIOS_value" ist nirgends definiert, der Compiler müsste mit Fehler 
abbrechen!

von Hans W. (hans_wurst)


Lesenswert?

@ 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.

von Peter Diener (Gast)


Lesenswert?

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

von Hans W. (hans_wurst)


Lesenswert?

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.

von Peter Diener (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.