// 参数: adr 为地址 , 范围 0x1000~0xFFFF
voidFlashRead(long adr,uint8 *bBuf,uint8 bLen)
{
while (bLen--)
*bBuf++=*(uint8 *)adr++;
return;
}
本文引用地址:
//m.amcfsurvey.com/article/201611/321246.htm
// 写入地址 adr写入数据:*pc_byte
void FlashWrite(long adr,uchar *Datain,uint len)
{
//FCTL2 = FWKEY + FSSEL_1 + FN3 + FN4;//MCLK16*FN4 + 8*FN3
FCTL3 = FWKEY;
FCTL1 = FWKEY + WRT;
while(FCTL3 & BUSY);//如果处于忙状态,则等待
while(count--)
{
while(FCTL3 & BUSY);
*(uchar*)adr++ = *Datain++;
}
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
while(FCTL3 & BUSY);
}
EraseSectorFlash过程
void EraseSectorFlash(unsigned int adr)
{
_DINT();
uchar *p0;
//FCTL2 = FWKEY + FSSEL_1 + FN3 + FN4;//选择时钟源,分频
FCTL3 = FWKEY;//清除LOCK
while(FCTL3 & BUSY);//如果出于忙,则等待
FCTL1 = FWKEY + ERASE;//使能段操作每段512字节
p0 = (unsigned char *)adr;//数值强制转换成指针
*p0 = 0;//向段内任意地址写0,即空写入,启动擦除操作
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
while(FCTL3 & BUSY);
_EINT();//开总中断
}
查看空闲的FLASH 地址,避免擦除代码所在的地址。每次擦除均是一段一段的擦除,每段512字节。
找不到datasheet,不知道段的起止地址的,可以打开memory ,在内存窗口,用代码尝试随便写入一个任意地址,看哪些地方被改写成0xFF 就知道段的起止,如:
我们在0x15000写入(EraseSectorFlash(0x15000);),那里原本有非0xFF数据,好辨认(是FF的可以先写再擦)。看到段的起止是15000-151ff 刚好是512 。
0x15000+0x200->0x15200 所以下一段的起始地址是 0x15200 以此类推。
验证代码:
EraseSectorFlash(0x2A000);
EraseSectorFlash(0x2A200);
EraseSectorFlash(0x2A400);
EraseSectorFlash(0x2A600);
FlashWrite(0x2A000,origin_protect_data,512);
memset(origin_protect_data,0xCB,900);
FlashWrite(0x2A200,origin_protect_data,512);
memset(origin_protect_data,0xCA,900);
FlashWrite(0x2A400,origin_protect_data,512);
memset(origin_protect_data,0xC9,900);
FlashWrite(0x2A600,origin_protect_data,512);
编译地址分配:
在IAR窗口中,点击view》memory ,在内存窗口,点下拉框选择 SER 可知,SFR地址为
0x0000-0fff
RAM地址为:0x1c00-5bff
FLASH地址:0x5c00-45bff
结合看下面的地址分配图,即可知道各部分代码和数据被分配到什么地方。
****************************************
*
*
*
SEGMENTS IN ADDRESS ORDER
*
*
*
****************************************
SEGMENT
SPACE
START ADDRESS
END ADDRESS
SIZE
TYPE
ALIGN
=======
=====
=============
===========
====
====
=====
DATA16_AN
0102 - 0103
2
rel
0
0120 - 0121
2
0140 - 0141
2
0144 - 0145