我用CH375标准U盘读写模块在c8051f020的单片机上做一个读写口,因为我要存的数据不是太多,用字节读写方式就行了,可是不知道字节读写方式该咋样的读写,谁有这方面的例程能不能该我发个来呢?谢谢了在此!!!我的邮箱:个人信息保护,已隐藏
你到我们公司网站上下载CH375HM.ZIP,这里面有字节读写的例子程序。
谢谢你的回答,你说的是应用资料中的ch375hm.zip 吗? 我已经下了,可是没有字节读写的例子
那里面,并口方式只提供了扇区模式读写的例子。 但是你可以根据我们提供的串口方式下,以字节模式读写的例子作些简单的修改就可以了。
你说得是不是SER_BYTE 中的CH375HMS.C 你的一是我只改以下两个函数就可以了吗? /* 发送一个字节数据给CH375模块 */ void mSendByte( unsigned char c ) { TI = 0; SBUF = c; while ( TI == 0 ); }
/* 从CH375模块接收一个字节数据 */ unsigned char mRecvByte( ) { unsigned char c; while ( RI == 0 ); c = SBUF; RI = 0; return( c ); }
不是,这两个子函数是串口发送接收一个字节的数据的函数,你用并口不需要它们。 扇区模式的读写用CMD_FileRead和CMD_FileWrite函数,你用字节模式读写的话,应该用CMD_ByteRead和CMD_ByteWrite,需要设置读写大小的输入参数。 最好先仔细看看我们模块的说明书CH375HM.PDF和CH375HMP.PDF。
这个是并口读写数据的例子,可以参考: #include #include #include #include
#define MAX_PATH_LEN 20 /* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H,CH375模块支持的最大值是64,最小值是13,并口最大值62 */ #include "CH375HM.H" unsigned char TempLength;
#define CH375HM_INDEX XBYTE[0xBCF0] /* CH375模块的索引端口的I/O地址 */ #define CH375HM_DATA XBYTE[0xBDF1] /* CH375模块的数据端口的I/O地址 */ #define CH375HM_INT_WIRE INT0 /* 假定CH375模块的INT#引脚连接到单片机的INT0引脚 */ sbit P15 = P1^5; #define CH375HM_STA P15 /* 假定CH375模块的STA#引脚连接到单片机的P15引脚 */ sbit LED_OUT =P1^4; /* P1.4 低电平驱动LED显示,用于监控演示程序的进度 */
/* 假定文件数据缓冲区: ExtRAM: 0000H-7FFFH */ //unsigned char xdata DATA_BUF[ 512 * 2 ] _at_ 0x0000; /* 外部RAM的文件数据缓冲区,从该单元开始的缓冲区长度不小于一次读写的数据长度,最少为512字节 */
//unsigned char xdata TempBuffer[80] _at_ 0x0000; unsigned char str[2]; unsigned char m_var; char n; CMD_PARAM mCmdParam; /* 默认情况下该结构将占用64字节的RAM,可以修改MAX_PATH_LEN常量,当修改为32时,只占用32字节的RAM */ unsigned char mIntStatus; /* CH375模块的中断状态或者操作完成状态 */
/* 对于模拟的并口读写时序或者其它并口读写方式,请修改以下3个子程序 */ #define CH375HM_INDEX_WR( Index ) { CH375HM_INDEX = (Index); } /* 写索引地址 */ #define CH375HM_DATA_WR( Data ) { CH375HM_DATA = (Data); } /* 写数据 */ #define CH375HM_DATA_RD( ) ( CH375HM_DATA ) /* 读数据 */
/* 以毫秒为单位延时,适用于24MHz时钟 */ void mDelaymS( unsigned char delay ) { unsigned char i, j, c; for ( i = delay; i != 0; i -- ) { for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz时钟下延时500uS */ for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz时钟下延时500uS */ } }
//void atoi( char *s) reentrant //{
// n = 0; // for ( i = 0; s[i] >= '0' && s[i] <= '9'; ++i ) // n = 16 *(s[0] - '0') + (s[1] - '0'); // return n; //}
/* 执行命令 */ unsigned char ExecCommandBuf( unsigned char cmd, unsigned char len, unsigned char xdata *bufstart ) reentrant /* 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中 */ /* 输入参数bufstart仅用于CMD_FileRead或者CMD_FileWrite命令,指定外部RAM缓冲区的起始地址,可以参考中断方式C程序采用全局变量buffer的方式 */ { unsigned char i, status; #define DataCount status /* 节约一个变量单元 */ unsigned char data *buf; unsigned char xdata *CurrentBuf; CH375HM_INDEX_WR( 0 ); /* 索引地址置0 */ CH375HM_DATA_WR( cmd ); /* 向索引地址0写入命令码 */ CH375HM_DATA_WR( len ); /* 向索引地址1写入后续参数的长度 */ if ( len ) { /* 有参数 */ i = len; buf = (unsigned char *)&mCmdParam; /* 指向输入参数的起始地址 */ do { CH375HM_DATA_WR( *buf ); /* 从索引地址2开始,写入参数 */ buf ++; } while ( -- i ); }
CH375HM_STA = 0; /* 产生下降沿通知模块,说明命令包已经写入,请求开始执行命令 */ CurrentBuf = bufstart; /* 外部RAM缓冲区起始地址,仅用于FileRead或者FileWrite命令 */ while ( 1 ) { /* 处理数据传输,直到操作完成才退出 */
while ( CH375HM_INT_WIRE ); /* 等待模块完成操作产生低电平中断,最佳检测方式是对模块的INT#信号进行下降沿边沿检测 */
CH375HM_INDEX_WR( 63 ); /* 写入索引地址63 */ status = CH375HM_DATA_RD( ); /* 从索引地址63读取中断状态 */
CH375HM_STA = 1; /* 中断应答,取消来自模块的中断请求 */
/* 因为模块在收到中断应答后3uS之内才撤消中断请求,所以,如果是查询INT#信号的低电平,那么在发出中断应答后3uS之内不应该再查询INT#信号的状态 但是由于51单片机较慢,下面的处理时间已经超过3uS,所以不必另加延时等待模块撤消中断请求 */ if ( status == ERR_SUCCESS ) { /* 操作成功 */ CH375HM_INDEX_WR( 1 ); DataCount = CH375HM_DATA_RD( ); /* 从索引地址1读取返回结果数据的长度,计数 */ if ( DataCount ) { /* 有结果数据 */ buf = (unsigned char *)&mCmdParam; /* 指向输出参数的起始地址 */ i = 2; do { CH375HM_INDEX_WR( i ); i ++; *buf = CH375HM_DATA_RD( ); /* 从索引地址2开始,读取结果 */ buf ++; } while ( -- DataCount ); } //status = ERR_SUCCESS; break; /* 操作成功返回 */ }
else if ( status == USB_INT_DISK_READ || status == USB_INT_DISK_WRITE || status == USB_INT_DISK_RETRY ) { break; } else { /* 操作失败 */ if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) mDelaymS( 100 ); /* U盘刚刚连接或者断开,应该延时几十毫秒再操作 */ break; } } while( CH375HM_INT_WIRE == 0 );// 如果单片机速度很快,有可能该程序返回前模块尚未撤消中断请求,那么应该等待中断请求引脚无效 */ return( status ); }
/* 执行命令 */ unsigned char ExecCommand( unsigned char cmd, unsigned char len ) reentrant /* 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中 */ { return( ExecCommandBuf( cmd, len, 0 ) ); /* 只有CMD_FileRead或者CMD_FileWrite命令用到输入参数bufstart,其它命令没有用到 */ }
/* 检查操作状态,如果错误则显示错误代码并停机,应该替换为实际的处理措施 */ void mStopIfError( unsigned char iError ) reentrant { unsigned char led; if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ //printf( "Error: %02X\n", (unsigned short)iError ); /* 显示错误 */ led=0; while ( 1 ) { LED_OUT = led&1; /* LED闪烁 */ mDelaymS( 100 ); led^=1; } }
/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) {
SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xf3; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }
/* 发送一个字节数据给CH375模块 */ void mSendByte( unsigned char c ) { TI = 0; SBUF = c; while ( TI == 0 ); }
/* 从CH375模块接收一个字节数据 */ //unsigned char mRecvByte( ) //{ // unsigned char c; // while ( RI == 0 ); // c = SBUF; // RI = 0; // return( c ); //}
main( ) { unsigned char i; LED_OUT = 0; mDelaymS( 200 ); /* 延时100毫秒,CH375模块上电后需要100毫秒左右的复位时间 */ mDelaymS( 200 ); mDelaymS( 200 ); mDelaymS( 200 ); mDelaymS( 200 ); LED_OUT = 1; mInitSTDIO( ); printf( "Start\n" );
while ( 1 ) {
printf( "Wait Udisk\n" ); while ( 1 ) { /* 使用查询方式看U盘是否连接 */ i = ExecCommand( CMD_QueryStatus, 0 ); /* 查询当前模块的状态 */ mStopIfError( i ); if ( mCmdParam.Status.mDiskStatus >= DISK_CONNECT ) break; /* U盘已经连接 */ mDelaymS( 200 ); } mDelaymS( 200 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ LED_OUT = 0; /* LED亮 */ for ( i = 0; i < 5; i ++ ) { mDelaymS( 100 ); printf( "Ready ?\n" ); if ( ExecCommand( CMD_DiskReady, 0 ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ }
/* 读取原文件 */ printf( "open\n" ); // memcpy( mCmdParam.Open.mPathName, "\\C51\\CH375HFT.C", MAX_PATH_LEN ); /* 文件名,该文件在C51子目录下 */ memcpy( mCmdParam.Open.mPathName, "\\CH375.C", MAX_PATH_LEN ); i = ExecCommand( CMD_FileOpen, MAX_PATH_LEN ); /* 打开文件,输入参数置为最大值,省得再计算参数长度 */
if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { printf( "miss_file\n" ); } else { mStopIfError( i );
while(1) {
mCmdParam.ByteRead.mByteCount = 20; /* 请求读出20字节数据, 单次读写的长度不能超过 sizeof( mCmdParam.ByteWrite.mByteBuffer ) */ i = ExecCommand( CMD_ByteRead, 1 ); /* 以字节为单位读取数据 */ mStopIfError( i );
if ( mCmdParam.ByteRead.mByteCount<20 ) break; for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) printf( "%C", mCmdParam.ByteRead.mByteBuffer[i] ); }
mCmdParam.Close.mUpdateLen = 0; i = ExecCommand( CMD_FileClose, 1 ); /* 关闭文件 */ mStopIfError( i );
}
/* 查询磁盘信息 */ pri
(1)请问hcn 用的是并行查询的方式,字节读写还需要时值下面的函数吗? (2)还有我把数据线接到了p7口上,(我用的c8051f020单片机控制的),写的时候咋样往p7 口上送的数据呢? 我在您的程序中没有看到(也就是说不知道哪句是往p7口的送的数据?) 因为我对c语言也不是太精通,看不太懂上边的函数是怎么写入的数据? 请针对我的问题给出些详细的解答,好吗? 在此谢谢了! /* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) {
SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xf3; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }
/* 发送一个字节数据给CH375模块 */ void mSendByte( unsigned char c ) { TI = 0; SBUF = c; while ( TI == 0 ); }
/* 从CH375
1,下面的函数是不需要的,只是为了用串口数据来监测程序运行的 2,你要修改的就是索引口地址和数据口地址