430 microcontrollers generally have an internal information area to save some data that requires EEPROM to save.
I didn't receive any relevant information in the forum, so I borrowed the information on the Internet to start a discussion. If you have any questions, please correct me and let's master it together!
The FLASH memory module of the MSP430 FLASH microcontroller is divided into several segments according to different capacities. The information memory SegmengA and SegmentB each have 128 bytes, and the other segments have 512 bytes. The address of SegmentB is: 0x1000 to 0x107F, and the address of SegmentA is: 0x1080 to 0x10FF. The addresses of other segments are allocated according to different capacities, starting from 0xFFFF, and every 512 bytes is allocated as a segment.
When writing data to the FLASH memory, each bit can only change from "1" to "0", and cannot change from "0" to "1". Therefore, when we have data to save to the FLASH memory, we must first perform an entire segment erase operation on the target segment. The erase operation makes the corresponding segment FLASH memory become all "1". The following is a subroutine for erasing a FLASH segment. After configuring the necessary registers, write data to any address in the segment and erase a segment.
Run the code Copy the code
void flash_clr(int *ptr)
{
_DINT(); //Disable interrupt
FCTL3 = 0x0A500; //* Lock = 0 Unlock
FCTL1 = 0x0A502; //* Erase = 1 Enable erasure
*((int *) ptr) = 0; //* Erase segment
}
The FLASH memory can be written either by byte or by word.
// Byte write
void flash_write_int8(int8_t *ptr, int8_t value)
{
_DINT();
FCTL3 = 0x0A500; // Lock = 0 unlock
FCTL1 = 0x0A540; // Write = 1 enable write
*((int8_t *) ptr) = value; // Write data
}
// Word write
void flash_write_int16(int16_t *ptr, int16_t value)
{
_DINT();
FCTL3 = 0x0A500; /* Lock = 0 */
FCTL1 = 0x0A540; /* Write = 1 */
*((int16_t *) ptr) = value; /* Program the flash */
}
The FLASH memory can be written continuously
// Write a specified amount of data in bytes
void flash_memcpy(char *ptr, char *from, int len)
{
_DINT();
FCTL3 = 0x0A500; /* Lock = 0 */
FCTL1 = 0x0A540; /* Write = 1 */
while (len)
{
*ptr++ = *from++;
len--;
}
}
In our application, we can put the data to be saved in a custom structure, for example:
typedef struct Setup
{
float gain_ch0; // 0 channel gain
float gain_ch1; // 1 channel gain
float gain_ch2; // 2 channel gain
...
char init_flag; //Initialization flag, always 0xAA;
}SETUP;
We define a SETUP structure to store the gains of three AD channels and other information to be saved when the power is turned off. The function of init_flag is to mark whether the FLASH parameters have been initialized correctly. After we set the FLASH parameters, we set init_flag to a fixed value, such as 0xAAh. When the program starts running, we check init_flag. When the value of init_flag is 0xAAh, it indicates that the parameters have been initialized.
Use FLASH parameters: define a pointer variable of type SETUP in the program, and access the parameters in FLASH through this pointer. For example:
Run the code Copy the code
#define SegmentA 0x1080
float temp;
SETUP *p_setup_flash = (SETUP *) SegmentA
if(p_setup_flash-> init_flag == 0xAA)
{
temp = p_setup_flash->gain_ch0;
}
Modify the FLASH information: Since FLASH cannot be directly modified like RAM, you can copy the FLASH information to RAM, modify the corresponding parameters, and then save it to the FLASH memory again. Before that, you must erase the FLASH storage area. For example:
Run the code to copy the code
SETUP *p_setup;
SETUP buf; // Temporary variable
p_setup = (SETUP *) SegmentA // Point to FLASH
memcpy((char *) buf, (char *) p_setup_flash, sizeof(SETUP)); // Copy to RAM
p_setup = &buf; // Point to RAM
p_setup-> gain_ch0 = 1.02; // Modify parameters
flash_memcpy((char *) p_setup_flash, (char *) buf, sizeof(SETUP)); // Copy to FLASH
|