WinbondSPIFlash数据记录先进先出机制
- 实验平台:STM32L053R
- 软件平台:Keil MDK V5.22
- WinbondSPIFlash:W25X40
基本思路:
数据记录满后,继续循环记录,开辟一个4K的数据缓存区进行数据转存;
共需要实现三个机制:
1.带FIFO的数据保存机制
2.数据下载机制
3.参数还原机制
具体实现如下:
程序实现:
void W25QXX_Write_FIFO(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t i=0;
uint16_t j=0;
uint16_t k=0;
uint16_t m=0;
uint8_t BuffTemp[128]={0};
if((RECORD_DATA_TOTAL*RECORD_DATA_SIZE%4096))
{
m = RECORD_DATA_TOTAL*RECORD_DATA_SIZE/4096+1;
}
else
{
m = RECORD_DATA_TOTAL*RECORD_DATA_SIZE/4096;
}
if( SYS_RecordData.Item.RecordCycleNum > 0 )
{
j = SYS_RecordData.Item.RecordAddr/4096;
k = SYS_RecordData.Item.RecordAddr%4096;
if(k == 0)
{
W25QXX_Erase_Sector(m);
for(i = 0; i<32; i++)
{
W25QXX_Read(BuffTemp,j*4096+i*128,128);
W25QXX_Write_NoCheck(BuffTemp,m*4096+i*128,128);
}
W25QXX_Erase_Sector(j);
}
}
W25QXX_Write_NoCheck(pBuffer,WriteAddr,NumByteToWrite);
}
程序实现:
if( (SYS_RecordData.Item.RecordCycleNum ==0) || (Tem1==0 && Tem2==0) )//Êý¾Ýδ´æÂú»òÕßÕýºÃÑ»·ÍêÒ»´Î
{
for(i=0; i<Date_Num; i++)
{
ulFlashBaseAddr=(uint32_t)((((uint32_t)SYS_WorkParmData.curpacknum-1)*PACKETSIZE_USB*RECORD_DATA_SIZE)+i*RECORD_DATA_SIZE);
W25QXX_Read((uint8_t*)&Send_Data[21+i*RECORD_DATA_SIZE],ulFlashBaseAddr,RECORD_DATA_SIZE);
}
}
else
{
if(Tem2 == 0)//Êý¾Ý¸ÕºÃ¼Ç¼ÂúÒ»¸öÉÈÇø
{
for(i=0; i<Date_Num; i++)
{
ulFlashBaseAddr=(uint32_t)((((uint32_t)SYS_WorkParmData.curpacknum-1)*PACKETSIZE_USB*RECORD_DATA_SIZE)+i*RECORD_DATA_SIZE+Tem1*4096 - Tem3);
if(ulFlashBaseAddr == RECORD_DATA_TOTAL*RECORD_DATA_SIZE - RECORD_DATA_SIZE)//Ò»´Î±äÖ·
{
Tem3 = RECORD_DATA_TOTAL*RECORD_DATA_SIZE ;
}
W25QXX_Read((uint8_t*)&Send_Data[21+i*RECORD_DATA_SIZE],ulFlashBaseAddr,RECORD_DATA_SIZE);
}
}
else//Êý¾ÝÖ»¼Ç¼ÁËÉÈÇøµÄÒ»²¿·Ö
{
for(i=0; i<Date_Num; i++)
{
ulFlashBaseAddr=(uint32_t)((((uint32_t)SYS_WorkParmData.curpacknum-1)*PACKETSIZE_USB*RECORD_DATA_SIZE)+i*RECORD_DATA_SIZE+ m*4096+Tem2 - Tem3 - Tem4);
if(Tem1 == (m-1) )//×îºóÒ»¸öÉÈÇø£¬¿ÉÄÜÊÇÍêÕûµÄÒ»¸öÉÈÇø£¬Ò²¿ÉÄܲ»ÊÇ
{
if(ulFlashBaseAddr == (m*4096+n-RECORD_DATA_SIZE) )//Ò»´Î±äÖ·
{
Tem3 =(m*4096+n);
}
}
else//²»ÊÇ×îºóÒ»¸öÉÈÇø
{
if(ulFlashBaseAddr == ( (m+1)*4096-RECORD_DATA_SIZE) )//µÚÒ»´Î±äÖ·
{
Tem3 =(m - Tem1)*4096;
}
if(ulFlashBaseAddr == (RECORD_DATA_TOTAL*RECORD_DATA_SIZE-RECORD_DATA_SIZE) )//µÚ¶þ´Î±äÖ·
{
Tem4 = (RECORD_DATA_TOTAL*RECORD_DATA_SIZE);
}
}
W25QXX_Read((uint8_t*)&Send_Data[21+i*RECORD_DATA_SIZE],ulFlashBaseAddr,RECORD_DATA_SIZE);
}
}
}
程序实现:
void W25QXX_ReadRecordAddr(void)
{
uint8_t BuffTemp[4]={0};
uint8_t BuffTemp1[4]={0};
uint8_t BuffTemp2[4]={0};
uint16_t m=0;
uint16_t n=0;
uint16_t i=0;
uint16_t j=0;
if((RECORD_DATA_TOTAL*RECORD_DATA_SIZE%4096))
{
m = RECORD_DATA_TOTAL*RECORD_DATA_SIZE/4096+1;
n = RECORD_DATA_TOTAL*RECORD_DATA_SIZE%4096;
}
else
{
m = RECORD_DATA_TOTAL*RECORD_DATA_SIZE/4096;
n = 4096;
}
W25QXX_Read(BuffTemp,m*4096,4);
if(BuffTemp[0] == 0xFF)//4K»º´æÇøΪ¿Õ£¬Î´½øÈëFIFOģʽ
{
SYS_RecordData.Item.RecordCycleNum = 0;//CaseA
W25QXX_Read(BuffTemp,(m-1)*4096+n-RECORD_DATA_SIZE,4);//¼Ç¼Çø×îºóÒ»¸öÊý¾ÝµÄʱ¼ä
if( BuffTemp[0] != 0xFF)//Êý¾Ý½«½«¼Ç¼Âú
{
SYS_RecordData.Item.RecordCycleNum = 1;
SYS_RecordData.Item.RecordAddr = 0;
return;//CaseA1
}
else//Êý¾Ýδ¼Ç¼Âú
{
for(i=0;i<m;i++)
{
W25QXX_Read(BuffTemp,i*4096,4);//ÿ¸öÉÈÇøµÚÒ»¸öÊý¾ÝµÄʱ¼ä
if(BuffTemp[0] == 0xFF)//Êý¾Ý»¹Ã»Ð´µ½×îºóÒ»¸öÉÈÇø
{
if(i == 0)//ûÓÐÊý¾Ý¼Ç¼
{
SYS_RecordData.Item.RecordAddr = 0;
return;//CaseA2
}
else//ÓÐÊý¾Ý¼Ç¼£¬ÕÒµ½Êý¾Ý½áβµÄµØÖ·
{
for(j=0;j<(4096/RECORD_DATA_SIZE);j++)
{
W25QXX_Read(BuffTemp,(i-1)*4096+j*RECORD_DATA_SIZE,4);
if(BuffTemp[0] == 0xFF)//²»Ò»¶¨»á½øÈ¥£¬»áÓиոմæÂúÕâ¸öÉÈÇøµÄÇé¿ö
break;
}
SYS_RecordData.Item.RecordAddr = (i-1)*4096+j*RECORD_DATA_SIZE;
return;//CaseA3
}
break;
}
}
//Êý¾Ýдµ½×îºóÒ»¸öÉÈÇøÁË,×îºóÒ»¸öÉÈÇøµÄ´óС²»¹Ì¶¨
for(j=0;j<n/RECORD_DATA_SIZE;j++)
{
W25QXX_Read(BuffTemp,(i-1)*4096+j*RECORD_DATA_SIZE,4);
if(BuffTemp[0] == 0xFF)//Ò»¶¨»á½øÈ¥£¬ÒòΪÊý¾Ýδ¼Ç¼Âú
{
SYS_RecordData.Item.RecordAddr = (i-1)*4096+j*RECORD_DATA_SIZE;
return;//CaseA4
}
}
}
}
else//4K»º´æÇø²»Îª¿Õ£¬Êý¾Ý¼Ç¼Âú£¬ÒѽøÈëFIFOģʽ
{
SYS_RecordData.Item.RecordCycleNum = 1;//CaseB
W25QXX_Read(BuffTemp , m*4096+n-RECORD_DATA_SIZE,4);//»º´æÇø×îºóÒ»¸öÊý¾ÝµÄʱ¼ä
W25QXX_Read(BuffTemp1,(m-1)*4096+n-RECORD_DATA_SIZE,4);//¼Ç¼Çø×îºóÒ»¸öÊý¾ÝµÄʱ¼ä
for(i = 0;i<4;i++)
{
if(BuffTemp1[i] != BuffTemp[i])
break;
}
if(i == 4)//Êý¾ÝÕýºÃ¼Ç¼µ½×î´óµØÖ·£¬½«Êý¾ÝдָÕë¹éÁã
{
SYS_RecordData.Item.RecordAddr = 0;
return;//CaseB1
}
else
{
W25QXX_Read(BuffTemp,(m+1)*4096-RECORD_DATA_SIZE,4);
if(BuffTemp[0] == 0xFF )//»º´æÇøÊý¾ÝĩβÈç¹ûÊÇ0xff˵Ã÷Êý¾Ýдµ½ÁË×îºóÒ»¸öÉÈÇø£¬ÇÒÕâ¸öÉÈÇøÖ»»áÕ¼ÓÃÒ»²¿·Ö
{
for(j=0;j<n/RECORD_DATA_SIZE;j++)
{
W25QXX_Read(BuffTemp,(m-1)*4096+j*RECORD_DATA_SIZE,4);
if(BuffTemp[0] == 0xFF)//Ò»¶¨»á½øÈ¥£¬ÒòΪ×îÐÂÊý¾Ý¸üе½¼Ç¼ÇøβµÄÇé¿öÒѾÅųý
{
SYS_RecordData.Item.RecordAddr = (m-1)*4096+j*RECORD_DATA_SIZE;
return;//CaseB2
}
}
}
else//»º´æÇø4KдÂú£¬ËµÃ÷Êý¾ÝÖ¸ÕëËùÔÚµÄÉÈÇøÒ»¶¨ÊDZ»ÍêÈ«Õ¼ÓõÄ(Õâ¸öÉÈÇø¿ÉÄÜÊÇ×îºóÒ»¸öÉÈÇø)
{
W25QXX_Read(BuffTemp,(m+1)*4096 - RECORD_DATA_SIZE,4);//¶ÁÈ¡4K»º´æÇø×îºóÒ»¸öÊý¾ÝµÄʱ¼ä
for(i=0;i<m;i++)
{
W25QXX_Read(BuffTemp1,(i+1)*4096 - RECORD_DATA_SIZE,4);//¶ÁÈ¡¼Ç¼Çøÿ¸öÉÈÇø×îºóÒ»¸öÊý¾ÝµÄʱ¼ä
if(BuffTemp1[0] == 0xFF)//i×î´óµ½m-1
{
for(j=0;j<(4096/RECORD_DATA_SIZE);j++)
{
W25QXX_Read(BuffTemp,i*4096+j*RECORD_DATA_SIZE,4);
if(BuffTemp[0] == 0xFF)//Ò»¶¨»á½øÈ¥£¬ÒòΪÒѾ֪µÀËüµÄ×îºóÒ»¸öÊý¾ÝÊÇ0xFF
{
SYS_RecordData.Item.RecordAddr = i*4096+j*RECORD_DATA_SIZE;
return;//CaseB3
}
}
}
else//i×î´óµ½m-2
{
for(j=0;j<4;j++)//±È½ÏËüÃǵÄʱ¼äÊÇ·ñÒ»ÖÂ
{
if(BuffTemp1[j] != BuffTemp[j])
break;
}
if(j == 4)
{
SYS_RecordData.Item.RecordAddr = (i+1)*4096;
return;//CaseB4
}
}
}
}
}
}
}