MSP430G2553 的Flash分为 主Flash和 信息Flash
主flash就是存储程序的
信息flash就是我们可以存储我们想要存储的数据的
信息存储器的大小是256byte ,分为4个64byte的存储段
flash的是能一个地址一个地址的写 , 但是只能整段擦除
#define SegA 0x010C0
#define SegB 0x01080
#define SegC 0x01040
#define SegD 0x01000
上面是各个段的其实地址
经我的发现 , SegA不能写 , 里面可能放了单片机的一些数据吧, 还是不要强制擦除了
所以实际可用的是有192byte
还有一点就是flash里面的数据只能又"1"变为"0" , 不能又 "0"变为"1", 所以写的时候要注意
大概函数分为
flash初始化
段擦除
向某个地址写数据
向某个地址读数据
向某个地址修改数据
连续写数据
flash初始化
void FlashInit() //select clock & divider
{
FCTL2 = FWKEY + FSSEL_2 + FN1; //选择时钟SMCLK 2 分频
}
段擦除
void FlashErase(int SegX)
{
_DINT(); //关中断
FlashCheckBusy(); //检忙
FCTL3 = FWKEY ; //lock = 0 开锁
FCTL1 = FWKEY + ERASE; //使能段擦除
*((int *)SegX) = 0x00; //段擦除
FlashCheckBusy(); //检忙
FCTL3 = FWKEY | LOCK; //lock = 1 上锁
}
向某个地址写数据
void FlashWriteChar(unsigned int addr , char wdata)
{
_DINT(); //关中断, 防止读写的时候发生意外
FlashCheckBusy(); //检忙
FCTL3 = FWKEY; //开锁
FCTL1 = FWKEY + WRT; //准备写
*((unsigned char *)addr) = wdata; //写
FCTL1 = FWKEY; //
FCTL3 = FWKEY + LOCK; //上锁
return ;
}
向某个地址读数据
char FlashReadChar(unsigned int addr)
{
char rdata;
rdata = *(char *)addr;
return rdata;
}
连续写数据
void FlashBurstWrite(int SegX , int *pStr)
{
int i = 0;
FlashErase(SegX);
FCTL3 = FWKEY ; //lock = 0 开锁
FCTL1 = FWKEY + WRT; //
for(i = 0 ; i < sizeof(pStr) ; i ++)
{
*(unsigned char *)(SegX + i) = *(pStr + i);
}
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}
连续读我不提供 , 我不能什么都做完了吧 , 即使后面的程序包里我也删除了的
其实很简单 , 就是地址加 , 再读 , 一个循环就搞定了
下面是修改某个地址的数据
因为msp430只能只能整段擦除 , 所以修改某个地址的数据的话过程比较复杂 , 其实还是挺简单的
先把要修改的那一段存入缓存数组 --> 修改要修改地址的数据 --> 再写入那一段 -->搞定
void FlashModifyChar(uint SegX, char AddrNum , char wdata)
{
char i,TempArry[SegSize];
for ( i = 0 ; i < SegSize ; i ++) //读入内存
{
TempArry = *(uint *)(SegX + i);
}
TempArry[AddrNum] = wdata;
FlashErase(SegX);
FCTL3 = FWKEY ; //lock = 0 开锁
FCTL1 = FWKEY + WRT; //
for (i = 0 ; i < SegSize ; i ++)
{
*(unsigned char *)(SegX + i) = TempArry;
}
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}
提醒大家一句flash的读写要注意数据类型 , 不然的话flash的数据的读写不会像你要求的那样读写 ,
多用调试 ,
写程序的时候多用宏定义 , 使程序的移植性更好
|