原创 沁恒电子的CH376U盘模块读写

2011-3-1 19:51 7188 7 7 分类: MCU/ 嵌入式

 

本日记使用的是沁恒电子的CH376U盘模块读写, 采用PIC芯片;

我把调试过程简单的介绍下,希望给各位需要设计U盘读写的参考思路。

uint8  UsbSendDataFun(  uint8  * u8UsbSendRam ) {  //

//   最好关闭中断;  数据采集时候会发生意外的呢;

uint8 u8UsbRamBuf[20]; // 文件名字RAM;   

uint8 ucTemp;   // 变量;      

uint16 uiTemp; // 用于USB 传输范围的 选择;

uint16 retry;  // uint16 adc, month, date, hour;

uint8 *ui8BufPtr;  //  存16通道 参数的 数组 //

uint16 U16SendPagePtr; // 发送的指针;

uint8 u8FunRet;  //  返回发送 报告;

 

DelayNMs(100);  // while ( 1) {  // DfDisInter;   // 关闭中断;
 
retry =0;  //  // 初始化CH376 // 

while ( retry< 10 ){  // 10 S  ?

u8FunRet= mInitCH376Host( );  // 初始化CH376

if ( u8FunRet== USB_INT_SUCCESS ){  break;}  //    // // 继续;  // OK // return  0xff ;   // 报告上层调用的函数,出错了;

else { // 初始化失败; 延时是10S,  通信陈宫;成功,延时大约3S;

retry ++;

DelayNMs( 10);

} //

} //  retry++ 

if ( u8FunRet!= USB_INT_SUCCESS ){    // 初始化失败;
 
return  DfInitCH376HostErr;  // ERR_USB_UNKNOWN;   // 报告上层调用的函数,出错了;

} //
else{; }

 

CLRWDT(); // 清看门狗  // 假如N次芯片复位后, 系统还是连不上, 就需要复位PIC 系统! 突然拔掉5V电源;

retry=0;

// 检查U盘是否连接,等待U盘插入,对于SD卡,  可以由单片机直接查询SD卡座的插拔状态引脚 // 

while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) {  //  return  0xff ;   //

if ( retry > 10) {//   break;    // //   关闭U 盘,避免浪费电源; 和意外的发生;就是退出后, U盘写入的文件无法更新;

return  DfUSBUnConnect;  // ERR_USB_UNKNOWN;
}//     
else{  retry ++ ;

DelayNMs(10 );   //   如果没有 U 盘的话; 执行任务 : 否则退出,写U盘;
}

}//

 
// 检查U盘是否连接,  否则退出,写U盘; // CH375_DelayNms(100);   // 延时500ms让U盘准备好  

DelayNMs( 100 );  // 延时,可选操作,有的USB存储器需要几十毫秒的延时 //


// 对于检测到USB设备的,最多等待10*50mS //
retry =0;  

while ( 1 ) {  // 最长等待时间,10*50mS //   

CLRWDT(); // 清看门狗 // DelayNMs(20 );  //// printf( "Ready ?\n" );  // 30 S

// 初始化磁盘并测试磁盘是否就绪 //   
if ( CH376DiskMount( ) == USB_INT_SUCCESS ) { break;   } // // Ok

if ( retry > 10){  // #define DfCH376DiskMountErr  5

return DfUSBDiskMountErr ;// ERR_USB_UNKNOWN;

} //
else  {  retry ++ ;


DelayNMs(10 );  // 1S
}//

}// 次数超过,也退出;
 

xWriteCH376Cmd( CMD_SET_FILE_NAME );  // 设置将要操作的文件的文件名,通配符支持所有文件和子目录 
xWriteCH376Data( '/' );
xWriteCH376Data( '*' );
xWriteCH376Data( 0 );
xWriteCH376Cmd( CMD_FILE_OPEN );  // 枚举文件和目录 
while ( 1 ) {

//s = mWaitInterrupt( );
s =Wait376Interrupt( );
if ( s == USB_INT_DISK_READ ) {  // 请求数据读出 
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
printf( "Name: ");
xReadCH376Data( );  // 长度总是sizeof(FAT_DIR_INFO) 

for ( s = 0; s != 8+3; s ++ ) printf( "%c", xReadCH376Data( ) );
printf( "         (%c)\n", xReadCH376Data( )&ATTR_DIRECTORY?'#':'*' );  // 目录显示#后缀,文件显示*后缀
for ( s = 11; s != sizeof( FAT_DIR_INFO ); s ++ ) xReadCH376Data( );  // 取出后续数据 
xWriteCH376Cmd( CMD0H_FILE_ENUM_GO );  // 继续枚举文件和目录 //
}
else if ( s == ERR_MISS_FILE ) break;  //没有找到更多的匹配文件,正常结束 //
// else mStopIfError( s );  // 操作出错 //
}

