关于CH375读U盘的物理扇区数据

楼主,您好   我在读U盘的物理扇区时,读到的总是U盘的产品型号,我的程序如下,   因EMAIL老是超时,发不出,我的EMAIL:MICHAEL.DU@AVERA-TECH.COM

//HOST //*********************************************************

#include "c8051F410.h" #include "main.h"

//************************************************ // main ASM // system clock=50M //************************************************

void main(void) { PCA0MD &= ~0x40; /*watch dog*/ Sys_Clk_Init(); Port_Init();

// Flash_Init(); // Flash_RD_ID();

// Main_Init(); Ch375_Init();

while(Ch375_Counter != 0x14) { Ch375_Command(0x51); Ch375_Counter=Ch375_Status(); Delay_xxuS(50000); Delay_xxuS(50000); }

Ch375_RD_Page(); while(1); } void Ch375_RD_Page(void) { data char i;

Fat_Pointer=0x00; Ch375_Command(0x54); // while(Ch375_INT); // i=Ch375_Status(); Ch375_WR_Data(0x8a); Ch375_WR_Data(0x00); Ch375_WR_Data(0x00); Ch375_WR_Data(0x00); Ch375_WR_Data(0x01);

while(Ch375_INT); i=Ch375_Status();

for(i=0;i<8;i++) { Ch375_Command(0x28);

for(Ch375_Counter=0x00;Ch375_Counter<65;Ch375_Counter++) { Fat_Data[Fat_Pointer]=Ch375_RD_Data(); Fat_Pointer++; } Ch375_Command(0x55); while(Ch375_INT); // Ch375_Status();

} }

//********************************************************* // ch375相关子程序 //********************************************************* void U_Communication(void) { if(J2a_Pointer>=512) { Ch375_Command(0x56); } }

char Ch375_Init(void) { char temp=0; char temp1;

Ch375_Command(0x05); Delay_xxuS(40000);

Ch375_Command(0x15); //工作模式输入 Delay_xxuS(100); Ch375_WR_Data(0x06); temp1=Ch375_RD_Data();

Ch375_Command(0x06); //CH375 CHIP检测 Ch375_WR_Data(0x11); temp1=Ch375_RD_Data(); //总是0xFF

Ch375_Command(0x06); //CH375 CHIP检测 Ch375_WR_Data(0x11); temp1=Ch375_RD_Data();

Ch375_Command(0x06); Ch375_WR_Data(0x34); temp1=Ch375_RD_Data();

Ch375_Command(0x51); //工作模式输入 temp1=Ch375_RD_Data();

return(temp1); }

char Ch375_Status(void) { char temp; Ch375_Command(0x22); temp=Ch375_RD_Data(); return(temp); }

void Usb_Err(void) {

}

void Sram_To_Usb(void) {

}

void Usb_To_Sram(void) {

}

void Ch375_Command(command) { idata volatile char nop_nop;

P1MDOUT=0xff; Ch375_A0=1; P1=command; Ch375_CE=0; Ch375_WE=0; nop_nop++; nop_nop++; nop_nop++; nop_nop++; Ch375_WE=1; Ch375_CE=1; Ch375_A0=0;

for(nop_nop=0;nop_nop<5;nop_nop) nop_nop++; }

void Ch375_WR_Data(value) { idata volatile char nop_nop; P1MDOUT=0xff; P1=value; Ch375_CE=0; Ch375_WE=0; nop_nop++; nop_nop++; nop_nop++; nop_nop++; Ch375_WE=1; Ch375_CE=1; for(nop_nop=0;nop_nop<2;nop_nop) nop_nop++; }

char Ch375_RD_Data(void) { idata volatile char nop_nop; unsigned char para;

P1MDOUT=0x00; P1=0xff; Ch375_CE=0; Ch375_RE=0; nop_nop++; nop_nop++; nop_nop++; nop_nop++; para=P1; Ch375_RE=1; Ch375_CE=1; // P1=0xff; for(nop_nop=0;nop_nop<2;nop_nop) nop_nop++; return(para); }

//************************************************** // sys_clk_init() //************************************************** void Sys_Clk_Init(void) { int i = 0;

PFE0CN &= ~0x20; FLSCL = 0x10; PFE0CN |= 0x20; OSCICN = 0x87; CLKMUL = 0x80; for (i = 0; i < 20; i++); // Wait 5us for initialization CLKMUL |= 0xC0; while ((CLKMUL & 0x20) == 0); CLKSEL = 0x02; }

//************************************************** // Port_Init() //************************************************** void Port_Init(void) { P0MDIN=0xff; P1MDIN=0xff; P2MDIN=0xff; P0=0x2b; P2=0xff; // P1=0xff; P0MDOUT=0xdc; // P1MDOUT=0xff; P2MDOUT=0xf7; XBR0=0x01; //enable uart0 XBR1=0x40; //enable port

Ch375_CE=1; Ch375_A0=0;

Flash_CE=1; //init i/o Flash_RE=1; Flash_WE=1; Flash_R_B=1; //OPEN DRAIN Flash_CLE=0; Flash_ALE=0;

J2a_CS=1; J2a_INT=1; J2a_RST=0; }

//************************************************** // 中断 //************************************************** void INT_Init (void) { SCON0= 0x50; /*SCON0:模式1,8位UART,时能RX*/ TMOD= 0x20; /*TMOD: 定时器工作再模式2, 8位重载*/ TH1= 202; /*设置定时1用作波特率的重载值 256-49000k/48/2/9.6k=203 */ TR1= 1; /*开定时器1*/ CKCON |= 0x02; /*定时器1用系统时钟作为它的时基 /48*/ PCON |= 0x80; /*SMOD00 = 1*/ ReceiveBit=0; ES0=1; //UART中断标志

