[求助]PIC读取U盘,出现读取错误

我用PIC MCU控制CH375,读取U盘中的MP3数据到VS1003中解码播放,在播放中途出现数据读取错误,经过仿真跟踪,发现CH375无法产生中断信号,CH375的中断处理采用查询方式.请问这种情况是什么原因,该怎么解决呢? 相关的程序如下: /******************************************* 函数名称:Ch375WaitInt() 作 用:等待CH375中断 入 口:无; 出 口:中断状态 *******************************************/ unsigned char Ch375WaitInt( void ) { unsigned long x; x = 0x3fffff; while( USBINT>0 ) { // 查询等待CH375操作完成中断(INT#低电平) USBINT_T = 1; x--; if( x == 0 ) { break; } } if(x == 0) { return USB_INT_DISK_ERR; }

Ch375WrCmdPort( CMD_GET_STATUS ); /* 产生操作完成中断,获取中断状态 */ return( Ch375RdDatPort( ) ); }

/******************************************* 函数名称:CH375WriteSector() 作 用:CH375扇区写入 入 口:扇区号LBA,缓冲区地址 出 口:返回状态; *******************************************/ unsigned char CH375WriteSector( unsigned long lba, unsigned char *buff ) { unsigned char blockcnt,cnt; Ch375WrCmdPort( CMD_DISK_WRITE ); Ch375WrDatPort( (unsigned char)(lba&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>8)&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>16)&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>24)&0xff) ); Ch375WrDatPort( 1 ); //写一个扇区 for( blockcnt=8; blockcnt>0; blockcnt--) { cnt = Ch375WaitInt(); if( cnt == USB_INT_DISK_WRITE ) { Ch375WrCmdPort( CMD_WR_USB_DATA7 ); Ch375WrDatPort( 64 ); //写入64字节 for( cnt=64 ; cnt>0; cnt--) { Ch375WrDatPort( *buff ); buff++; } Ch375WrCmdPort( CMD_DISK_WR_GO ); } else { break; } } if( blockcnt == 0 ) { return( Ch375WaitInt() ); } else { return(cnt); } }

补充说明一下,上述故障是随机出现的,有时候出现在刚开始播放,有时候在播放的中途出现,播放高速率音乐和低速率的时候都是一样的~~~


(1)读文件的部分的程序在哪? (2)可以做个实验,把读取出来数据扔掉,不送给VS1003播放,看看能否正确读完一个文件。 (3)能否把整个流程贴出来,从读文件到送给VS1003播放


