📄 ch375hft.c
字号:
/* 2004.06.05
****************************************
** Copyright (C) W.ch 1999-2004 **
** Web: http://www.winchiphead.com **
****************************************
** USB Host File Interface for CH375 **
** TC2.0@PC 8086/X86, Small Model **
****************************************
*/
/* CH375 主机文件系统接口 */
/* 支持: FAT12/FAT16/FAT32 */
/* 8086/X86单片机C语言的U盘文件读写示例程序 */
/* 该程序将U盘中的/C51/CH375HFT.C文件中的小写字母转成大写字母后, 写到新建的文件NEWFILE.TXT中,
如果找不到原文件CH375HFT.C, 那么该程序将显示C51子目录下所有以CH375开头的文件名, 并新建NEWFILE.TXT文件并写入提示信息,
如果找不到C51子目录, 那么该程序将显示根目录下的所有文件名, 并新建NEWFILE.TXT文件并写入提示信息
*/
/* CH375的INT#引脚采用查询方式处理, 数据复制方式为"内部复制", 本程序适用于8086兼容的X86单片机, 文本显示输出监控信息 */
/* TCC -ms -IC:\TC\INCLUDE -O -r -Z -c CH375HFT.C */
/* TLINK CH375HFT.OBJ C:\TC\LIB\C0S.OBJ, CH375HFT.EXE, , ..\CH375HF7.LIB C:\TC\LIB\CS.LIB */
#include <dos.h>
#include <string.h>
#include <stdio.h>
/* 以下定义的详细说明请看CH375HF7.H文件 */
#define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */
#define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */
#define DISK_BASE_BUF_LEN 4096 /* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
/* 单片机的RAM有限,其中CH375子程序用512字节,剩余RAM部分可以用于文件读写缓冲 */
#define FILE_DATA_BUF_LEN 0x4000 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */
unsigned short mPortBaseAddr; /* CH375EDM电子盘模块的I/O基址 */
#define CH375EDM_DATA_PORT ( mPortBaseAddr + 0 ) /* CH375EDM的数据端口的I/O地址 */
#define CH375EDM_COMMAND_PORT ( mPortBaseAddr + 1 ) /* CH375EDM的命令端口的I/O地址 */
#define CH375EDM_STATUS_PORT ( mPortBaseAddr + 2 ) /* CH375EDM的状态端口的I/O地址 */
#define CH375_INT_WIRE ( inportb( CH375EDM_STATUS_PORT ) & 0x01 ) /* CH375EDM的中断线INT#引脚,用于查询中断状态 */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未调用CH375FileEnumer程序故禁止以节约代码 */
#define NO_DEFAULT_CH375_F_QUERY 1 /* 未调用CH375FileQuery程序故禁止以节约代码 */
#include "..\CH375HF7.H"
/* 本例将CH375EDM电子盘模块连接到PC机的ISA或者PCI总线 */
/* 在ISA总线中, I/O基址假定为250H */
/* 在PCI总线中, I/O基址由BIOS自动分配, 也可以由CH365本地定址功能保持为原ISA地址 */
#ifndef CH365_PCI_CARD
#define CH375EDM_ISA_IO_ADDR 0x0250
#endif
void mDelay1_2uS( ) /* 至少延时1.2uS,根据单片机主频调整 */
{
UINT16 i;
for ( i = 3; i != 0; i -- ) inportb( CH375EDM_STATUS_PORT );
}
void CH375_PORT_INIT( ) /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */
{
#ifdef CH365_PCI_CARD
union REGS mReg;
mReg.x.ax = 0xb102;
mReg.x.cx = 0x5049; /* 设备ID */
mReg.x.dx = 0x4348; /* 厂商ID */
mReg.x.si = 0; /* 搜索第一个 */
int86 ( 0x1a, &mReg, &mReg ); /* 调用PCI的BIOS */
if ( mReg.h.ah == 0 ) { /* 调用成功 */
mReg.x.ax = 0xb109;
mReg.x.di = 0x0010;
int86 ( 0x1a, &mReg, &mReg ); /* 调用PCI的BIOS */
mPortBaseAddr = mReg.x.cx & 0xfffe; /* PCI设备的I/O基址 */
}
else { /* 没有检测到CH365 */
printf( "CH365 PCI card not found\n" );
exit( 1 ); /* 强制程序终止 */
while( 1 );
}
#else
mPortBaseAddr = CH375EDM_ISA_IO_ADDR; /* CH375电子盘模块的ISA基址 */
#endif
}
void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */
{
mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时2uS */
outportb( CH375EDM_COMMAND_PORT, mCmd ); /* 向CH375EDM输出数据 */
mDelay1_2uS( ); mDelay1_2uS( ); /* 至少延时2uS */
}
void xWriteCH375Data( UINT8 mData ) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */
{
outportb( CH375EDM_DATA_PORT, mData ); /* 向CH375EDM输出数据 */
mDelay1_2uS( ); /* 至少延时1.2uS */
}
UINT8 xReadCH375Data( void ) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */
{
mDelay1_2uS( ); /* 至少延时1.2uS */
return( inportb( CH375EDM_DATA_PORT ) ); /* 从CH375EDM输入数据 */
}
/* 以文本提示代替LED用于监控演示程序的进度 */
#define LED_OUT_INIT( ) { putchar(7); } /* 初始化 */
#define LED_OUT_ACT( ) { printf("LED action\n"); } /* 低电平驱动LED显示 */
#define LED_OUT_INACT( ) { printf("LED inaction\n"); } /* 低电平驱动LED显示 */
/* 延时指定毫秒时间,根据单片机主频调整,不精确 */
void mDelaymS( UINT16 ms )
{
UINT32 i;
while ( ms -- ) for ( i = 800; i != 0; i -- ) mDelay1_2uS( );
}
/* 检查操作状态,如果错误则显示错误代码并停机 */
void mStopIfError( UINT8 iError )
{
if ( iError == ERR_SUCCESS ) return; /* 操作成功 */
printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */
while ( 1 ) {
LED_OUT_ACT( ); /* LED闪烁 */
mDelaymS( 100 );
LED_OUT_INACT( );
mDelaymS( 100 );
}
}
int main( ) {
UINT8 i, c, SecCount;
UINT16 NewSize, count; /* 因为RAM容量有限,所以NewSize限制为16位,实际上如果文件较大,应该分几次读写并且将NewSize改为UINT32以便累计 */
UINT8 *pCodeStr;
CH375_PORT_INIT( );
LED_OUT_INIT( );
LED_OUT_ACT( ); /* 开机后LED亮一下以示工作 */
mDelaymS( 100 ); /* 延时100毫秒 */
LED_OUT_INACT( );
printf( "Start\n" );
#if DISK_BASE_BUF_LEN == 0
pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定义CH375的专用缓冲区,而是用缓冲区指针指向其它应用程序的缓冲区便于合用以节约RAM */
#endif
i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */
mStopIfError( i );
/* 其它电路初始化 */
while ( 1 ) {
printf( "Wait Udisk\n" );
/* while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( );*/ /* 查询CH375中断并更新中断状态,等待U盘插入 */
while ( CH375DiskStatus < DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘插入 */
if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */
mDelaymS( 100 );
}
LED_OUT_ACT( ); /* LED亮 */
mDelaymS( 200 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */
/* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */
for ( i = 0; i < 5; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */
mDelaymS( 100 );
printf( "Ready ?\n" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -