STC官方给出的建议:

1 /***************************************************************Author:Liming***
2 * @brief 读取参数
3 * @param None
4 * @retval None
5 ****************************************************************0x49E7FC7B*****/
6 void ReadParam(void)
7 {
8 uint8_t i;
9 uint8_t buffer[64][8];//1扇区分为64块存储区 1块内的8个字节
10
11 EepromReadBytes(IAP_SECTOR0, &buffer[0][0], 0x200);
12
13 #ifdef DEBUG
14 for(i=0; i<64; i++)//调试模式输出数据
15 {
16 SendBytes(&buffer[i][0], 8);
17 SendString("\r\n");
18 Delay(25);
19 }
20 #endif
21
22 for(i=0; i<64; i++)
23 {
24 if((buffer[i][0] == 0xff) && buffer[i][1] != 0xff)
25 {
26 LocalID = buffer[i][1];
27 return;
28 }
29 }
30 }
31
32
33 /***************************************************************Author:Liming***
34 * @brief 保存参数
35 针对STC单片机Flash作为EEPROM,0只能通过扇区擦除才能变为1,但是1可以
36 写入改为0,发现如果对单个字节写入一次数据比如0x63,再写入0x00,读出的值为0x40并
37 不是理论上的0x00,但第一次写入数据都没问题。所以采用以下方法:
38 一扇区512字节以8字节为一块分为64块,每一块的第一字节为标志位,如果为0xff则后面
39 的7字节为有效数据,如果为0x00则后面的7字节已经作废。
40 * @param
41 * @retval None
42 ****************************************************************0x49E7FC7B*****/
43 void SaveParam(void)
44 {
45 uint8_t i;
46 uint8_t buffer[64][8];//1扇区分为64块存储区 1块内的8个字节
47
48 EepromReadBytes(IAP_SECTOR0, buffer, 0x200);
49
50 for(i=0; i<64; i++)
51 {
52 if((buffer[i][0] == 0xff) && (buffer[i][1] == 0xff))
53 {
54 IapProgramByte(IAP_SECTOR0+(i*8)+1, LocalID);
55 if(i != 0x00)
56 {
57 IapProgramByte(IAP_SECTOR0+(i*8)-8, 0x00);//用过的存储块更改标志
58 }
59 return;
60 }
61 }
62 IapEraseSector(IAP_SECTOR0);
63 IapProgramByte(IAP_SECTOR0+1, LocalID);
64 }