//  列举目录成功! 2011 0127

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//  如果USB在线,且有数据可以继续创建文件
 
memcpy(&u8UsbRamBuf[0],"RECD00.BIN" , 11); // printf("buf = ’%s’\n", buf);

if( ( Gu16SysComAddr >99)||(Gu16SysComAddr<0)) { Gu16SysComAddr=1;  }
// 补丁; 如果地址溢出,那么就错误;

u8UsbRamBuf[0+4]=Gu16SysComAddr/10+'0'; //    // Show_Numstring8x8( (0)*8,0,&u8UsbRamBuf[0],5 );  // +符号位   
u8UsbRamBuf[1+4]=Gu16SysComAddr%10+'0'; //    // Show_Numstring8x8( (0)*8,0,&u8UsbRamBuf[0],5 );  // +符号位   

// u8UsbRamBuf[0]='0'+1;  // GWriteCout%9 // 要在RAM中建立文件名成功了太好了我将工程 CLEAN了 再编译就好了;

u8FunRet= CH376FileCreate( &u8UsbRamBuf[0] );    // 新建 文件并打开

DfenablInter;

//  "/ MY_ADC.TXT"NULL新建文件并打开,如果文件已经存在则先删除后再新建, 
// 不必再提供文件名,刚才已经提供给CH376FileOpen //   

if ( u8FunRet== USB_INT_SUCCESS ) {   // 文件名创建成功;

// 调用数据写入程序;
u8FunRet=UsbSendRecdDatFun(u8UsbSendRam );// 正常传送;

if( u8FunRet == USB_INT_SUCCESS ){; // 继续下面的程序;

} else{ return  u8FunRet ;  }

}  //    // 继续;  // OK ; // return   ;    
else {  // return DfCH376DiskMountErr ;

return  u8FunRet; 
} // // 报告上层调用的函数,出错了;// ERR_USB_UNKNOWN;

 

// 所以只用于更新文件的长度,当阶段性写入数据后,可以用这种办法更新文件长度 //  

// CH376ByteWrite( buf, 0, NULL );  //以字节为单位向文件写入数据,因为是0字节写入,

// 关闭文件,自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 // 

// DfDisInter; // 关闭中断; 
u8FunRet= CH376FileClose( TRUE );  //

DfenablInter;

DelayNMs(100); // 复位完成;

DelayNMs( 2000 );  // 延时,可选操作

//  printf( "Write end\n" );  //
 
return  u8FunRet;    

// return  USB_INT_SUCCESS;    //  成功退出  OK ;  

}// end file  main;

 

 

//////////////////////////////////////////////////////////////模拟出的并口的时序/////////////////////////////////////////////////////////////////////////////////

 

// 由于使用通用I/O模拟并口读写时序,所以进行初始化 如果模拟出的并口上只有CH376*/

void CH376_PORT_INIT( void ) 
{
// 实现对A口进行初始化;//  //  设置与模拟通道有关的口全部为数字  
ADCON1 = 0x0f; //   // DfLcd_CtrlOutput();

DirCH376_CD=0;
DirCH376_WR=0;
DirCH376_RD=0;  //  输出;

mDelayuS( 4);
CH376_WR = 1;
mDelayuS( 4);
CH376_RD = 1;
mDelayuS( 4);
DfCH376_CD = 0;

mDelayuS( 4);

CH376_DATA_DIR_IN( );  // 设置并口输入 //

DfCH376_CS = 1; // 无效
}

 

// #define xEndCH376Cmd( )  // 结束CH376命令,仅用于SPI接口方式 //


// 从CH376读状态,仅用于并口方式 //
UINT8 xReadCH376Status( void ) {

UINT8 mData;

// DfPsp_CS=0; // 总的数据线片选;

CH376_DATA_DIR_IN( );  // 设置并口方向为输入 //
 
DfCH376_CD = 1;
DfCH376_CS = 0;
mDelayuS( 4);
CH376_RD = 0;  // 输出有效读控制信号, 读CH376芯片的状态端口 //
DfCH376_CS = 0; 
// 该操作无意义,仅作延时,CH376要求读写脉冲宽度大于40nS,强烈建议此处执行一条空指令延时以确保并口有足够时间输入数据 //

mDelayuS( 4);
mData = CH376_DATA_DAT_IN( );  // 从CH376的并口输入数据 //
CH376_RD = 1;  // 输出无效的控制信号, 完成操作CH376芯片 //
DfCH376_CS = 1;
DfCH376_CD = 0;

// DfPsp_CS=1; // 总的数据线片选;

DfCH376_CS = 1; // 无效

return( mData );
}

