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

📄 main.c

📁 采用C8051F020和CH375芯片构建的可实现U-DISK功能的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

/************************************************************************************
*  Copyright (c) 2004,西安铭朗电子科技有限责任公司
*            All rights reserved.
*
* 文件名称: Main.C
* 文件标识: none
* 适用器件: C8051F020 
* 
* 摘 	要: 本文件是USB器件CH375主方式应用程序,器件使用INT1资源.
* 
* 当前版本: 1.1
* 作 	者: 刘大伟
* 完成日期: 2007年3月7日
*************************************************************************************/

/********************************引用外部头文件**************************************/
#include "main.h"
#include <intrins.h>
#include <stdio.h>
#include <string.h>

/************************************其他程序*****************************************/
void Delay_us (unsigned int times)
{
    unsigned int i;

	for (i=0; i<times; i++)
	{
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}	     
}

void Delay_ms(unsigned int times) 
{
	unsigned int i;

	for (i=0; i<times; i++)
	{
		Delay_us(1000);
	}
}

void xWriteCH375Cmd( UINT8 mCmd )		/* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */
{
	Delay_us(2);
	CH375_CMD_PORT_ADDR = mCmd;
	Delay_us(2);
}

void xWriteCH375Data( UINT8 mData )		/* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */
{
	CH375_DAT_PORT_ADDR = mData;  /* 向CH375的并口输出数据 */
	Delay_us(2);
}

UINT8 xReadCH375Data( void )			/* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */
{
	unsigned char i;
	Delay_us(2);
	i = CH375_DAT_PORT_ADDR;
	return( i );
}

unsigned char xdata *current_buffer;	/* 保存文件数据读写时的缓冲区的当前指针,由应用程序在调用CH375FileReadX和CH375FileWriteX子程序前设置初值 */

void xReadFromExtBuf( UINT8 mLength )	/* 该子程序由CH375的子程序库调用,用于从外部缓冲区读取文件数据到CH375,被CH375FileWriteX调用 */
{
	if ( mLength ) 
	{
		do 
		{  /* 根据长度写入数据,实际上长度总是CH375_MAX_DATA_LEN,也就是64 */
			xWriteCH375Data( *current_buffer );  /* 将数据写入,可以用这种方式从单片机的各种串行存储器中取出文件数据 */
			current_buffer ++;
		} 
		while ( -- mLength );
	}  /* 复制上述数据的总时间不得超过2mS */
	else 
	{  /* 重试,恢复缓冲区起址,如果将文件数据读写的缓冲区的当前指针放在mCmdParam.WriteX.mDataBuffer中则会被自动恢复,无需下面的两行程序 */
		current_buffer += (UINT16)mCmdParam.WriteX.mDataBuffer;  /* mDataBuffer中为负值 */
		mCmdParam.WriteX.mDataBuffer = 0;  /* 为了支持重试,在调用CH375FileWriteX之前也应该清0 */
	}
}

void xWriteToExtBuf( UINT8 mLength )	/* 该子程序由CH375的子程序库调用,用于从CH375读取文件数据到外部缓冲区,被CH375FileReadX调用 */
{
/*	if ( (UINT16)current_buffer + mLength >= (UINT16)&FILE_DATA_BUF + sizeof( FILE_DATA_BUF ) ) return;*/  /* 防止缓冲区溢出 */
	if ( mLength ) 
	{
		do 
		{  /* 根据长度读取数据,实际上长度总是CH375_MAX_DATA_LEN,也就是64 */
			*current_buffer = xReadCH375Data( );  /* 读出数据并保存,可以用这种方式将文件数据保存到单片机的各种串行存储器中 */
			current_buffer ++;
		} while ( -- mLength );
	}  /* 复制上述数据的总时间不得超过2mS */
	else 
	{  /* 重试,恢复缓冲区起址,如果将文件数据读写的缓冲区的当前指针放在mCmdParam.ReadX.mDataBuffer中则会被自动恢复,无需下面的两行程序 */
		current_buffer += (UINT16)mCmdParam.ReadX.mDataBuffer;  /* mDataBuffer中为负值 */
		mCmdParam.ReadX.mDataBuffer = 0;  /* 为了支持重试,在调用CH375FileReadX之前也应该清0 */
	}
}

/* 检查操作状态,如果错误则显示错误代码并停机,应该替换为实际的处理措施 */
void mStopIfError(unsigned char iError)
{
	if (iError == ERR_SUCCESS) return;  /* 操作成功 */
	printf("Error: %02X\r\n", (UINT16)iError);  /* 显示错误 */
	while (1) 
	{
		LED1 = ~LED1;  /* LED闪烁 */
		LED2 = ~LED2;  /* LED闪烁 */
		LED3 = ~LED3;  /* LED闪烁 */
		Delay_ms(50);
	}
}

typedef struct _FILE_NAME 
{
	UINT32	DirStartClust;				/* 文件所在目录的起始簇号 */
	UINT32	Size;						/* 文件长度 */
	UINT8	Name[8+3+1+1];				/* 文件名,共8+3字节,分隔符,结束符,因为未包含目录名所以是相对路径 */
	UINT8	Attr;						/* 文件属性 */
} FILE_NAME;
#define		MAX_FILE_COUNT		200
FILE_NAME	xdata	FileNameBuffer[ MAX_FILE_COUNT ];	/* 文件名结构 */
UINT16	FileCount;
UINT32	CurrentDirStartClust;			/* 保存当前目录的起始簇号,用于加快文件枚举和打开速度 */

/* 例子:列举指定目录下的所有文件 */
UINT8 ListFile(void) // 输入参数mCmdParam.Open.mPathName[]为目录名字符串,形式与文件名相同,单个斜线则代表根目录
{
	UINT8	i;
	printf("List Directory: %s\n", mCmdParam.Open.mPathName);  /* 显示目录名 */
//	for ( i = 0; i < MAX_PATH_LEN; i ++ ) /* 找目录名的结束符 */
//	{  
//		if ( mCmdParam.Open.mPathName[i] == 0 ) break;
//	}
	i = strlen(mCmdParam.Open.mPathName);  /* 计算路径的长度,找目录名的结束符 */
	if (i && mCmdParam.Open.mPathName[i-1] == '/') {}  /* 是根目录,或者是已经有路径分隔符 */
	else mCmdParam.Open.mPathName[i++] = '/';  /* 在当前目录下进行枚举,除根目录外都是相对路径,不是根目录则加路径分隔符 */
	mCmdParam.Open.mPathName[i++] = '*';  /* 枚举通配符,完整的路径例如"\*"或者"\C51\*"或者"\C51\CH375*"等 */
	mCmdParam.Open.mPathName[i] = 0xFF;  /* 0xFF指定枚举序号在CH375vFileSize中 */
	CH375vFileSize = 0xFFFFFFFF;  /* 快速连续枚举,每找到一个文件调用一次xFileNameEnumer回调子程序,如果值小于0x80000000则每次只枚举一个文件太慢 */
	i = CH375FileOpen();  /* 枚举,由回调程序xFileNameEnumer产生记录保存到结构中 */
	if (i == ERR_SUCCESS || i == ERR_FOUND_NAME || i == ERR_MISS_FILE) /* 操作成功,通常不会返回ERR_SUCCESS,仅在xFileNameEnumer提前退出时才会返回ERR_FOUND_NAME */
	{  
		printf("Success, new FileCount = %d\n", FileCount);
		return(ERR_SUCCESS);
	}
	else 
	{
		printf("Failed, new FileCount = %d\n", FileCount);
		return(i);
	}
}

