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

📄 hpi.c

📁 采用811芯片实现单片机读写U盘的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define HPI_FILE
#include "include.h"

//extern XXGFLAGS bdata bXXGFlags;
//extern unsigned char xdata DBUF[BUFFER_LENGTH];
//////////////////////////////////////////
//UART_CMD_BLOCK xdata inblock;
//unsigned char xdata UARTBUF[UARTBUF_LENGTH];
//extern SYS_INFO_BLOCK xdata DeviceInfo;
//UART_CMD_BLOCK xdata UartCmdBlock;
//UART_RSP_BLOCK xdata UartRspBlock;
//extern FILE_INFO xdata ThisFile;
//extern FREE_FAT_INFO xdata FreeFat;

unsigned char UartHandler(uchar cmd,uchar package,uint buf_len,uchar *para)
{
  unsigned char retStatus;
  unsigned int len;
  unsigned long pointer;
  
	switch(cmd)
  	{
   	case CMD_RESET:
    
    		break;
    		
   	case CMD_DETECT_DEVICE:
    		file_point.file_open_flag=0;	
    		para[0]=DetectDevice();
    		retStatus=send_data(0,1,para);
    		break;
    		
    	case CMD_LIST:
    		file_point.file_open_flag=0;	
	    	retStatus=List(para);
	    	break;
	    	
    	case CMD_OPEN_FILE:
    		retStatus=OpenFile(buf_len,para);
//    		if(!retStatus)
//    			send_data(0,32,para);
    		break;
    		
    case CMD_CREATE_FILE:
			
	    	retStatus=CreateFile(buf_len,para);
	    	if(retStatus==FILE_EXIST){
	    		retStatus=OpenFile(11,para);
	    		if(retStatus) break;
	    	}	
	    	if(!retStatus)
    			send_data(0,32,para);
    	break;
    	
    case CMD_READ_FILE:
    	len=*((uint *)para);
		retStatus=ReadFile(len,para);
		if(!retStatus)
			send_data(0,len,para);
    	break;
    	
    case CMD_WRITE_FILE:
    	len=*((uint *)para);
    	retStatus=WriteFile(len,&para[2]);
    	if(!retStatus)
			send_data(0,0,para);
    	break;
    
    case CMD_REMOVE_FILE:
    	if(len!=11){
    		retStatus=RECE_DATA_ERR;
    		break;
    	}	
	file_point.file_open_flag=0;	
    	retStatus=RemoveFile(para);
    	if(!retStatus) 
    		send_data(0,0,para);
    	break;
    	
//    case CMD_GET_CAPACITY:
//    	ThisFile.bFileOpen=0;	
//    	retStatus=GetCapacity();
////    	UartRspBlock.cmd=CMD_GET_CAPACITY_RSP;
//    	break;
//    	
//    case CMD_GET_FREE_CAPACITY:
//    	ThisFile.bFileOpen=0;	
//    	retStatus=GetFreeCapacity();
////    	UartRspBlock.cmd=CMD_GET_FREE_CAPACITY_RSP;
//    	break;
//    
    case CMD_SET_FILE_POINTER:
		pointer=*((ulong *)para);
		retStatus=SetFilePointer(pointer);  
		if(!retStatus)
			send_data(0,0,para);
    	break;
//    	
//    case CMD_GET_VERSION:
//	ThisFile.bFileOpen=0;
//	retStatus=GetFirmwareVersion();   
////	UartRspBlock.cmd=CMD_GET_VERSION_RSP; 
//    	break;
    	
    default:
    	retStatus=CMD_ERROR;
    	break;
  }
  if(retStatus)
		send_error(retStatus);
  return TRUE;
}

unsigned char DetectDevice(void)
{
	return bXXGFlags.bits.SLAVE_IS_ATTACHED;
	
}

/******************************************************
在当前目录下查找文件
入口参数:flag==1   找到文件后更新文件目录项
                               ==0   找到文件后返回目录项
******************************************************/
uchar find_file(uchar *file_name,uchar *file_item,uchar flag)
{
	uint i;
	uchar bstop,end_sector,find_flag;
	uchar package=1;
	uchar sector_temp;
	ulong start_sec,clus_temp;
	
	find_flag=0;
	bstop=0;
	start_sec=cur_dir_info.start_sec;
	clus_temp=cur_dir_info.start_clue;
	end_sector=(uchar)(deviceinfo.RootEntCnt>>4);
	
	sector_temp=0;
	while(1){
		
		if(!RBC_Read(start_sec,1,DBUF))
			return DEVICEC_OP_ERR;
			
		for(i=0;i<deviceinfo.BytePerSec;i=i+32){
			if(DBUF[i]==0x00){
				bstop=1;
				break;
			}
			if((DBUF[i]==0xE5)||(DBUF[i+11]==0x0f))
				continue;
			else{
				if(DBUF[i]==0x05) DBUF[i]=0xe5;
				if(!memcmp_cur(&DBUF[i], file_name, 11)) {
					if(flag){
						memcpy_cur(&DBUF[i],file_item,32);
						//更新目录信息
						if(!RBC_Write(start_sec,1,DBUF))
							return DEVICEC_OP_ERR;
					}else{	
						memcpy_cur( file_item,&DBUF[i],32);
					}	
					find_flag=1;
					bstop=1;
					break;	
				}		
			}
		}
		
		if(bstop==1)break;
		start_sec++;
		sector_temp++;
		if((deviceinfo.type)||(!cur_dir_info.root_flag)){
			if(sector_temp==deviceinfo.SecPerClus){
				sector_temp=0;
				clus_temp=GetNextClusterNum(clus_temp);
				if(clus_temp>0x0fffffef) break;
				start_sec=FirstSectorofCluster(clus_temp);
			}	
		}else{
			if(sector_temp==end_sector) break;
		}	
	}	
	
	if(!find_flag) return FILE_NON_EXIST;
	
	return 0;	
}

