CH376读写sd问题[求助]

我用的是mega128控制376读写sd卡,目前可以通过初始化,但是我用CH376DiskCapacity函数去读sd卡容量时,总是返回5f 7f 7f 7f,我知道返回是卡的总扇区数量,就是乘以512也不是卡容量啊?这是怎么回事啊?

还有,我希望贵公司能写一个完整的只支持sd卡的范例,所有代码都是基于u盘的,就算是sd的范例也需要用户改写,sd这块我弄了好几天了一些基本函数都没有通过。。。。


实际上读写SD卡和读写U盘的区别只有2个地方,一个是模式的设置,SD卡设置模式3,U盘设置模式6.另一个就是设备的插拔的检测,U盘采用我们芯片的INT#引脚来检测,而SD卡则需要单独的使用一个单片机的I/O口来进行检测。至于其他的软件上面完全一样。


为什么调用CH376DiskCapacity,返回是5f7f7f7f呢?


而且还不是sd卡的总扇区数?


CH376DiskMount( )函数是否返回成功?然后你在做i = CH376ReadBlock( buf );看看是否也返回成功。


调用CH376ReadBlock,回复的是0x24这个值


不过读卡器这部分好使,我已经用函数建立出一个txt文件了,但是就是sd卡这里,我一直调不通。。


CH376DiskMount这个函数在sd卡上通过了,返回0x14,我用示波器观察sd的链接脚,信号线正常工作,但是调用CH376DiskCapacity,返回是5f7f7f7f,调用CH376DiskQuery则返回0x1f。


5f7f7f7f值是CH376DiskCapacity显示的容量,返回值为0x14.。。


从你的描述来看,你所有的操作都是正确的。 5f7f7f7f这个数据你是通过什么方式读到的?你把你这块的代码贴出来


底层部分: /ICC-AVR application builder : 2009-11-13 16:24:24 //Target : M8515 //Crystal: 16.000Mhz /*******************************************************************************/ /* Ä£ÄâÐźÅÃû Òý½Å·ÖÅä ¶ÔÓ¦CH376Òý½Å SCS PB0 SCS SCK PB1 SCK MOSI PB2 SDI MISO PB3 SDO ÆäËûÐźÅ:Èç¹ûʹÓÃÖжÏÒý½Å INT PB7 INT# //δʹÓà Ҳ䶨ÒåµÄÐźŠBZ PB4 BZ */ /*******************************************************************************/ #include"iom128v.h" #include"macros.h" #include"CH376INC.H" #include"AVRFUNCTION.H"

/***************************Ä£ÄâSPIµÄ¶Ë¿ÚºÍÒý½Å¶¨Òå***********************************/ #define SW_SPI_PORTx PORTB #define SW_SPI_DDRx DDRB #define SW_SPI_PINx PINB #define SW_SCS 0 #define SW_SCK 1 #define SW_MOSI 2 #define SW_MISO 3 /*************************Ä£ÄâSPIµÄ¶Ë¿ÚÉèÖúͲÙ×÷*******************************/ /*Òý½Å²Ù×÷¶¨Òå*/ //ƬѡÐźŲÙ×÷:SCS #define SW_SCS_SET (SW_SPI_PORTx|=1< #define SW_SCS_RESET (SW_SPI_PORTx&=(~(1< //ʱÖÓÐźŲÙ×÷:SCK #define SW_SCK_SET (SW_SPI_PORTx|=1< #define SW_SCK_RESET (SW_SPI_PORTx&=(~(1< //Êä³öÊý¾Ý:MOSI #define SW_MOSI_SET (SW_SPI_PORTx|=1< #define SW_MOSI_RESET (SW_SPI_PORTx&=(~(1< //¶ÁÈ¡Êý¾Ý:MISO #define SW_MISO_READ (SW_SPI_PINx&(1</*********************ÖжÏÒý½Å¶Ë¿ÚÉèÖúͶ¨Òå,²»Ê¹ÓÃÖжÏÔòʹÓÃSDO¼æ×öÖжÏÒý½Å************************/ //#define USE_INT_WIRE 1 #ifdef USE_INT_WIRE #define CH376_INT_PORTx PORTB #define CH376_INT_DDRx DDRB #define CH376_INT_PINx PINB #define CH376_INT_NUMx PINB3 #define CH376_INT_WIRE (CH376_INT_PINx&(1<#else //ʹÓÃCH376µÄSDO¼æ×öÖжÏÊä³ö<--->AVR:MISOÖжÏÊäÈë #ifndef CH376_SPI_SDO #define CH376_SPI_SDO SW_MISO_READ #endif #endif