UINT8	ListAll(void)  /* 以广度优先的算法枚举整个U盘中的所有文件及目录 */
{
	UINT8	i;
	UINT16	OldFileCount;
	OldFileCount = FileCount = 0;  /* 清文件结构计数 */
	FileNameBuffer[0].Name[0] = '/';  /* 根目录,是完整路径名,除根目录是绝对路径之外都是相对路径 */
	FileNameBuffer[0].Name[1] = 0;
	FileNameBuffer[0].DirStartClust = 0;  /* 根目录的这个参数无意义 */
	FileNameBuffer[0].Attr = ATTR_DIRECTORY;  /* 根目录也是目录,作为第一个记录保存 */

	for (FileCount = 1; OldFileCount < FileCount; OldFileCount++) /* 尚有新枚举到的文件名结构未进行分析 */
	{  
		if (FileNameBuffer[ OldFileCount ].Attr & ATTR_DIRECTORY) /* 是目录则继续进行深度搜索 */
		{  
			strcpy(mCmdParam.Open.mPathName, FileNameBuffer[ OldFileCount ].Name);  /* 目录名,除根目录外都是相对路径 */
			CH375vStartCluster = FileNameBuffer[OldFileCount].DirStartClust;  /* 当前目录的上级目录的起始簇号,便于用相对路径打开,比完整路径名速度快 */
			i = CH375FileOpen();  /* 打开目录,仅为了获取目录的起始簇号以提高速度 */
			if (i == ERR_SUCCESS) return(ERR_MISS_DIR);  /* 应该是打开了目录,但是返回结果是打开了文件 */
			if (i != ERR_OPEN_DIR) return(i);
			if (OldFileCount) CurrentDirStartClust = CH375vStartCluster;  /* 不是根目录,获取目录的起始簇号 */
			else /* 是根目录,获取根目录的起始簇号 */
			{  
				if (CH375vDiskFat == DISK_FAT32) CurrentDirStartClust = CH375vDiskRoot;  /* FAT32根目录 */
				else CurrentDirStartClust = 0;  /* FAT12/FAT16根目录 */
			}
			CH375FileClose();  /* 对于根目录一定要关闭 */

//			strcpy( mCmdParam.Open.mPathName, FileNameBuffer[ OldFileCount ].Name );  /* 目录名,由于mPathName未被修改所以无需再复制 */
			CH375vStartCluster = FileNameBuffer[OldFileCount].DirStartClust;  /* 当前目录的上级目录的起始簇号,便于用相对路径打开,比完整路径名速度快 */
			i = ListFile();  /* 枚举目录,由回调程序xFileNameEnumer产生记录保存到结构中 */
			if (i != ERR_SUCCESS) return(i);
		}
	}
// U盘中的文件及目录全部枚举完毕,下面开始根据结构记录依次打开文件 */
	printf("Total file&dir = %d, Open every file:\n", FileCount);
	for (OldFileCount = 0; OldFileCount < FileCount; OldFileCount++) 
	{
		if ((FileNameBuffer[OldFileCount].Attr & ATTR_DIRECTORY) == 0)/* 是文件则打开,目录则跳过 */ 
		{  
			printf("Open file: %s\n", FileNameBuffer[OldFileCount].Name);
			strcpy(mCmdParam.Open.mPathName, FileNameBuffer[OldFileCount].Name);  /* 相对路径 */
			CH375vStartCluster = FileNameBuffer[OldFileCount].DirStartClust;  /* 当前文件的上级目录的起始簇号,便于用相对路径打开,比完整路径名速度快 */
			i = CH375FileOpen();  /* 打开文件 */
			if (i == ERR_SUCCESS)  /* 成功打开了文件 */
			{ 
				mCmdParam.ReadX.mDataBuffer = 0x2000;  /* 指向文件数据缓冲区的起始地址 */
				mCmdParam.ReadX.mSectorCount = 1;  /* 读取扇区数 */
				CH375FileReadX();
//				CH375FileClose();  /* 不做写操作可以无需关闭 */
			}
		}
	}
}

UINT8	CH375LibInit( void )  //初始化CH375程序库和CH375芯片,操作成功返回0 
{
	if ( SP > 0xEE ) return( 0xFC );  //单片机的堆栈空间不够,CH375子程序库最多可能有7级子程序,查询方式最多需要14字节的堆栈空间,建议提供余量 
	CH375LibConfig = LIB_CFG_VALUE;  //CH375程序库配置值 

⌨️ 快捷键说明

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