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

📄 hpi.c

📁 利用单片机实现的USB1.1通信中的人机接口部分的实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		flash_buf[i]^=flash_buf[i-8];
		}
	//倒序存放
	flash_buf[0]=flash_buf[11];
	flash_buf[1]=flash_buf[10];
	flash_buf[2]=flash_buf[9];
	flash_buf[3]=flash_buf[8];
	add_start.add_word=VERIFY_ID;
	fm_write(flash_buf,4);
	}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



//将8+2048K的数据信息全部写入到
//bit WriteFile(unsigned int writeLength,unsigned char *pBuffer)		//将pBuffer指向的数据、writeLength规定长度的数据写入文件
bit WriteFile(void)		//将所有8+2048K的数据写入文件
{
	idata	uint		i,j,k;
	idata	uchar		page_num,len;
	idata	uint		write_step;
	xdata	PDIR_INFO 	pDirInfo;

	if(!SLAVE_IS_ATTACHED)	//U盘是否已经连接
	{
		UartRspBlock.uart_rsp_block_usb.errcode=ERC_NODEVICE;
		return FALSE;
	}
	if(!ThisFile.bFileOpen)		//文件是否已经打开
	{
		UartRspBlock.uart_rsp_block_usb.errcode=ERC_FILENOTOPENED;
		return FALSE;
	}
	if((DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus)>8192)	//超过8192字节每簇了不能执行本程序
		return FALSE;
	//至此已经载入了当前文件的参数,FAT当前扇区信息
	//以文件长度全部完成写、出错为退出条件,以FAT扇区换页作为结算单元,进行文件写,最后修改DBR
	//此时还需要将文件的最后修改时间与编号连同文件名进行加密数据存储,以备校验文件的合法性
	save_file_modify_time();
	if((DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus)>2048)	//超过缓冲区大小了必须分开传送
	{
		i=(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus)/2048;
		len=2048/DeviceInfo.BPB_BytesPerSec;
		page_num=16;		//每次转移的数据所占FALSH的页数
	}
	else		//1次传送即可
	{
		i=1;
		len=DeviceInfo.BPB_SecPerClus;
		page_num=DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus/128;		//每次转移的数据所占FALSH的页数
	}
	for(write_step=0;write_step<(8192/(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus));write_step++)	//每次一定只传送1簇
	{
		for(j=0;j<i;j++)
		{
			read_to_dbuf(i*write_step+j,len*DeviceInfo.BPB_BytesPerSec);
			for(k=0;k<len;k++)
			{
				NOW_READ=1;
				if(!RBC_Write(ThisFile.SectorPointer,1,DBUF+(k*512)))		//将这段数据写到设备对应位置
				{
					UartRspBlock.uart_rsp_block_usb.errcode=ERC_DEVICEERR;	//写失败
					return  FALSE;
				}
				ThisFile.SectorPointer++;
			}
		}
		if(!FindNextFreeClus())
		return	FALSE;
	}
	//8192字节数据传送完毕,接下来要传送FLASH的数据了
	write_step=(0x1FFFFF/(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus))+1;
	flash_address.flash_page=0;	//从0页开始传送
	flash_reset_read();
	while(write_step)			//每次写1簇
	{
		//将FLASH的数据按照整簇写到U盘对应扇区
		if(!RBC_Write_Flash(DeviceInfo.BPB_SecPerClus))	//将这段数据写到设备对应位置
		return FALSE;

		ThisFile.SectorPointer+=DeviceInfo.BPB_SecPerClus;
		//////////////////////////////////////////
		if(write_step==1)
		{
			CurFatSector[ThisFile.NowFatEntOffset]=0xff;		//标定文件结束标志
			CurFatSector[ThisFile.NowFatEntOffset+1]=0xff;
		}
		else
		{
			if(!FindNextFreeClus())
			return	FALSE;
		}
		write_step--;
	}
	if(!UpdateFat())		//保存当前的FAT扇区
		return FALSE;
	//接下来修改文件项
//	get_file_name();          //caine add
	//        ThisFile.NowDirItem=0;
	pDirInfo=(PDIR_INFO)(CurDirInfo+ThisFile.NowDirItem);//指针指向当前的文件项
//	copy_ram_same(file_name,pDirInfo->name,11);	//文件名和扩展名一起拷贝8+3byte
	pDirInfo->attribute=0x21;		//文件的属性是只读和存档
	pDirInfo->startCluster=SwapINT16(ThisFile.StartCluster);	//起始扇区先设置为第1个闲簇,FAT16只有低位簇号
	pDirInfo->startCluster_msb=0;	//起始簇先设置为第1个闲簇,FAT16只有低位簇号,高位总为0
	pDirInfo->length=SwapINT32(0x202000);				//文件的长度定为0x202000字节
	time_to_fat(modify_time,(ulong *)(&pDirInfo->lastUpdateTime));	//pDirInfo->lastUpdateTime,将时间和日期都转换为FAT的格式
	pDirInfo->Dir_CrtTime=pDirInfo->lastUpdateTime;		//创建时间即最后写时间
	pDirInfo->Dir_CrtDate=pDirInfo->lastUpdateDate;		//创建日期即最后写日期
//	DelayMs(50);
	NOW_READ=1;
	if(!RBC_Write(ThisFile.NowDirSec+DeviceInfo.RootStartSector,1,CurDirInfo))	//将当前文件项刷新回写
		return	FALSE;
	return	TRUE;
}

