WinbondSPIFlash数据记录先进先出机制

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
						}						
					}
				}		
			}			
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值