void xWriteCH376Cmd( UINT8 mCmd ){  // 向CH376写命令 //


CH376_DATA_DIR_OUT( );  // 设置并口方向为输出 // 
mDelayuS( 5);
CH376_DATA_DAT_OUT( mCmd );  // 向CH376的并口输出数据 // PORTD =  mCmd ;

DfCH376_CD = 1;
DfCH376_CS = 0;
CH376_WR = 0;  // 输出有效写控制信号, 写CH376芯片的命令端口 //
mDelayuS( 4);
DfCH376_CS = 0;  // 该操作无意义,仅作延时,CH376要求读写脉冲宽度大于40nS //


CH376_WR = 1;  // 输出无效的控制信号, 完成操作CH376芯片 //
DfCH376_CS = 1;
DfCH376_CD = 0;
mDelayuS( 4);
CH376_DATA_DIR_IN( );  // 禁止数据输出 //

// mDelay0_5uS( ); mDelay0_5uS( ); mDelay0_5uS( );// 
// 延时1.5uS确保读写周期大于1.5uS,或者用状态查询代替 //
DfCH376_CS = 1; // 无效

}

void xWriteCH376Data( UINT8 mData )  // 向CH376写数据 //
{
 
CH376_DATA_DIR_OUT( );  // 设置并口方向为输出 //
mDelayuS( 5);

CH376_DATA_DAT_OUT( mData );  // 向CH376的并口输出数据 //

mDelayuS( 5);
 
DfCH376_CD = 0;
DfCH376_CS = 0;
CH376_WR = 0;  // 输出有效写控制信号, 写CH376芯片的数据端口 //
mDelayuS( 4);
DfCH376_CS = 0;  // 该操作无意义,仅作延时,CH376要求读写脉冲宽度大于40nS //

CH376_WR = 1;  // 输出无效的控制信号, 完成操作CH376芯片 //
DfCH376_CS = 1;
mDelayuS( 4);

CH376_DATA_DIR_IN( );  // 禁止数据输出 //
// mDelay0_5uS( );  // 确保读写周期大于0.6uS //

DfCH376_CS = 1; // 无效
}

UINT8 xReadCH376Data( void )  // 从CH376读数据 //
{
UINT8 mData;

// mDelay0_5uS( );  // 确保读写周期大于0.6uS // // CH376_WR = 0;

CH376_DATA_DIR_IN( );  // 设置并口方向为输入 //
mDelayuS( 4);

DfCH376_CD = 0;
DfCH376_CS = 0;
CH376_RD = 0;  // 输出有效读控制信号, 读CH376芯片的数据端口 //
DfCH376_CS = 0;  // 该操作无意义,仅作延时,CH376要求读写脉冲宽度大于40nS,强烈建议此处执行一条空指令延时以确保并口有足够时间输入数据 //

mDelayuS( 4);
mData = CH376_DATA_DAT_IN( );  // 从CH376的并口输入数据 //
CH376_RD = 1;  // 输出无效的控制信号, 完成操作CH376芯片 //


DfCH376_CS = 1; // 无效

return( mData );
}

 

// 查询CH376中断(INT#低电平) //
UINT8 Query376Interrupt( void )
{

#ifdef CH376_INT_WIRE
 return( CH376_INT_WIRE ? FALSE : TRUE );  // 如果连接了CH376的中断引脚则直接查询中断引脚 
#else
 return( xReadCH376Status( ) & PARA_STATE_INTB ? FALSE : TRUE );  // 如果未连接CH376的中断引脚则查询状态端口 //
#endif

// return( xReadCH376Status( ) & PARA_STATE_INTB ? FALSE : TRUE );  // 如果未连接CH376的中断引脚则查询状态端口 //

}


 // 初始化CH376 //
UINT8 mInitCH376Host( void ) {

UINT8 res=0;

CH376_PORT_INIT( );  // 接口硬件初始化 //

Gres=res;       // 观察的; 中间变量

xWriteCH376Cmd( CMD11_CHECK_EXIST );  // 测试单片机与CH376之间的通讯接口 //

xWriteCH376Data( 0xf0  ); // 那么CH376的输出数据是输入数据的按位取反。~0x65=0x9A

res = xReadCH376Data( );

Gres=res;       // 观察的; 中间变量

// xEndCH376Cmd( );  // 并口方式不需要
if ( res != 0x0f ) return( ERR_USB_UNKNOWN );  // 通讯接口不正常,可能原因有:接口连接异常,其它设备影响(片选不唯一),串口波特率,一直在复位,晶振不工作 //

xWriteCH376Cmd( CMD11_SET_USB_MODE );  // 设备USB工作模式 //
xWriteCH376Data( 0x06 );

mDelayuS( 20 );

res = xReadCH376Data( );
Gres=res;       // 观察的; 中间变量;

// xEndCH376Cmd( );  // 并口方式不需要
if ( res == CMD_RET_SUCCESS ) return   ( USB_INT_SUCCESS );
else return( ERR_USB_UNKNOWN );  // 设置模式错误 //
}

 

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条