⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 使用VC模拟一个在单片机内部FLASH的顺序文件系统
💻 C
字号:
#include "stdio.h"

#include "type.h"

#include "filesystem.h"

#include "flash.h"
#include "main.h"

FILE  *fp;

uint8 FLASH[16 * 1024];

uint8 FLASHReadOneByte(uint16 addr)
{

	uint8 temp;
	if((fp = fopen("FLASH","rb")) == NULL)
	{
		printf("Open file error!\n");
		getchar();
		//exit(0);
	}
	fseek(fp,addr,0);
	temp = fgetc(fp);
	fclose(fp);
	return temp;	
}

void FLASHWriteOneByte(uint16 addr,uint8 dat)
{
	if((fp = fopen("FLASH","rb+")) == NULL)
	{
		printf("Open file error!\n");
		getchar();
		//exit(0);
	}
	fseek(fp,addr,0);
	fputc(dat,fp);
	fclose(fp);


}

void FLASHPageErase(uint16 addr)
{
	uint16 i;

	if((fp = fopen("FLASH","rb+")) == NULL)
	{
		printf("Open file error!\n");
		getchar();
		//exit(0);
	}
	addr &= 0xfe00;
	fseek(fp,addr,0);
	for(i=0;i<512;i++)
	{
		fputc(0xff,fp);
	}
	fclose(fp);
}

void FLASHCopy(uint16 tar,uint16 src,uint16 len)
{
	for(;len!=0;len--){
		FLASHWriteOneByte(tar++, FLASHReadOneByte(src++));
		}
}
		
void FLASHWrite(uint16 tar,uint8 *p,uint16 len)
{
	for(;len!=0;len--)
		{
		FLASHWriteOneByte(tar++,*p++);
		}	
}

void FLASHClear(uint16 src,uint16 len)
{
	uint16 flashD1,flashD2;
	uint16 flashE1,flashE2;

	flashD1 = src & 0xfe00;
	flashD2 = (src + len) & 0xfe00;

	if(flashD1 == flashD2){
		flashE1 = src;
		flashD2 = src + len;
		flashE2 = flashD1 + FLASH_PAGE_SZ;

		FLASHPageErase(FLASH_TEMP_ADDR);
		FLASHCopy(FLASH_TEMP_ADDR,flashD1,flashE1 - flashD1);
		FLASHCopy(FLASH_TEMP_ADDR + flashD2 - flashD1,flashD2,flashE2 - flashD2);
		FLASHPageErase(flashD1);
		FLASHCopy(flashD1,FLASH_TEMP_ADDR,FLASH_PAGE_SZ);
	}
	else
	{
		flashE1 = src;
		flashD2 = src + len;
		flashE2 = (flashD2  + FLASH_PAGE_SZ) & 0xfe00;
	
		
		FLASHPageErase(FLASH_TEMP_ADDR);
		
		FLASHCopy(FLASH_TEMP_ADDR,flashD1,flashE1 - flashD1);
		
		FLASHPageErase(flashD1);
		
		FLASHCopy(flashD1,FLASH_TEMP_ADDR,FLASH_PAGE_SZ);
	
		FLASHPageErase(FLASH_TEMP_ADDR);
	
		FLASHCopy(FLASH_TEMP_ADDR + 512 + flashD2 - flashE2,flashD2,flashE2 - flashD2);
	
		FLASHPageErase(flashD2);
	
		FLASHCopy(flashD2 & 0xfe00,FLASH_TEMP_ADDR,FLASH_PAGE_SZ);
		for(flashD1 += 512;flashD1 < (flashD2 - 512);flashD1 += 512)
		{
			FLASHPageErase(flashD1);
		}
	}
}

void FLASHRead(uint16 addr,uint8 *p,uint8 len)
{
	if((fp = fopen("FLASH","rb")) == NULL)
	{
		printf("Open file error!\n");
		getchar();
	}
	fseek(fp,addr,0);
	
	for(;len!=0;len--)	
	{
		*p++ = fgetc(fp);
	}

	fclose(fp);
}

void FLASHUpdate(uint16 tar,uint8 *p,uint8 len)
{
	FLASHClear(tar,len);
	FLASHWrite(tar,p,len);
}

//从addr2处开始移动len个数据到addr1
void FLASHMove(uint16 addr1,uint16 addr2,int16 len)
{
	uint16 spareLen;					// 用来指示FLASH_TEMP中剩余空间
	FLASHPageErase(FLASH_TEMP_ADDR);
	FLASHCopy(FLASH_TEMP_ADDR,addr1 & 0xfe00,addr1 & 0x1ff);	// 把addr所在区间之前的数据拷贝到FLASH_TEMP中	
	spareLen = 512 - (addr1 & 0x1fff);
	do 
	{
		//从addr2中拷贝数据到FLASH_TEMP
		FLASHCopy(FLASH_TEMP_ADDR + (addr1 & 0x1ff),addr2,spareLen);
		len -= spareLen;
		addr2 += spareLen;
		//FLASH_TEMP填满后addr1 需要改变成它所在区间的首地址
		addr1 &= 0xfe00;
		FLASHPageErase(addr1);		// 擦除addr1 所在的flash空间
		FLASHCopy(addr1,FLASH_TEMP_ADDR,512);
		addr1 += 512;						// addr1 到达下一个flash区间的首地址
		FLASHPageErase(FLASH_TEMP_ADDR);
		spareLen = 512;					// 擦除FLASH_TEMP后,剩余空间恢复到512
	} while (len >0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -