亿加合和智能车制作

标题: SD卡多扇区读写与PC读取SD卡扇区数据 [打印本页]

作者: vic_hong    时间: 2012-4-11 13:03
标题: SD卡多扇区读写与PC读取SD卡扇区数据
本帖最后由 vic_hong 于 2012-4-11 13:07 编辑

        有人问我关于PC机读SD卡扇区的资料,我就顺便发个帖子吧。
        我觉得文件系统始终是在SD卡基本读写操作上再加上一层包装,速度绝对不会比直接读写扇区快的,但是慢多少我也没测过。
        对于单片机读写SD卡已经有很多资料了,也比较简单。不过SD卡读写也是有窍门的。现有的大部分SD卡读写函数,都是单扇区读写的。而读写的主要时间大部分消耗在读写命令上,如果调用循环读写,会比较慢。实际上SD卡有一个多扇区读写命令,可以提高读写效率。可以参考以下网址:
       http://bbs.eeworld.com.cn/thread-105903-1-1.html

        回到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

作者: 洋葱圈    时间: 2012-4-11 13:35
好贴,顶了。
作者: z1yxyq2008    时间: 2012-4-28 18:16

作者: 木疙瘩    时间: 2012-10-20 21:47
不得不说,这是个好东西
作者: 庞七七    时间: 2012-11-20 22:26
问一下,写多块会比写单块速度快吗?我们现在是写单块,速度在1.5ms这样一个扇区,想把时间缩短至毫秒级别,有办法吗?
作者: 庞七七    时间: 2012-11-20 22:26
特别紧急的事情,希望帮帮忙提些意见。。目前陷入瓶颈中了
作者: vic_hong    时间: 2012-11-20 23:50
庞七七 发表于 2012-11-20 22:26
问一下,写多块会比写单块速度快吗?我们现在是写单块,速度在1.5ms这样一个扇区,想把时间缩短至毫秒级别, ...

以前测过XS128写普通的TF卡单块也就是那个速度。多块是会快的,因为初始化占用的时间比较长,多块可以避免一些初始化。由于XS128RAM的原因我只试过写9块,有没有1ms以内我没测过,但的确比单独写9块来得快。你用电脑端的SD卡速度测试软件试试就知道了,写的块越大速度越快。

作者: 庞七七    时间: 2012-11-21 08:58
vic_hong 发表于 2012-11-20 23:50
以前测过XS128写普通的TF卡单块也就是那个速度。多块是会快的,因为初始化占用的时间比较长,多块可以避免 ...

我们每次程序周期只需要写4,5个数,所以写多块也很浪费了,目前我们块大小为4,速度还是没快多少。
作者: vic_hong    时间: 2012-11-21 12:32
庞七七 发表于 2012-11-21 08:58
我们每次程序周期只需要写4,5个数,所以写多块也很浪费了,目前我们块大小为4,速度还是没快多少。

你的块大小是4,然后竟然写了1.5ms?我写的单块的512byte的。多块的意思是在程序开始时初始化多块的设置,然后写一个扇区,写一个扇区。。最后设置结束就行了。而单块的意思是初始化,写数据,结束。这中间必然浪费很多时间。可以在RAM上把数存起来,存够512byte后一次性写入,用多块的方式写,应该少于1.5ms。

作者: 心静0189    时间: 2012-12-11 10:15
多扇区写入,是用的 25号命令吗?
作者: vic_hong    时间: 2012-12-11 22:11
心静0189 发表于 2012-12-11 10:15
多扇区写入,是用的 25号命令吗?

是的。参考网址那里有例程。

作者: 心静0189    时间: 2012-12-12 21:53
vic_hong 发表于 2012-12-11 22:11
是的。参考网址那里有例程。

哪个网址,给我具体一下吧。非常感谢!

作者: 心静0189    时间: 2012-12-13 10:29
谢谢啊。我找到了。我再好好看看。
作者: 文艺小青年    时间: 2014-11-23 21:25
能够分享一个好的上位机吗





欢迎光临 亿加合和智能车制作 (http://111.231.132.190/) Powered by Discuz! X3.2