SCM您好~~程序如下: /******************************************* 函数名称:_ISR _CNInterrupt() 作 用:电平变化中断处理 入 口:无; 出 口:无; *******************************************/ void _ISR _CNInterrupt( void ) { unsigned int cnt = 0; static unsigned char tcnt = 0; char buff[32]; unsigned char state; static unsigned long size = 0L;

if( ( _CNIE && _CN17IE ) && _CNIF ) { while( _RF4 == 1 ) { Mp3VolumeSet(); //音量设置 Mp3EffectSet(); //音效设置 cnt = FSfread ((char *)buff, 1, 32, gAudioFilePointer);//读取数据 size += cnt;//调整已读文件大小 state = 0; if( cnt != 32 ) { Isr_CN_Close();//关闭中断 FSfclose( gAudioFilePointer );//关闭文件 gMp3Status &= 0xfc;//清除播放状态标志 gMp3Status |= MP3OVERMODE; //播放结束 state = 1; if( ( size != gAudioFilePointer->size )&&( cnt == 0 ) ) {//文件读取错误 break; } }

//数据读取正常,装载数据 tcnt++; WaitBusy(); LoadAudioData( (char *)buff, cnt ); if( (tcnt&0x7f) == 0 ) {//每4K数据读取时间寄存器 gAudioDecodeTime = Mp3SCIRead( SPI_DECODE_TIME ); WaitBusy();//等待VS1003命令处理完毕 tcnt = 0; } cnt = 0; if( size == gAudioFilePointer->size ) { break; }//文件播放完毕,退出 } if( state > 0 ) { size = 0; ClearMp3Ram(); //清除VS1003的内部RAM Mp3SCIWrite(SPI_VOL, 0xffff); //静音 tcnt = 0; } cnt = PORTF; _CNIF = 0; //清除标志 } }

数据读取是采用VS1003中断来读取数据的,VS1003可以输入数据的时候,中断程序读取已经打开的文件将VS1003缓冲器填满后退出中断,中送数据前检查是否需要设置音量或者音效,每传送4K数据读取一次时间寄存器,防止频繁的读取时间寄存器影响CPU的工作效率. . 读取程序如下,昨天是大意,本来是上传读程序,结果弄错了.

************************************** 函数名称:CH375ReadSector() 作 用:CH375扇区读取 入 口:扇区号LBA,缓冲区地址 出 口:返回状态; *******************************************/ unsigned char CH375ReadSector( unsigned long lba, unsigned char *buff ) { unsigned char blockcnt,cnt; Ch375WrCmdPort( CMD_DISK_READ ); Ch375WrDatPort( (unsigned char)(lba&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>8)&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>16)&0xff) ); Ch375WrDatPort( (unsigned char)((lba>>24)&0xff) ); Ch375WrDatPort( 1 ); //读取一个扇区 for( blockcnt=8; blockcnt>0; blockcnt--) { cnt = Ch375WaitInt(); if( cnt == USB_INT_DISK_READ ) { Ch375WrCmdPort( CMD_RD_USB_DATA ); cnt = Ch375RdDatPort(); for( ; cnt>0; cnt--) { *buff = Ch375RdDatPort(); buff++; } Ch375WrCmdPort( CMD_DISK_RD_GO ); } else { break; } } if( blockcnt == 0 ) { return( Ch375WaitInt() ); } else { return(cnt); }

}

另外设置全文件读取而不播放的方式,我需要修改程序试一下,由于公司另做安排,需要出差几天,希望大家能多帮助一下,谢谢,等项目完成后,我会把PIC+CH375是全套FAT程序与大家共享~~


读取扇区部分的流程基本没问题。只是命令与数据之间的延时和数据与数据之间的延时是多少?具体的参数可以参考手册 还有你所说的出错,错在哪一步,出什么错


SCM,你好! 出差回来了,耽搁了几天.

按照你建议的直接程序读取我测试了,依然发生读取错误.

我的命令之间的延迟4uS左右,数据间的延迟是4uS左右. 出错是如下程序发生超时退出,具体是 CH375ReadSector( unsigned long lba, unsigned char *buff ) 中的那一句我还要再测试一下才知道. /******************************************* 函数名称:Ch375WaitInt() 作 用:等待CH375中断 入 口:无; 出 口:中断状态 *******************************************/ unsigned char Ch375WaitInt( void ) { unsigned long x; x = 0x3fffff; while( USBINT>0 ) { // 查询等待CH375操作完成中断(INT#低电平) USBINT_T = 1; x--; if( x == 0 ) { break; } } if(x == 0) { return USB_INT_DISK_ERR; }

Ch375WrCmdPort( CMD_GET_STATUS ); /* 产生操作完成中断,获取中断状态 */ return( Ch375RdDatPort( ) ); }


斑竹,你好!

数据读取错误的问题已经解决了~~问题与芯片及程序都没有关系,是因为我的并行口是模拟时序,与我的LCD发生了冲突,忘记了对LCD操作时候禁止中断.现在已经解决~~特报告一下!

不过现在也遇到了另外的问题,我的芯片是CH375B和CH375V,两种型号的芯片都出现了U盘识别率比较低,很多SD卡读卡器(单SD卡读卡器)都无法识别,MP3\MP4也不能连接识别,想问问初始化连接这些USB设备需要注意些什么?请指点一二. 我的初始化程序如下:

/******************************************* 函数名称:Ch375Init() 作 用:初始化CH375工作状态 入 口:无; 出 口:无; *******************************************/ void Ch375Init( void ) { CH375PortInit(); UsbSelection( HOSTUSB1 ); //USB通道选择 Ch375ResetAll(); Ch375WrCmdPort( CMD_SET_USB_MODE ); // 初始化CH375,设置USB工作模式 Ch375WrDatPort( 0x06 ); // 模式代码,自动检测USB设备连接 D_N_mS(1000); //延迟1S }

/******************************************* 函数名称:DiskInit() 作 用:初始化移动存储器 入 口:磁盘容量信息存放指针; 出 口:返回测试状态; *******************************************/ unsigned char DiskInit( unsigned char *buff ) { unsigned char state; unsigned char cnt; Ch375WrCmdPort( CMD_GET_STATUS ); CH375_Hold(10); state = Ch375RdDatPort(); if( state == USB_INT_DISCONNECT ) { return(state); } Ch375WrCmdPort( CMD_DISK_INIT ); // 初始化USB存储器 state = Ch375WaitInt(); if( state != USB_INT_SUCCESS ) { return(state); } Ch375WrCmdPort( CMD_DISK_SIZE ); // 获取USB存储器的容量 state = Ch375WaitInt(); if( state != USB_INT_SUCCESS ) { D_N_mS(100); Ch375WrCmdPort( CMD_DISK_SIZE ); state = Ch375WaitInt(); } if( state != USB_INT_SUCCESS ) { return(state); } //读取磁盘信息 Ch375WrCmdPort( CMD_RD_USB_DATA ); cnt = Ch375RdDatPort(); for(; cnt>0; cnt--) { *buff = Ch375RdDatPort(); buff++; } return( USB_INT_SUCCESS ); }

通过仿真跟踪,无法识别的U盘设备都是在"Ch375WrCmdPort( CMD_DISK_INIT );"这条语句,返回的状态都是错误状态.具体数值是0x20.

请问,为了提高识别率我的初始化工作应该怎么做?可以提供初始化流程吗?


U盘的兼容性并不仅仅取决于芯片本身,还与程序有很大的关系。上面的初始化使用了芯片内置U盘固件,初始化流程比较简单,支持率也很难提升。现在提供的始化流程也只有这么多。我们的子程序库可以支持市面95%以上的U盘,建议使用我们的子程序库操作U盘


Hi,sem,我也希望用你们的芯片用你们的程序库,我们只能用PIC的芯片,而偏偏你们就是没有PIC的程序库~~~嘿嘿~~PIC也算数一数二的芯片,就是很奇怪你们为什么不支持啊~~

现在也就是说想提高支持率如果不用你们的库或者你们不支持的库就完全没有其他的方法了吗?


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