写程序存储器
#define tmpBuffer[64] //是要写入的数据
#define ProgrammingBuffer[64] //临时缓存
//写FlashBlock(一个块为64字节)
void WriteFlashBlock(void) {
uint8_t i;
//将64字节读入RAM。
TBLPTRU = 0x00;
TBLPTRH = HIGH_BYTE(ProgrammedPointer);
TBLPTRL = LOW_BYTE(ProgrammedPointer);
for (i = 0; i < WRITE_BLOCK_SIZE; i++) {
asm("tblrdpostinc");
ProgrammingBuffer[i] = TABLAT;
}
//根据需要更新RAM中的数据值。
for (i = OffsetHead; i < OffsetTail; i++) {
ProgrammingBuffer[i] = tmpBuffer[i];
}
//用擦除的地址加载表指针寄存器。
TBLPTRU = 0x00;
TBLPTRH = HIGH_BYTE(ProgrammedPointer);
TBLPTRL = LOW_BYTE(ProgrammedPointer);
EECON1 = 0b10010100; //准备清除闪存
//执行行擦除过程。
UnlockAndActivate(CORRECT_UNLOCK_KEY);
asm("tblrdpostdec"); //参考手册写数据到FLASH程序内存的示例
// 用正在写入的第一个字节的地址加载表指针寄存器。
TBLPTRU = 0x00;
TBLPTRH = HIGH_BYTE(ProgrammedPointer);
TBLPTRL = LOW_BYTE(ProgrammedPointer);
//TBLPTRL = LOW_BYTE(ProgrammedPointer + OffsetHead);
// 用自动增量将64字节写入持有寄存器。
for (i = 0; i < WRITE_BLOCK_SIZE; i++) {
TABLAT = ProgrammingBuffer[i];
asm("tblwtpostinc");
}
asm("tblrdpostdec");
// 执行写过程。
EECON1 = 0b10000100; //设置 EECON1 寄存器来执行写操作:将 EEPGD 位置 1 以指向程序存储器,将 CFGS 位清零以访问程序存储器,将 WREN 置 1 以使能字节写操作.
UnlockAndActivate(CORRECT_UNLOCK_KEY); //执行写入flash操作
}
//激活并开始写入Flash
void UnlockAndActivate(unsigned char UnlockKey)
{
INTCONbits.GIE = 0; //禁用中断。
if(UnlockKey != CORRECT_UNLOCK_KEY)
{
OSCCON = 0x03; //切换到低频率的INTOSC
while(1)
{
Sleep(); //死循环
}
Reset(); //复位
}
读程序存储器
unsigned long addr32; // for PIC18FXXK80
unsigned char rdata[8];
addr32=0x2000;
TBLPTR = addr32;
//读取从0x2000地址开始的8字节数据
for (i = 0; i < 8; i++) {
asm("tblrdpostinc");
rdata[i] = TABLAT;
}
擦除程序存储器
void erase_device(void) {
unsigned int i;
//擦除用户代码(ROM中START_PAGE_TO_ERASE到MAX_PAGE_TO_ERASE的代码)
for (i = START_PAGE_TO_ERASE; i < (MAX_PAGE_TO_ERASE + 1); i++) {
ClrWdt(); //清除看门狗
#ifdef __XC8__
TBLPTRU = 0x00;
TBLPTRH = (uint8_t)(i >> 2);
TBLPTRL = (uint8_t)(i << 6);
#else
TBLPTR = i << 6; //指定要擦除的块地址
#endif
EECON1 = 0b10010100; //准备擦除
UnlockAndActivate(CORRECT_UNLOCK_KEY);
}