/******************************************************
在当前目录下插入文件目录项
说明:直接在目录尾插入文件目录项
******************************************************/
uchar add_file_item(uchar *file_item)
{
	uint i;
	uchar bstop,end_sector,find_flag;
	uchar package=1;
	uchar sector_temp;
	ulong start_sec,clus_temp;
	
	find_flag=0;
	bstop=0;
//	start_sec=cur_dir_info.start_sec;
	clus_temp=cur_dir_info.start_clue;
	end_sector=(uchar)(deviceinfo.RootEntCnt>>4);

	//目录没有文件长度,故需要重新搜索
	if((deviceinfo.type)||(!cur_dir_info.root_flag)){
		//得到最后一个簇号
		while(1){
			clus_temp=GetNextClusterNum(clus_temp);
			if(clus_temp>0x0fffffef) break;
		}
		start_sec=FirstSectorofCluster(clus_temp);
	}else{
		start_sec=cur_dir_info.start_sec;
	}	
	
	while(1){
		
		if(!RBC_Read(start_sec,1,DBUF))
			return DEVICEC_OP_ERR;
			
		for(i=0;i<deviceinfo.BytePerSec;i=i+32){
			if(DBUF[i]==0x00){
				bstop=1;
				memcpy_cur(&DBUF[i], file_item,32);
				break;
			}
		}
		
		if(bstop==1)break;
		start_sec++;
		if((deviceinfo.type)||(!cur_dir_info.root_flag)){
			if(start_sec==deviceinfo.SecPerClus){
				start_sec=FirstSectorofCluster(fat_info.next_free_clus);
				if(!CreateClusterLink(clus_temp)) return DEVICEC_OP_ERR;
				if(!updata_fat_free()) return DEVICEC_OP_ERR;
			}	
		}else{
			if(sector_temp==end_sector) break;
		}	
	}	
	
	if(!bstop) return DEVICE_FULL;
	if(!RBC_Write(start_sec,1,DBUF)) return DEVICEC_OP_ERR;
	return 0;	
}

/********************************************************
读取当前目录下的文件列表
说明:每个文件项中的数据均为小端模式(即PC模式)
********************************************************/	
uchar List(uchar *para)
{
	uint item,i;
	uchar bstop,end_sector;
	uchar error,package=1;
	uchar sector_temp;
	ulong start_sec,clus_temp;
	
	if(!bXXGFlags.bits.SLAVE_IS_ATTACHED)
	{
		return NOT_DEVICE;		
	}
	
	item=0;bstop=0;
	start_sec=cur_dir_info.start_sec;
	clus_temp=cur_dir_info.start_clue;
	end_sector=(uchar)(deviceinfo.RootEntCnt>>4);
	
	sector_temp=0;
	while(1){
		
		if(!RBC_Read(start_sec,1,DBUF))
			return NOT_DEVICE;
			
		for(i=0;i<deviceinfo.BytePerSec;i+=32){
			if(DBUF[i]==0x00){
				bstop=1;
				break;
			}
			if((DBUF[i]==0xE5)||(DBUF[i+11]==0x0f))
				continue;
			else{
				if(DBUF[i]==0x05) DBUF[i]=0xe5;
				if(item>1023){
					error=send_data(package,item,para);
					if(error) return error;
					package++;
					item=0;
				}
				memcpy_cur(&para[item], &DBUF[i], 32);
				item=item+32;
			}
		}
		
		if(bstop==1)break;
		start_sec++;
		sector_temp++;
		if((deviceinfo.type)||(!cur_dir_info.root_flag)){
			if(sector_temp==deviceinfo.SecPerClus){
				clus_temp=GetNextClusterNum(clus_temp);
				if((clus_temp>0x0fffffef)||(!clus_temp)) break;
				start_sec=FirstSectorofCluster(clus_temp);
			}	
		}else{
			if(sector_temp==end_sector) break;
		}	
	}	
		
	if(item){
		error=send_data(0,item,para);
		if(error) return error;	
	}	
	
	return 0;

}