//检查磁盘剩余的空间是否足够存放一个文件,不够返回FALSE,参数为0代表剩余全部的空间作为比对标准,为1要扣除文件本身已经存在的大小再作比较
bit check_free_capacity(bit	exist_count)
	{
	union
		{
		uchar	temp_byte[2];
		uint		temp_word;
		}i;
	bit	taken_free;	//已经得到了闲簇标志,=1表示得到
	idata		uint	require_cluster;	//需要的空簇数
	taken_free=0;
	DeviceInfo.FreeCluNum=0;
	if(!SLAVE_IS_ATTACHED)
		{
		UartRspBlock.uart_rsp_block_usb.errcode=ERC_NODEVICE;
		return FALSE;
		}
	if(exist_count)		//如果本文件原本就有大小
		{
		require_cluster=((ThisFile.LengthInByte-1)/(DeviceInfo.BPB_SecPerClus*DeviceInfo.BPB_SecPerClus))+1;
		if(require_cluster>=((0x201FFF/(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus))-1))	//已经存在的文件大小超过要求大小则空间肯定足够
			return TRUE;
		else
			require_cluster=((0x201FFF/(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus))-1)-require_cluster;
		}
	else
		require_cluster=(0x201FFF/(DeviceInfo.BPB_BytesPerSec*DeviceInfo.BPB_SecPerClus))-1;
	for(i.temp_word=0;i.temp_word<DeviceInfo.CountOfCluster+2;i.temp_word++)
		{
		if(i.temp_byte[1]==0)
			{
			if(!RBC_Read(i.temp_byte[0]+DeviceInfo.FatStartSector,1,DBUF))	//判断读扇区是否成功
				{
				UartRspBlock.uart_rsp_block_usb.errcode=ERC_NODEVICE;	//不成功要退出
				return FALSE;
				}
			}
		if((DBUF[(uint)(i.temp_byte[1]*2)]==0)&&(DBUF[(uint)(i.temp_byte[1]*2+1)]==0))
			{
			DeviceInfo.FreeCluNum++;
			if(!taken_free)
				{
				DeviceInfo.FirstFreeClu=i.temp_word;
				taken_free=1;		//得到了首闲簇
				}
			if(DeviceInfo.FreeCluNum>=require_cluster)
				return TRUE;
			}
		}

	return FALSE;
	}
//在U盘中生成记录仪编号的ASCII码为文件名的文件,成功返回TRUE,失败返回FALSE
bit	generate_file(void)
{
	//得到当前的文件修改日期
	read_realtime(modify_time);
	modify_time[5]&=0xfe;	//计算文件的修改时间精度是2秒
	//检查当前U盘是否存在,不在返回FLASE
	if(!SLAVE_IS_ATTACHED)
	{
		UartRspBlock.uart_rsp_block_usb.errcode=ERC_NODEVICE;
		return FALSE;
	}
	if(OpenFile())		//当前文件名是否存在
	{
		if(ThisFile.LengthInByte>=0x202000)	//判断文件大小是否符合规范
		{
			if(!DeleteFileFat())		//先将文件的FAT清除,并打开文件
			return	FALSE;
			DelayMs(50);
			if(!WriteFile())	//若已存在文件大于要保存文件不要检查剩余空间再写完成后修改FAT和文件项就可
			{
				UartRspBlock.uart_rsp_block_usb.errcode=ERC_WRITEERR;	//写文件失败
				return	FALSE;
			}
		}
		else	//已存在文件小于要保存文件,要检查剩余空间足够才可写入,写完成后修改FAT和文件项就可
		{
			//检查剩余空间
			if(!check_free_capacity(1))		//检查剩余的所有空间,以簇为单位检查,参数=1代表检测时要扣除已经占用的簇数
			{
				UartRspBlock.uart_rsp_block_usb.errcode=ERC_DEVICEFULL;	//剩余空间不够存放本文件
				return	FALSE;
			}
			if(ThisFile.LengthInByte)
			{
				if(!DeleteFileFat())		//先将文件的FAT清除,并打开文件
				return	FALSE;
			}
			if(!WriteFile())
			{
				UartRspBlock.uart_rsp_block_usb.errcode=ERC_WRITEERR;	//写文件失败
				return	FALSE;
			}
		}
	}
	else		//如果无法打开文件就建立一个
	{
		if(!check_free_capacity(0))		//检查剩余的所有空间,以簇为单位检查,参数为0代表
		{
			UartRspBlock.uart_rsp_block_usb.errcode=ERC_DEVICEFULL;	//剩余空间不够存放本文件
			return	FALSE;
		}
		if(!CreateFile())
		{
			UartRspBlock.uart_rsp_block_usb.errcode=ERC_CREATEERR;	//建立文件失败
			return	FALSE;
		}
		if(!WriteFile())	//写入文件内容
		{
			UartRspBlock.uart_rsp_block_usb.errcode=ERC_WRITEERR;	//写文件失败
			return	FALSE;
		}
	}
	IE=0xDB;
	return	TRUE;	//操作成功
}

⌨️ 快捷键说明

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