//CH376¶Ë¿Ú³õʼ»¯:´Ë´¦Êµ¼ÊÉϾÍÊdzõʼ»¯Ä£ÄâSPIËùʹÓõÄ4¸ö¶Ë¿ÚºÍÖжÏÒý½Å(Èç¹ûʹÓÃÖжÏÒý½Å) //CH376Ö§³ÖSPIµÄģʽ0ºÍģʽ3. ĬÈÏΪ¸ßµçƽ,SPIģʽ3,Ò²¿ÉÒÔÓÃSPIģʽ0,µ«Ä£Äâ³ÌÐò¿ÉÄÜÐèÉÔ×öÐÞ¸Ä //Èç¹ûÊÇÓ²¼þSPI½Ó¿Ú,ÄÇô¿ÉʹÓÃmode3(CPOL=1&CPHA=1)»òmode0(CPOL=0&CPHA=0) //CH376ÔÚʱÖÓÉÏÉýÑزÉÑùÊäÈë,ϽµÑØÊä³ö,Êý¾ÝλÊǸßλÔÚÇ° void CH376_PORT_INIT( void ) { SW_SPI_PORTx|=((1< SW_SPI_DDRx|=((1< SW_SPI_DDRx&=~(1< #ifdef USE_INT_WIRE CH376_INT_PORTx|=(1< CH376_INT_DDRx&=~(1< #endif } /*****************************ÑÓʱns**************************************/ void mDelaynS(unsigned char i) { while(i--); } /*****************************ÑÓʱ1us**************************************/ void mDelayuS(unsigned char i) {//²ÉÓÃ16M¾§Õñ,ÑÓʱ1us while(i--) { NOP();NOP();NOP();NOP(); NOP();NOP(); //NOP();NOP(); //NOP();NOP();NOP();NOP();

} } /*****************************ÑÓʱMS**************************************/ void mDelaymS( unsigned int delay ) { unsigned int i, j, c; for ( i = delay; i != 0; i -- ) { for ( j = 50; j != 0; j -- ) { for ( c = 10; c != 0; c -- ) mDelayuS(1); } } }

//AVRͨ¹ýÄ£ÄâSPIʱÐòÏòCH376·¢ËÍÊý¾Ý void SpiOut_CH376(unsigned char DatOut) { unsigned char i; for ( i = 0; i < 8; i ++ ) { SW_SCK_RESET; if ( DatOut & 0x80 ) SW_MOSI_SET ; //AVR SDOÊä³öÊý¾Ý else SW_MOSI_RESET; DatOut <<= 1; /* Êý¾ÝλÊǸßλÔÚÇ° */ SW_SCK_SET ; /* CH376ÔÚʱÖÓÉÏÉýÑزÉÑùÊäÈë */ mDelaynS(1); /*ÑÓʱ1¸ö»úÆ÷ÖÜÆÚµÄʱ¼ä*/ } }

//AVRͨ¹ýÄ£ÄâSPIʱÐò´ÓCH376¶ÁÈ¡Êý¾Ý unsigned char SpiIn_CH376(void) { unsigned char i,RecvDat=0; for ( i = 0; i < 8; i ++ ) { SW_SCK_RESET ; /* CH376ÔÚʱÖÓϽµÑØÊä³ö */ RecvDat <<= 1; /* Êý¾ÝλÊǸßλÔÚÇ° */ mDelaynS(1); /*ÑÓʱ1¸ö»úÆ÷ÖÜÆÚµÄʱ¼ä,ÐèÒªµÈ´ýÊ&yacu


不知道为什么汉字是乱码。。。fat部分: #define EN_DISK_QUERY #ifdef EN_DISK_QUERY extern unsigned long memory; UINT8 CH376DiskCapacity( unsigned long *DiskCap ) /*PUINT32 ²éѯ´ÅÅÌÎïÀíÈÝÁ¿,ÉÈÇøÊý */ { UINT8 s; s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY ); printf("s=%x\r\n",s); xEndCH376Cmd( );

if ( s == USB_INT_SUCCESS ) { /* ²Î¿¼CH376INC.HÎļþÖÐCH376_CMD_DATA½á¹¹µÄDiskCapacity */ printf("yes memory pass,but cmd...\r\n"); xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); xReadCH376Data( ); /* ³¤¶È×ÜÊÇsizeof(CH376_CMD_DATA.DiskCapacity) */ printf(); *DiskCap = CH376Read32bitDat( ); /* CH376_CMD_DATA.DiskCapacity.mDiskSizeSec,´ÓCH376оƬ¶ÁÈ¡32λµÄÊý¾Ý²¢½áÊøÃüÁî */ printf("disk=%ld",*DiskCap); } else *DiskCap = 0; printf("memory s=%x",s); xEndCH376Cmd( ); return( s ); }

