本帖最后由 vic_hong 于 2012-4-11 13:07 编辑
有人问我关于PC机读SD卡扇区的资料,我就顺便发个帖子吧。 我觉得文件系统始终是在SD卡基本读写操作上再加上一层包装,速度绝对不会比直接读写扇区快的,但是慢多少我也没测过。 对于单片机读写SD卡已经有很多资料了,也比较简单。不过SD卡读写也是有窍门的。现有的大部分SD卡读写函数,都是单扇区读写的。而读写的主要时间大部分消耗在读写命令上,如果调用循环读写,会比较慢。实际上SD卡有一个多扇区读写命令,可以提高读写效率。可以参考以下网址:
回到PC读SD卡扇区的问题。其实网上资料也很多,也比较简单。通过 WriteSectors实现扇区写入,ReadSectors实现扇区读取。这里使用Visual C++6.0。 BOOL WriteSectors(BYTE bDrive, unsigned long dwStartSector, unsigned long wSectors, LPBYTE lpSectBuff) 第一个参数bDrive是硬盘号。假如你的电脑只有一个硬盘(注意与分区不一样,一个硬盘有多个分区),那么你的第一个移动硬盘号就是1。 稍微调试一下就知道了。 第二个参数dwStartSector是起始扇区号 第三个参数wSectors是读取的扇区数 第四个参数lpSectBuff是数据存储指针。比如 BYTE *bBuf=new BYTE[1000]; 第四个参数可以放bBuf,需要注意的是分配的空间大小,至少应该是 wSectors*512个byte。 BOOL ReadSectors(BYTE bDrive, unsigned long dwStartSector, unsigned long wSectors, LPBYTE lpSectBuff) 这是读取函数,参数与WriteSectors是一样的。
还需要注意的是sd卡要以移动硬盘方式接入PC,此方法不适用于笔记本电脑上自带读卡器。还有PC机上也尽量多扇区读写,就是wSectors尽量大。尽量少用循环读取,你可以看到很明显的差距。 下面是两个函数的具体实现:
BOOL WriteSectors(BYTE bDrive, unsigned long dwStartSector, unsigned long wSectors, LPBYTE lpSectBuff) { // 对磁盘扇区数据的写入 if(bDrive==0)return 0;//还是保护一下好。。写到自己硬盘上就。。。 char devName[] = "\\\\.\\PHYSICALDRIVE2";//硬盘号,注意和分区不一样 devName[strlen(devName)-1]=bDrive+'0'; HANDLE hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDev == INVALID_HANDLE_VALUE) return 0; SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN); DWORD dwCB; BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL); CloseHandle(hDev); return bRet; }
BOOL ReadSectors(BYTE bDrive, unsigned long dwStartSector, unsigned long wSectors, LPBYTE lpSectBuff){ // 对磁盘扇区数据的读取 if (bDrive == 0) return 0; char devName[] = "\\\\.\\PHYSICALDRIVE2"; devName[strlen(devName)-1]=bDrive+'0'; HANDLE hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDev == INVALID_HANDLE_VALUE) return 0; long pointer; long phigh; pointer = dwStartSector; pointer = pointer<<9; phigh = pointer>>32; SetFilePointer(hDev,(unsigned long)pointer,&phigh,FILE_BEGIN); //SetFilePointer(hDev, 512 * dwStartSector, ((unsigned long)512 * dwStartSector)>>32, FILE_BEGIN); DWORD dwCB; BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL); CloseHandle(hDev); return bRet; } 2012-4-11 by vizone |