📄 flash.c
字号:
/*---------------------------------------------------*/
/* Flash 操作程序
Description: 本程序最主要是读写/扇区搽除/片搽除,以及主要的调用程序
源程序时使用AMD 公司s29gl032m,现在修改为sst公司sst36vf03203
这样,需要增加扇区搽除,以及修改存储流程
*/
/*--------------------------------------------------*/
/*-------------------------------------------------*/
#include "defineh.h"
#include "flash.h"
#include "sbitdef.h" //test
/*-------------------------------------------------*/
extern uchar Dec_Cem(uchar dec_data);
extern void delay();
extern void Clr_Rx();
extern void init_timer2();
extern void clr_timer2();
extern uchar idata Tx_buffer[16]; //test
extern void txstart();
extern void delays60ms();
/*------------------------------------------------*/
void Chip_Erase_Op()
{
uchar xdata *mm;
AUXR=0x03;
P1=0;
mm=0xaaa;
*mm=0xaa;
mm=0x555;
*mm=0x55;
mm=0xaaa;
*mm=0x80;
mm=0xaaa;
*mm=0xaa;
mm=0x555;
*mm=0x55;
mm=0xaaa;
*mm=0x10;
delay();
delay();
AUXR=0x00;
}
/*---------------------------------------------*/
void Sector_Erase_Op(ulong write_address)
{
ulong data temp;
uchar data i;
uchar xdata *mm;
temp=write_address;
AUXR=0x03;
i=(uchar)(temp>>16);
P1=i;
mm=0xaaa;
*mm=0xaa;
mm=0x555;
*mm=0x55;
mm=0xaaa;
*mm=0x80;
mm=0xaaa;
*mm=0xaa;
mm=0x555;
*mm=0x55;
mm=(uint)(temp);
*mm=Flash_Write; //if 36vf3202,=0x50
delay(); //>18ms
AUXR=0x00;
}
/*-------------------------------------------------*/
/* Rwad Message Group
DESCRIPTION:
读取信息的编号,需要带页地址来
每一次读出8字节
*/
/*-----------------------------------------------------*/
void Page_Read_Op()
{
uchar data i;
uint data j;
uchar xdata *mm;
i=(uchar)(read_block>>16);
P1=i;
j=(uint)(read_block);
AUXR=0x03;
for(i=0;i<18;i++)
{
mm=j+i;
message_group[i]=*mm;
}
AUXR=0;
}
/*---------------------------------------------*/
/*
根据偏移位置和目前编号,保存在地址write_block
注意寄存器 write_block,infonumber
*/
/*--------------------------------------------*/
void save_infomessage()
{
ulong data y;
uint data k;
uchar data i,j;
uchar xdata *mm;
y=write_block;
AUXR=0x03;
i=(uchar)(y>>16);
P1=i; //a15---a22 had out from p1
y=write_block;
k=(uint)(y);
EA=0;
for(j=0;j<(infonumber+1);j++)
{
mm=0xaaa;
*mm=0xaa; //program step 1
mm=0x555;
*mm=0x55; //program step 2
mm=0xaaa;
*mm=0xa0; //program step 3 ,not 0x80????test
mm=k+j;
if(j==0)
{
*mm=message_group[offset_smallest];
}
else
{
AUXR=0X00;
i=*(info_buffer+4+j);
AUXR=0X03;
*mm=i;
}
}
delay();
AUXR=0X00;
EA=1;
}
/*-------------------------------------*/
/* 把使用区域的除最旧区域以外信息复制到count_copy指定的区域
首先确定被复制的区域地址,由read_block决定
*/
/*----------------------------------*/
void Copy_Message()
{
uchar data i,j,m,k;
uchar xdata *mm;
EA=0;
AUXR=0X03;
if((offset_smallest!=0)&&(offset_smallest!=15)) //最小的信息在中间
{
for(k=0;k<offset_smallest;k++)
{
mm=read_block+k*0x100+1;
m=*mm;
for(j=0;j<(m+1);j++)
{
mm=read_block+k*0x100+j;
i=*mm;
//writing to the new zone a byte
mm=0x0aaa;
*mm=0xaa; //step 1
mm=0x0555;
*mm=0x55; //step 2
mm=0x0aaa;
*mm=0xa0; //step 3
mm=0x10000+count_copy*0x1000+k*0x100+j;
*mm=i;
}
}
for(k=(offset_smallest+1);k<16;k++)
{
mm=read_block+k*0x100+1;
m=*mm;
for(j=0;j<(m+1);j++)
{
mm=read_block+k*0x100+j;
i=*mm;
//writing to the new zone a byte
mm=0x0aaa;
*mm=0xaa; //step 1
mm=0x0555;
*mm=0x55; //step 2
mm=0x0aaa;
*mm=0xa0; //step 3
mm=0x10000+count_copy*0x1000+k*0x100+j;
*mm=i;
}
}
}
else if(offset_smallest==0)
{
for(k=(offset_smallest+1);k<16;k++)
{
mm=read_block+k*0x100+1;
m=*mm;
for(j=0;j<(m+1);j++)
{
mm=read_block+k*0x100+j;
i=*mm;
//writing to the new zone a byte
mm=0x0aaa;
*mm=0xaa; //step 1
mm=0x0555;
*mm=0x55; //step 2
mm=0x0aaa;
*mm=0xa0; //step 3
mm=0x10000+count_copy*0x1000+k*0x100+j;
*mm=i;
}
}
}
else //offset_smallest=15
{
for(k=0;k<offset_smallest;k++)
{
mm=read_block+k*0x100+1;
m=*mm;
for(j=0;j<(m+1);j++)
{
mm=read_block+k*0x100+j;
i=*mm;
//writing to the new zone a byte
mm=0x0aaa;
*mm=0xaa; //step 1
mm=0x0555;
*mm=0x55; //step 2
mm=0x0aaa;
*mm=0xa0; //step 3
mm=0x10000+count_copy*0x1000+k*0x100+j;
*mm=i;
}
}
}
EA=1;
AUXR=0X00;
}
/*----------------------------------------*/
/* 把整体从暂时区域复制 过来到使用区
使用寄存器read_block ,count_copy
*/
/*-----------------------------------*/
transfer_infomation()
{
uchar data i,j,m,k;
uchar xdata *mm;
EA=0;
AUXR=0X03;
for(k=0;k<16;k++)
{
mm=0x10000+count_copy*0x1000+k*0x100+1;
m=*mm;
//count_copy计算暂时区域的位置,k计算0---15的256字节,j直接的偏移
for(j=0;j<(m+1);j++)
{
mm=0x10000+count_copy*0x1000+k*0x100+j;
i=*mm;
//writing to the new zone a byte
mm=0x0aaa;
*mm=0xaa; //step 1
mm=0x0555;
*mm=0x55; //step 2
mm=0x0aaa;
*mm=0xa0; //step 3
mm=read_block+k*0x100+j;
*mm=i;
}
}
EA=1;
AUXR=0X00;
}
/*--------------------------------------*/
/*
统计最大、最小值
*/
void Count_BigandSmall()
{
uchar data i;
// count out the offset address
offset_biggest=0;
offset_smallest=0x99;
for(i=0;i<16;i++)
{
if(message_group[i]>0x99) //if not been writed,data will >99!!
{
message_group[i]=0;
}
if( message_group[i]>offset_biggest )
{
offset_biggest = message_group[i]; //count bigest num
}
if( message_group[i]<offset_smallest)
{
offset_smallest=message_group[i]; //count smallest num
}
}
}
/*----------------------------------------------------*/
/* Set the Offset place
描述:找出最小编号的位置,还有最大编号,这样就知道所有信息了。
最小编号位置可以写进当前偏移信息,最大编号可以知道是不是满了
*/
/*----------------------------------------------------*/
void Set_Offset()
{
uchar data i;
if(offset_biggest!=0) //已经有信息了,不是全部为空
{
for(i=0;i<16;i++)
{
if(offset_biggest<16) //有空位置
{
if(message_group[i]==offset_biggest)
{
offset_smallest=i+1; //record the place ,not number
offset_biggestplace=i;
}
}
else
{
if(message_group[i]==offset_biggest)
{
if(i==15)
{
offset_biggest=16;
offset_smallest=0;
offset_biggestplace=i;
}
else
{
offset_biggest=16;
offset_smallest=i+1;
offset_biggestplace=i;
}
}
}
}
}
else //全部为空
{
offset_biggest=0;
offset_smallest=0;
offset_biggestplace=0;
for(i=0;i<16;i++)
{
message_group[i]=0;
}
}
}
/*--------------------------------------------*/
/* Count Flash Offset
Desription:
判断那个位置的信息是最老的,每一次都把编号读出来,
然后重新排列,放置在message_group[16]里面,在移动过来以后
就把他们修改过来。
使用变量:
*/
/*---------------------------------------------*/
void Count_Flash_Offset()
{
uint data m;
uchar data i;
uchar xdata *mm;
AUXR=0x03;
i=(uchar)(read_block>>16);
P1=i;//16~23
m=(uint)(read_block);
for(i=0;i<16;i++)
{
mm=m+i*0x100;
message_group[i]=*mm;
_nop_();
}
Count_BigandSmall();
Set_Offset();
AUXR=0x00;
}
/*---------------------------------------------*/
/* 重新排列大小编号
*/
/*-------------------------------------------*/
Offset_Resize()
{
uchar data i;
if(offset_biggest==0)
{
message_group[0]=1;
}
else if(offset_biggest<16) //没有满
{
for(i=0;i<16;i++)
{
if(i==offset_smallest)
{
message_group[i]=offset_biggest+1;
}
}
}
else //满了
{
for(i=0;i<16;i++)
{
if(i==offset_smallest)
{
message_group[i]=16;
}
else
{
message_group[i]=message_group[i]-1;
}
}
}
}
/*------------------------------------------------------*/
/* Save Message To Specified Flash Address
Desription: save the receive message frame to the specified address flash
if the address low than 0x1000,must be public
所有信息只能看,不能够删除 !!
*/
/*------------------------------------------------------*/
void Save_Message_Flash()
{
ulong data t;
//房号<33..读编号x0x10,读信息x1000
if(lounumH!=0)
{
read_block=((Dec_Cem(lounumH)+Dec_Cem(lounumL-1)/0x10)*0x20+Dec_Cem(lounumL-1)%0x10)*0x01000;
}
else
{
read_block=0x00000000;
}
t=read_block;
Count_Flash_Offset(); //找出最老时间存储的短信息位置,地址指示在offset_smallest
if(offset_biggest>15) //需要搽除信息扇区
{
//不是公共信息,等待应答,如果时间到没有应答,搽除本暂时扇区,退出;有就全部转移到指定区域
/*
if(lounumH!=0)
{
init_timer2();
while((timeout2<0x64)&&(EnWork_bit==0))
{
if(Rx_bit==1)
{
if((Rx_count==7)&&(*(info_buffer+1)==EXTBACK))
{
EnWork_bit=1;
}
Clr_Rx();
}
}
clr_timer2();
}
if((EnWork_bit==1)||(lounumH==0)) //answer ok or public message
{
*/
if(count_copy>15)
{
count_copy=0;
}
else
{
count_copy++;
}
Offset_Resize();
write_block=0x10000+count_copy*0x1000+offset_smallest*0x100;
save_infomessage(); //save to temp zone
Clr_Rx();
Copy_Message(); //from read_block to temp zone
Sector_Erase_Op(t);
transfer_infomation();
Sector_Erase_Op(0x10000+count_copy*0x1000);
// }
}
//空间还没有存储满,不用把使用扇区搽除
else
{
/*
if(lounumH!=0)
{
init_timer2();
while((timeout2<0x64)&&(EnWork_bit==0))
{
if(Rx_bit==valid)
{
if((Rx_count==7)&&(*(info_buffer+1)==EXTBACK))
{
EnWork_bit=1;
Clr_Rx();
}
else
{
Clr_Rx();
}
}
}
clr_timer2();
}
if((EnWork_bit==1)||(lounumH==0)) //answer ok
{
*/
write_block=t+offset_smallest*0x100;
message_group[offset_smallest]=message_group[offset_smallest]+1;
save_infomessage();
Clr_Rx();
// }
}
EnWork_bit=0;
}
/*-----------------------------------------------*/
/*
bit Read_ID_Op()
{
// For BYTE mode: (Depends on system application)
uchar i;
AUXR=0x03; //out ram read/write enable
_nop_();
_nop_();
P1=0;
XBYTE[0xaaaa]=0xaa;
XBYTE[0x5555]=0x55;
XBYTE[0xaaaa]=0x90;
_nop_();
i=XBYTE[0x0002]; // read mfr.ID
if(i == 0x7e)
{
i=XBYTE[0x001c];
if(i != 0x00)
{
i=XBYTE[0x001e];
if(i != 0x1a)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
else
{
return( FALSE);
}
}
else
{
return(FALSE);
}
XBYTE[0xaaaa]=0xaa;
XBYTE[0x5555]=0x55;
XBYTE[0xaaaa]=0xf0;
AUXR=0;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -