📄 main.c
字号:
/************************************************************************************
* 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 + -