UINT8 CH376DiskQuery( PUINT32 DiskFre ) /* ²éѯ´ÅÅÌÊ£Óà¿Õ¼äÐÅÏ¢,ÉÈÇøÊý */ { UINT8 s; UINT8 c0, c1, c2, c3; s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY ); printf("query=%x",s); if ( s == USB_INT_SUCCESS ) { /* ²Î¿¼CH376INC.HÎļþÖÐCH376_CMD_DATA½á¹¹µÄDiskQuery */ printf("pass diskquery\r\n"); xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); xReadCH376Data( ); /* ³¤¶È×ÜÊÇsizeof(CH376_CMD_DATA.DiskQuery) */ xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mTotalSector */ xReadCH376Data( ); xReadCH376Data( ); xReadCH376Data( ); c0 = xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mFreeSector */ c1 = xReadCH376Data( ); c2 = xReadCH376Data( ); c3 = xReadCH376Data( ); printf("%x",c0); printf("%x",c1); printf("%x",c2); printf("%x\r\n",c3); *DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24; xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mDiskFat */ xEndCH376Cmd( ); } else *DiskFre = 0; return( s ); }

#endif


unsigned long memory; void main(void) { unsigned char s,i; unsigned char buffer1[512];//这里是为了测试你说的读块的函数设的缓冲区 init_devices(); CH376_PORT_INIT(); printf("test!"); mDelaymS(100);//µÈ´ýCH376¸´Î»½áÊø s=mInitCH376Host();/*Init CH376*/ printf("init=%x\r\n",s); printf("pass init\r\n");

while(1) { if ( CH376DiskMount( ) == USB_INT_SUCCESS ) { break; } printf("mount=%x\r\n",CH376DiskMount( )); // ³õʼ»¯´ÅÅ̲¢²âÊÔ´ÅÅÌÊÇ·ñ¾ÍÐ÷ mDelaymS(1000); } printf("ok\r\n");//测试时,mount一直查询,然后就通过了 i=CH376ReadBlock(buffer1); printf("readblock=%x\r\n",i);//在这里返回的是0x24

printf("res=%x\r\n",CH376DiskCapacity(memory));//容量。。。。问题1所在 printf("test1=%ld",memory); printf("res=%x\r\n",CH376DiskQuery(memory));// 剩余。。。。问题2所在 printf("test1=%ld",memory);

while(1);//在这里死循环是因为我想读出sd卡的容量就可以了 while(1) { //if(CH376DiskConnect( )== USB_INT_SUCCESS) //{ printf("pass connect\r\n"); mDelaymS( 200 ); // ÑÓʱ,¿ÉÑ¡²Ù×÷,ÓеÄUSB´æ´¢Æ÷ÐèÒª¼¸Ê®ºÁÃëµÄÑÓʱ for ( s = 0; s < 20; s ++ )// ×µÈ´ýʱ¼ä,10*50mS { mDelaymS( 100 ); if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; // ³õʼ»¯´ÅÅ̲¢²âÊÔ´ÅÅÌÊÇ·ñ¾ÍÐ÷ } ch376operCreate(123,456);//дÎļþÃû²¢´ò¿ªÎļþ 1.Îļþ´æÔÚдָÕëÌøµ½Î²²¿ 2.ûÓÐÎļþ»áн¨Îļþ ch376write(2009,11,23,7463);//ÔÚËù´ò¿ª»òн¨µÄÎļþÀïдÎļþ ch376write(2009,11,24,7456); strcpy(buf,"½ñÌìµÄADC\xd\xa");//½áÊøÓï s = CH376ByteWrite( buf, strlen( buf ), NULL ); /* ÒÔ×Ö½ÚΪµ¥Î»ÏòÎļþдÈëÊý¾Ý */ printf("bytewrite=%x\r\n",s); mDelaymS( 200 ); s = CH376FileClose( TRUE ); //¹Ø±ÕÎļþ,×Ô¶¯¼ÆËãÎļþ³¤¶È,ÒÔ×Ö½ÚΪµ¥Î»Ð´Îļþ,½¨ÒéÈóÌÐò¿â¹Ø±ÕÎļþÒÔ±ã×Ô¶¯¸üÐÂÎļþ³¤¶È printf("close=%x\r\n",s); while ( CH376DiskConnect( ) == USB_INT_SUCCESS ) // ¼ì²éUÅÌÊÇ·ñÁ¬½Ó,µÈ´ýUÅ̰γö { mDelaymS( 100 ); } while(1); //} } }


5f7f7f7f涉及到的函数有:xReadCH376Data:第一段;CH376DiskCapacity:第二段;调用在主函数main里面:第三段;


u盘,读卡器这种usb类的没有问题~唯独sd卡这里出问题,线路,信号线方向我特意注意了一下,没问题。


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