TMR2CN=0x00; //TC2,时钟选择SYSTEM CLOCK/12 TMR2RLL=0x3D; //10mS TMR2RLH=0x5D; TMR2L=0x3D; TMR2H=0x5D; TR2=0;

IT01CF=0x01; //INT0 低电平中断 P0.1 IT0=0; EX0=0; //允许INT0中断 EA=0; /*开中断标志*/ }

void UART0_ISR (void) interrupt 4 { if(!TI0) //是发送中断还是接收中断 { RI0 = 0; /*清接收标志位*/ Receiver =SBUF0; /*保存接收到的数据*/ ReceiveBit=1; /*置接收标志*/ } TI0 = 0; /*清发送标志位*/ }

void Delay_xxuS(temp) //用示波器校正过,总是>temp uS { int idata x; for(x=0;x Delay_1uS(); }

void Delay_1uS(void) { idata char xx; for(xx=0;xx<10;xx) xx++; }

void Delay() { data int x; for(x = 0;x <300;x) x++; }

UINT8 mInitDisk( void ) { /* 初始化磁盘 */ UINT8 Status,i,j=0; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ Status = CH375_RD_DAT_PORT( ); if ( Status == USB_INT_DISCONNECT ) return( Status ); /* USB设备断开 */ CH375_WR_CMD_PORT( CMD_DISK_INIT ); /* 初始化USB存储器 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status != USB_INT_SUCCESS ) return( Status ); /* 出现错误 */ while(1){j++; CH375_WR_CMD_PORT( CMD_DISK_SIZE ); /* 获取USB存储器的容量 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ) break; /* 出现错误 */ mDelaymS( 250 ); if(j==5) return(Status); } CH375_WR_CMD_PORT( CMD_DISK_R_SENSE ); /* 获取USB存储器的容量 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ){ /* 出现错误 */ for(i=0;i!=5;i++){ printf("Ready\n"); CH375_WR_CMD_PORT( CMD_DISK_READY ); /* 获取USB存储器的容量 */ Status = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( Status == USB_INT_SUCCESS ) break; /* 出现错误 */ } } return( 0 ); /* U盘已经成功初始化 */ } 上面是初始化U盘的函数,还有就是你在读取物理扇区的时候,请按照下面的步骤来操作: UINT8 mReadSector( UINT32 iLbaStart, UINT8 iSectorCount, UINT8X *oDataBuffer ) { /* 从U盘读取数据块到缓冲区 */ /* iLbaStart 起始扇区号, iSectorCount 扇区数, oDataBuffer 缓冲区起址 */ UINT16 mBlockCount; UINT8 c; CH375_WR_CMD_PORT( CMD_DISK_READ ); /* 从USB存储器读数据块 */ CH375_WR_DAT_PORT( (UINT8)iLbaStart ); /* LBA的最低8位 */ CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 8 ) ); CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 16 ) ); CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */ CH375_WR_DAT_PORT( iSectorCount ); /* 扇区数 */ for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) { /* 数据块计数 */ c = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( c == USB_INT_DISK_READ ) { /* 等待中断并获取状态,USB存储器读数据块,请求数据读出 */ CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从CH375缓冲区读取数据块 */ c = CH375_RD_DAT_PORT( ); /* 后续数据的长度 */ while ( c -- ) *oDataBuffer++ = CH375_RD_DAT_PORT( ); /* 根据长度读取数据并保存 */ CH375_WR_CMD_PORT( CMD_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */ } else break; /* 返回错误状态 */ } if ( mBlockCount == 0 ) { c = mWaitInterrupt( ); /* 等待中断并获取状态 */ if ( c== USB_INT_SUCCESS ) return( 0 ); /* 操作成功 */ } return( c ); /* 操作失败 */ }


CH375初始化程序,应该是先测试硬件连线,再发模式设置。 unsigned char mCH375Init( ) { unsigned char i; #ifdef TEST_CH375_PORT unsigned char c; CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 测试工作状态 */ CH375_WR_DAT_PORT( 0x55 ); /* 测试数据 */ c = CH375_RD_DAT_PORT( ); /* 返回数据应该是测试数据取反 */ if ( c != 0xaa ) { /* CH375出错 */ for ( i = 100; i != 0; i -- ) { /* 强制数据同步 */ CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* CH375执行硬件复位 */ c = CH375_RD_DAT_PORT( ); /* 延时 */ } mDelay100mS( ); /* 延时至少30mS */ } #endif CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); /* 设置USB工作模式 */ CH375_WR_DAT_PORT( 6 ); /* 模式代码,自动检测USB设备连接 */ for ( i = 0xff; i != 0; i -- ) /* 等待操作成功,通常需要等待10uS-20uS */ if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; /* 操作成功 */ if ( i != 0 ) return( 0 ); /* 操作成功 */ else return( 0xff ); /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */ }

C8051读写U盘如果以文件系统操作的话你可以直接调用我们51的子程序库;如果以物理扇区直接操作的话可以参考CH375EVT\PUB\MCS51C\MISCELL\CH375EV0.C。


谢谢各位帮忙


问题还是解决不了,还是老问题  


按照我们的流程写的初始化U盘的命令都通过了吗???


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