使用stm32精英版开发板,外置sd卡,
使用fat32记录固定容量数据的方法,当出现新故障,自动替换掉最旧记录的简易方法
思路,在写入记录一行一行往下记录,当超过要最多的记录时,文件指针返回到首地址开始记录。这样的话就会出现如果断电,程序重新开始,无法知哪条记录为最新,所以,在写入记录前,加入标志符,为最新的记录,前面标志符为1,其余都为0,程序便知道文件的最新记录为哪一条
typedef struct
{
int old_adr;//一条内容的起点,
int adr;//一条内容的终点
int sum_row;//当前有多少行,防止轮回写记录的时候,导致后面记录消失
int max_adr;//此文件最大数据
}Txt_Info;
Txt_Info m_Txt_Info;
下列代码实现,用来保存已经查找的一条记录的开始和末尾的指针
void updateAdr(int data)
{
if(!m_Txt_Info.adr)
{
m_Txt_Info.adr = data;
}
else
{
m_Txt_Info.old_adr = m_Txt_Info.adr+1;
m_Txt_Info.adr = m_Txt_Info.old_adr + data;
}
m_Txt_Info.sum_row++;
}
下面用来从开头插找对每行数据,并记录查照的记录的首尾,当查询到标志为1时停止,
int get_file_row(FIL *fp)//获得最旧纪录,1为找见已经记录的最新故障,
{
unsigned char buffer[30];//一行最多的数据
UINT br;
int i,j = 0;
int_data();
//---------------------------------------------
if(!(fp->fsize))//新文件停留则为第一行
{
updateAdr(0);//保存当前文件的头和尾地址
return 1;
}
f_lseek(fp,0);//移动到文件开头
br = 1;//启动循环
for(j = 0;br;j++)
{
f_read(fp,buffer,sizeof(buffer),&br);
for(i =1;i <br;i++)
{
if(('\r' == buffer[i -1])&&('\n' == buffer[i]))
{
updateAdr(i);//保存当前文件的头和尾地址
break;
}
}
if('1' == buffer[0])//寻找到标记
{
return 1;
}
f_lseek(fp,m_Txt_Info.adr+1);
}
return 0;
}
写入数据函数,在查找到最新记录后,先将上一行的数据1处改成0,然后在新行写入数据,将fp->指针移动到pf移动到文件指针出现的最大处,关闭文件,否则出现写入新数据后出现后面数据丢失的情况。
void write_date(FIL *fp)
{
//f_lseek(fp,fp.fsize-1);
UINT br;
if(get_file_row(fp))
{
f_lseek(fp,m_Txt_Info.old_adr);
//if(m_Txt_Info.adr)//如果为首行,则不写
{
f_write(fp,"0",1,&br);
}
if(m_Txt_Info.sum_row > max_raw)//超过最大行数,
{
int_data();//初始化文件指针
}
if(!(m_Txt_Info.adr))
{
f_lseek(fp,m_Txt_Info.adr);
}
else
{
f_lseek(fp,m_Txt_Info.adr+1);
}
f_write(fp,context,sizeof(context)-1,&br);
if(fp->fsize > m_Txt_Info.max_adr)
{
m_Txt_Info.max_adr = fp->fsize;
}
f_lseek(fp,m_Txt_Info.max_adr);
}
else
{
err = 2;
}
}