Я нечто подобное уже давно проделываю в LPC2148, но только PLL я не отключаю, а пишу на тех же 60МГц и за 2 года никаких проблем с корректностью записи небыло.(работает около сотни приборов). В линковщике уменьшил размер програмного сегмента на 20кБ(остальные страницы не по 4, а по 20 кБ, поэтому только 5 страниц по 4 кБ, мне пока хватало)
//*************************************************************************
// Read-only segments mapped to ROM.
//*************************************************************************
-DROMSTART=00000040
-DROMEND=0x00077fff //было 0x0007CFFF
с-файл
#include "includes.h"
//*************************************************************************
//С адреса 0x00078000 начинается сегмент данных.
//Калибровочные константы и т.д.
//Сектор №22(0x16) 0x00078000 - 0x00078FFF 4096 байт
//Сектор №23(0x17) 0x00079000 - 0x00079FFF 4096 байт
//Сектор №24(0x18) 0x0007A000 - 0x0007AFFF 4096 байт
//Сектор №25(0x19) 0x0007B000 - 0x0007BFFF 4096 байт
//Сектор №26(0x1A) 0x0007C000 - 0x0007CFFF 4096 байт
//*************************************************************************
#pragma data_alignment=4//Выравнивание по 4 байтам
Flash_data Const_ram,*pConst_flash=(Flash_data*)ADR_FLASH_DATA;
Flash_data *pConst_ram=&Const_ram;
unsigned char Progress=0;
int WRITE_RAM_FLASH(void)
{
unsigned char* a;
pConst_ram->CRC=0;
pConst_ram->Control_Byte=0xa5;
for(a=(unsigned char*)pConst_ram;a<((unsigned char*)pConst_ram+(sizeof(Flash_data)-4));a++)
{
pConst_ram->CRC+=(unsigned int)*a;
}
unsigned int command[5];
unsigned int result[2];
/******************************************************************************/
//Стирание FLASH_DATA
IAP iap_entry=(IAP) IAP_LOCATION;
Progress=0;
command[0]=50;
command[1]=22;
command[2]=26;
__disable_interrupt();
iap_entry(command,result);
Progress=5;
__enable_interrupt();
command[0]=52;
command[1]=22;
command[2]=26;
command[3]=FCCLK/1000;
__disable_interrupt();
iap_entry (command,result);
Progress=20;
__enable_interrupt();
/*****************************************************************************/
char dprogress=80/((sizeof(Const_ram)+255)/256);
for(short klaster=0;klaster<((sizeof(Const_ram)+255)/256);klaster++)
{
command[0]=50;
command[1]=22;
command[2]=26;
__disable_interrupt();
iap_entry (command,result);
__enable_interrupt();
command[0]=51;
command[1]=ADR_FLASH_DATA+256*klaster;
command[2]=((unsigned int)&Const_ram)+256*klaster;
command[3]=256;
command[4]=FCCLK/1000;
__disable_interrupt();
iap_entry (command,result);
Progress+=dprogress;
if(Progress>100)Progress=100;
__enable_interrupt();
}
Progress=100;
return(0);
}
void load_data (void)
{
unsigned char* a;
pConst_ram->CRC=0;
for(a=(unsigned char*)pConst_flash;a<((unsigned char*)pConst_flash+(sizeof(Flash_data)-4));a++)
{
pConst_ram->CRC+=(unsigned int)*a;
}
if((pConst_flash->CRC!=pConst_ram->CRC)||(pConst_flash->Control_Byte!=0xa5))
{
pConst_ram->Serial=0;
pConst_ram->Att_00=0.0;
pConst_ram->Att_10=10.0;
pConst_ram->Att_20=20.0;
pConst_ram->Att_30=30.0;
pConst_ram->Att_40=40.0;
WRITE_RAM_FLASH();
}
*pConst_ram=*pConst_flash;
}
и h-файл
#ifndef __FlASH_H
#define __FlASH_H
//*************************************************************************
//С адреса 0x00078000 начинается сегмент данных.
//Калибровочные константы и т.д.
//Сектор №22(0x16) 0x00078000 - 0x00078FFF 4096 байт
//Сектор №23(0x17) 0x00079000 - 0x00079FFF 4096 байт
//Сектор №24(0x18) 0x0007A000 - 0x0007AFFF 4096 байт
//Сектор №25(0x19) 0x0007B000 - 0x0007BFFF 4096 байт
//Сектор №26(0x1A) 0x0007C000 - 0x0007CFFF 4096 байт
//******************************************************************************
#define ADR_FLASH_DATA 0x00078000
#define CMD_SUCCESS 0 //Команда успешно выполнена
#define INVALID_COMMAND 1 //Неправильная команда
#define SRC_ADDR_ERROR 2 //адрес в озу не выровнен по 2 байта
#define DST_ADDR_ERROR 3 //граница во Flash не выровнена по 256 байт
#define SRC_ADDR_NOT_MAPPED 4 //обращение по несуществующему адресу в озу
#define DST_ADDR_NOT_MAPPED 5 //обращение по несуществующему адресу во Flash
#define COUNT_ERROR 6 //неверно указано колличество байт
#define INVALID_SECTOR 7 //несуществующий номер сектора
#define SECTOR_NOT_BLANK 8 //Сектор не очищен
#define SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9 //Сектор небыл подготовлен для записи или стирания
#define COMPARE_ERROR 10 //Данные во Flash не соответствуют данным в озу
#define BUSY 11 //Устройство записи во Flash занято
//******************************************************************************
#define IAP_LOCATION 0x7ffffff1 //Адрес ботлодера
typedef struct
{
unsigned short Serial;//Серийный номер.
float Att_00;
float Att_10;
float Att_20;
float Att_30;
float Att_40;
unsigned char Control_Byte;
unsigned int CRC;
}Flash_data;
extern Flash_data Const_ram,*pConst_flash;
extern Flash_data *pConst_ram;
extern unsigned char Progress;
typedef void (*IAP)(unsigned int [],unsigned int[]);
int WRITE_RAM_FLASH(void);
void load_data (void);
#endif//__FlASH_H