/********************************************************
打开文件
说明:参数包括11个字节文件名(ASC),4个字节当前日期(HEX),3个字节当前时间(HEX)
      该函数仅在当前目录中查找,若打开的为目录,则进入该目录
********************************************************/      
uchar OpenFile(uint len,uchar *para)
{

	uchar error;
	ulong clus_temp;
	uchar up_dir[11]={0x2e,0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
	uchar my_dir[11]={0x2e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
	
//	PDIR_INFO xdata pDirInfo;
	
	if(!bXXGFlags.bits.SLAVE_IS_ATTACHED)
	{
		return NOT_DEVICE;		
	}
	
	if(len!=18) return RECE_DATA_ERR;

	memcpy_cur(file_point.name, para,11);
			
	file_point.file_open_flag=0;
//	end_sector=(uchar)(DeviceInfo.BPB_RootEntCnt>>4);
	
	#ifdef ZLH_DEBUG
//	disp_data(2,"A2");
//	disp_data(4,&DeviceInfo.StartSector);
//	disp_data(4,&DeviceInfo.RootStartSector);
//	disp_data(2,&DeviceInfo.BPB_RootEntCnt);
//	disp_data(2,&end_sector);
//	disp_data(11,pBuffer);
//	while(!getkey());
	#endif
	
	error=find_file(file_point.name,(uchar *)&cur_file_item,0);
	if(error) return error;
	
	clus_temp=((ulong)cur_file_item.dir_fstcluslo)<<16+cur_file_item.dir_fstclushi;
	clus_temp=SwapINT32(clus_temp);
	
	if(cur_file_item.dir_attr&0x10){  //打开目录
		if(memcmp_cur(file_point.name,my_dir,11)==0){
			 //选择本目录
			send_data(0,0,para);
			return 0;
		}

		if(memcmp_cur(file_point.name,up_dir,11)==0){
			if(!clus_temp){
				 //上级目录为根目录
				cur_dir_info.root_flag=1;
				cur_dir_info.start_sec=deviceinfo.RootFirstSec;
				if(deviceinfo.type){
					cur_dir_info.start_clue=2;
					cur_dir_info.fat_sec=deviceinfo.FATFirstSec;
				}	
				else{
					cur_dir_info.start_clue=0;
					cur_dir_info.fat_sec=0;
				}
			}
			else{		
				cur_dir_info.root_flag=0;
				cur_dir_info.start_clue=clus_temp;
				cur_dir_info.start_sec=FirstSectorofCluster(clus_temp);
				cur_dir_info.fat_sec=ThisFatSecNum(clus_temp);
				//打开的是目录(根目录不包括)
				//目录文件永远没有大小
				file_point.type=0;
				file_point.file_start_clue=cur_dir_info.start_clue;
				file_point.file_size=SwapINT32(cur_file_item.dir_file_size);	
				file_point.current_clue=file_point.file_start_clue;
				file_point.current_sec=cur_dir_info.start_sec;
				file_point.offset_sec_clue=0;
				file_point.offset_byte=0;
				file_point.offset_fat_sec=cur_dir_info.fat_sec;
				file_point.offset_point=0;
				file_point.file_open_flag=1;	
			}
		}	
	}
	else{
		//打开文件
		if(cur_file_item.dir_file_size){
			file_point.file_start_clue=clus_temp;
			file_point.file_size=SwapINT32(cur_file_item.dir_file_size);
		
			file_point.current_clue=file_point.file_start_clue;
			file_point.current_sec=FirstSectorofCluster(file_point.current_clue);
			file_point.offset_sec_clue=0;
			file_point.offset_byte=0;
			file_point.offset_fat_sec=ThisFatSecNum(file_point.current_clue);
		}else{
			file_point.file_size=0;
		}		
		file_point.offset_point=0;
		file_point.type=1;
		file_point.file_open_flag=1;	
	}	
	
	memcpy_cur(file_point.date,&para[11], 7);
	
//	for(i=0,j=11;i<4;i++,j++)
//		file_point.date[i]=para[j];
//	for(i=0;i<3;i++,j++);
//		file_point.time[i]=para[j];		
	
	#ifdef ZLH_DEBUG
	disp_data(2,"B3");
	disp_data(68,&deviceinfo);
	#endif
	
	if(file_point.type) send_data(0,32,(uchar *)&cur_file_item);
	else send_data(0,0,para);
	
	return 0;
}

/*****************************************************************
读取当前文件数据
*****************************************************************/
uchar ReadFile(uint readLength,uchar *para)
{
	uint len,position=0;
	uchar bSuccess;
	//unsigned char sector;
	//unsigned long lba;
	
	if(!bXXGFlags.bits.SLAVE_IS_ATTACHED)
	{
		return NOT_DEVICE;		
	}

	if(!file_point.file_open_flag)
	{
		return FILE_NOT_OPEN;		
	}
	
	//目录不能读
	if(!file_point.type) return FILE_NOT_OPEN;
	
	if(!file_point.file_size) return FILE_LENTH_OVER;
	
	if(!readLength) return RECE_DATA_ERR;
	
	file_point.file_open_flag=0;
	  
	bSuccess=1;
	
	if(readLength+file_point.offset_point>file_point.file_size)
	{
//		return FILE_LENTH_OVER;	
		readLength=file_point.file_size-file_point.offset_point;

⌨️ 快捷键说明

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