STC12C5A16S2內(nèi)部Flash讀寫
一、扇區(qū)經(jīng)擦除后,扇區(qū)內(nèi)的各字節(jié)均為oxff,可以進(jìn)行寫操作,即字節(jié)編程,若扇區(qū)的某一字節(jié)不是0xff,則無法將字節(jié)中為0的位寫成1。所以保險的方法是先進(jìn)行扇區(qū)擦除,即只有扇區(qū)擦除才能將扇區(qū)的0變成1。
二、如果在一個扇區(qū)中存放了大量的數(shù)據(jù),某次只需要修改其中的一個字節(jié)或一部分字節(jié)時,則另外的不需要修改的數(shù)據(jù)須先讀出放在STC單片機(jī)的RAM中,然后擦除整個扇區(qū),再將需要保留的數(shù)據(jù)和需修改的數(shù)據(jù)按字節(jié)逐字節(jié)寫回該扇區(qū)中(只有字節(jié)寫命令,無連續(xù)字節(jié)寫命令)。這時每個扇區(qū)使用的字節(jié)數(shù)是使用的越少越方便(不需讀出一大堆需保留數(shù)據(jù))。
三、扇區(qū)中進(jìn)行多字節(jié)寫入時,首先進(jìn)行扇區(qū)擦除,然后進(jìn)行字節(jié)編程,地址是次扇區(qū)內(nèi)的首地址和末地址中的任何一個地址
////////////////////內(nèi)部flash操作函數(shù)
sfr IAP_DATA=0x0c2;
sfr IAP_ADDRH=0xc3;
sfr IAP_ADDRL=0xc4;
sfr IAP_CMD=0xc5;
sfr IAP_TRIG=0xc6;
sfr IAP_CONTR=0xc7;
//扇區(qū)字節(jié)讀
unsigned char read(unsigned char adder_h,unsigned char adder_l)
{
unsigned char dat;
IAP_ADDRH=adder_h;
IAP_ADDRL=adder_l;
IAP_CONTR=0x82;
IAP_CMD=0x01;
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
//nop;
dat=IAP_DATA;
return dat;
}
//扇區(qū)字節(jié)寫
void write(unsigned char adder_h,unsigned char adder_l,unsigned char dat)
{
IAP_DATA=dat;
IAP_ADDRH=adder_h;
IAP_ADDRL=adder_l;
IAP_CONTR=0x82;
IAP_CMD=0x02;
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
//nop;
}
void del(unsigned char adder_h,unsigned char adder_l)
{
IAP_ADDRH=adder_h;
IAP_ADDRL=adder_l;
IAP_CONTR=0x82;
IAP_CMD=0x03;
IAP_TRIG=0x5a;
IAP_TRIG=0xa5;
}
//把設(shè)置的鬧鐘值存進(jìn)單片機(jī)內(nèi)部flash函數(shù)
void restore(unsigned char hour,unsigned char min)
{
del(0x00,0x00);//將扇區(qū)內(nèi)的每個字節(jié)都變成0xff
delay_5ms();
write(0x00,0x00,hour);//第一個扇區(qū)的第一個地址存放設(shè)置的小時值
delay_5ms();
write(0x02,0x00,min);//第二個扇區(qū)的第一個地址存放設(shè)置的fen值
}