U盘对拷,

U盘对拷,的电路图里面要一个USB-HOST ,还是要两个USB-HOST,大概原理图是什么样的谢谢大家我的原理图是这个样子的能实现U盘对拷吗?谢谢,看看我的图20095141434319.jpg

U盘对考至少需要2片CH375,这个电路也是我们手册上的,只要再增加一片CH375,从74LS138上再取出一个片选信号,作为该375的片选,其余信号:WR、RD、A0、D7-D0与图中的375共用即可


谢谢 那么程序用这个可以吗请看一下 /* 2004.06.05 **************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB Host File Interface for CH375 ** ** TC2.0@PC, KC7.0@MCS51 ** **************************************** */ /* CH375 主机文件系统接口 */ /* 支持: FAT12/FAT16/FAT32 */

/* MCS-51单片机C语言的U盘文件读写示例程序 */ /* 用于以下情况的MCS51单片机 1. 高速MCS51单片机,机器周期小于0.3uS,或者在机器周期为12个时钟时的时钟频率大于40MHz 2. 非总线MCS51单片机,用普通I/O引脚模拟8位并行总线读写,与CH375之间采用并口连接 3. 单片机与CH375之间采用串口连接 */ /* 本程序用于演示将ADC模数采集的数据保存到U盘文件MY_ADC.TXT中 */ /* CH375的INT#引脚采用查询方式处理,本例用普通I/O引脚模拟8位并行总线读写,同时提供串口连接示例, 以字节为单位读写U盘文件,读写速度较扇区模式慢,但是由于字节模式读写文件不需要文件数据缓冲区FILE_DATA_BUF, 所以总共只需要600字节的RAM,适用于单片机硬件资源有限、数据量小并且读写速度要求不高的系统 */

/* C51 CH375HFT.C */ /* LX51 CH375HFT.OBJ , CH375HF5.LIB */ /* OHX51 CH375HFT */

#include #include

#define MAX_BYTE_IO 29 /* 以字节为单位单次读写文件时的最大长度,默认值是29,值大则占用内存多,值小则超过该长度必须分多次读写 */

/* 以下定义的详细说明请看CH375HF5.H文件 */ #define LIB_CFG_FILE_IO 1 /* 文件读写的数据的复制方式,0为"外部子程序",1为"内部复制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */ /*#define LIB_CFG_UPD_SIZE 1*/ /* 在添加数据后是否自动更新文件长度: 0为"不更新",1为"自动更新" */ /* 默认情况下,如果扇区数/字节数不为0那么CH375FileWrite/CH375ByteWrite只负责写入数据而不修改文件长度, 如果需要每次写完数据后会自动修改/更新文件长度,那么可以使全局变量CH375LibConfig的位4为1, 如果长时间不写入数据则应该更新文件长度,防止突然断电后前面写入的数据与文件长度不相符, 如果确定不会突然断电或者后面很快有数据不断写入则不必更新文件长度,可以提高速度并减少U盘损耗(U盘内部的内存寿命有限,不宜频繁改写) */ unsigned char volatile xdata CH375_CMD_PORT _at_ 0xAFF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xADF0; /* CH375数据端口的I/O地址 */ unsigned char volatile xdata CH375_CMD_PORT_U0 _at_ 0x9FF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT_U0 _at_ 0x9DF0; /* CH375数据端口的I/O地址 */ unsigned char Change_Bit; unsigned char xdata copy_buf[512],copy_buf_u0[512]; unsigned char xdata copy_mCmdParam[100],copy_mCmdParam_u0[100]; unsigned char status,status_u0; bit interrupt_bit,interrupt_bit_u0; /* 只使用单片机内置的1KB外部RAM: 0000H-01FFH 为磁盘读写缓冲区, 以字节为单位读写文件不需要文件数据读写缓冲区FILE_DATA_BUF */ #define DISK_BASE_BUF_ADDR 0x0000 /* 外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE */ #define FILE_DATA_BUF_ADDR 0x0200 /* 外部RAM的文件数据缓冲区的起始地址,缓冲区长度不小于一次读写的数据长度,字节模式不用该缓冲区 */ /* 由于单片机内置的外部RAM只有1KB, 有些单片机还要去掉256字节内部RAM, 只剩下768字节的外部RAM, 其中前512字节由CH375子程序用于磁盘数据缓冲 */ #define FILE_DATA_BUF_LEN 0x4000 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度,字节模式不用该缓冲区 */

sbit CH375_INT_WIRE = P1^1; /* P1.1, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */ sbit CH375_INT_WIRE_U0 = P1^2; /* P1.1, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */

#define NO_DEFAULT_CH375_F_ENUM 1 /* 未调用CH375FileEnumer程序故禁止以节约代码 */ #define NO_DEFAULT_CH375_F_QUERY 1 /* 未调用CH375FileQuery程序故禁止以节约代码 */

#include "CH375HFC.H"

/* 本例用I/O引脚模拟产生CH375的并口读写时序 */ /* 本例中的硬件连接方式如下(实际应用电路可以参照修改下述3个并口读写子程序) */ /* 单片机的引脚 CH375芯片的引脚 P3.2 INT# P1.0 A0 P1.1 CS# 如果模拟出的并口上只有CH375,那么CS#可以直接接低电平,强制片选 P1.2 WR# P1.3 RD# P0(8位端口) D7-D0 */ //void mDelay1_2uS( ) /* 至少延时1.2uS,根据单片机主频调整 */ //{ // return; //}

void CH375_PORT_INIT( ) /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */ { P0 = 0xFF; /* 并口输入 */ }

void xWriteCH375Cmd( UINT8 mCmd ) /* 外部定义的被CH375程序库调用的子程序,向CH375写命令 */ { // mDelay1_2uS( ); /* 至少延时1uS */ if(Change_Bit==0x01) CH375_CMD_PORT=mCmd; else if(Change_Bit==0x02) CH375_CMD_PORT_U0=mCmd; // mDelay1_2uS( ); /* 至少延时2uS */ }

void xWriteCH375Data( UINT8 mData ) /* 外部定义的被CH375程序库调用的子程序,向CH375写数据 */ { if( Change_Bit==0x01) CH375_DAT_PORT=mData; else if(Change_Bit==0x02) CH375_DAT_PORT_U0=mData; // mDelay1_2uS( ); /* 至少延时1.2uS */ }

UINT8 xReadCH375Data( void ) /* 外部定义的被CH375程序库调用的子程序,从CH375读数据 */ { UINT8 mData; // mDelay1_2uS( ); /* 至少延时1.2uS */ if( Change_Bit==0x01) mData=CH375_DAT_PORT; if( Change_Bit==0x02) mData=CH375_DAT_PORT_U0; return( mData ); }

/* 延时100毫秒,不精确 */ void mDelay100mS( ) { UINT8 i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }

UINT8 mCopyCodeStringToXRAM( UINT8 xdata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); }

void mCopy_Data_To_Data(unsigned char xdata *data_b0,unsigned char xdata *data_b1,unsigned short len) { unsigned short i; for(i=0;i!=len;i++){ *data_b0=*data_b1; data_b0++; data_b1++; } } /* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ while ( 1 ) { mDelay100mS( ); mDelay100mS( ); } }

/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xfe; /* 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }

void wire_interrupt( )/*检测设备插拔*/ { if(CH375_INT_WIRE==0){ xWriteCH375Cmd(CMD_GET_STATUS); status=xReadCH375Data(); // printf("status=%02x\n",(unsigned short)status); } }

void wire_interrupt_u0( )/*检测设备插拔*/ { if(CH375_INT_WIRE_U0==0){ xWriteCH375Cmd(CMD_GET_STATUS); status_u0=xReadCH375Data(); // printf("status_u0=%02x\n",(unsigned short)status_u0); }

}

main( ) { UINT8 i; UINT32 TotalLen,NewSize; CH375_PORT_INIT( ); /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */ mDelay100mS( ); /* 延时100毫秒 */ mInitSTDIO( ); /* 为了让计算机通过串口监控演示过程 */ printf( "Start\n" ); Change_Bit=0x01; i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i ); Change_Bit=0x02; i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i ); /* 其它电路初始化 */

while ( 1 ) { // printf( "Wait Udisk\n" ); while(1){ if(interrupt_bit==0){ Change_Bit=0x01; wire_interrupt( ); /* 查询CH375中断并更新中断状态,等待U盘插入 */ if(status==0x15)interrupt_bit=1; } if(interrupt_bit_u0==0){ Change_Bit=0x02; wire_interrupt_u0( ); if ( status_u0 == 0x15 )interrupt_bit_u0=1; /* 查询CH375中断并更新中断状态,等待U盘插入 */ } if((interrupt_bit==1)&(interrupt_bit_u0==1))break; } interrupt_bit=0; interrupt_bit_u0=0; mDelay100mS( ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ mDelay100mS( );

/* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ Change_Bit=0x01; for ( i = 0; i < 5; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */ mDelay100mS( ); // printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ){ mCmdParam.SaveVariable.mSaveVariable=1; //为0时恢复变量,为1时保存变量 mCmdParam.SaveVariable.mBuffe


这个应该是我们提供的U盘对考例程,对考的流程就是这个样子 另,注意CH375地址线、中断线需要与实际的硬件一致


sbit CH375_INT_WIRE = P1^1; /* P1.1, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */ sbit CH375_INT_WIRE_U0 = P1^2; /* P1.1, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */

这里面怎么有两个 P1.1 ,注释是不是错了


您说的“CH375地址线、中断线需要与实际的硬件一致”是什么意思,是完全要和图中的一样是吗?不能改动?两片375的INT#脚都要接51单片机的P1.1吗?


(1)注释标错了,2片375当然要用不同的中断线 (2)硬件是如何定义的,那么程序中就必须定义与硬件一致的地址,否则怎么操作芯片呢


朋友帮人帮到底吧!不要烦累?!?!我问最后一个问题,我费了好大劲买的是375BBBBBBBBBBBB可以吗?


80C51不是52,还行吗?


(1)可以,目前主推的就是CH375B (2)这两种程序空间都不够,89C55才可以


CH375B是可以的,80C51估计不行,你需要选型的单片机程序空间在16K左右,RAM最少需要600个字节,如果按照扇区方式对拷的话,RAM还需要加大点.


  建议楼主考虑选择STC11F16XE或数字在16以上的同类型号,不但可以满足hcn老师提供的参数,且速度完全适应CH375B能够提供的最大速率。


谢谢


高手来指点指点:我的375地址按照上面的程序改动的 unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBFF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBDF0; /* CH375数据端口的I/O地址 */ unsigned char volatile xdata CH375_CMD_PORT_U0 _at_ 0xAFF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT_U0 _at_ 0xADF0; /* CH375数据端口的I/O地址 */ 但是怎么实现不了呢?

另像这种“// mCopy_Data_To_Data(copy_buf_u0,DISK_BASE_BUF,0x200);”指令是不是//的存在都没有起作用啊,这是字节读取吗?


有人帮我看一下吗?


(1)实现不了,具体现象是什么,哪步出了问题,说具体点,不然我们怎么分析,总不能猜测吧!我们的程序中有串口调试,程序停在哪一部都会有提示。 (2)//mCopy_Data_To_Data,“//”表示注释,被注释了,自然不起作用了,C语言基本语法啊


只有登录才能回复,可以选择微信账号登录