打印
[应用相关]

SD卡连续读写操作

[复制链接]
11170|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fangui|  楼主 | 2009-1-6 18:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
香主,问个问题:
    我用你们的开发板STM3210EEVAL跑Mass_Storage程序,刚开始跑如下的程序
int main()
{
#ifdef DEBUG
  debug();
#endif

  Set_System();
  Set_USBClock();
  Led_Config();
  USB_Interrupts_Config();
  USB_Init();
  while (bDeviceState != CONFIGURED); 
  while (1)
  {
  }
 }
插上USB后用PC对128M的SD卡用fat32格式化,然后跑下面的程序
int main()
{
u32 buff[128];
int i;
#ifdef DEBUG
  debug();
#endif

  Set_System();
  Set_USBClock();
  Led_Config();
  USB_Interrupts_Config();
  USB_Init();
  while (bDeviceState != CONFIGURED); 
    for(i=0;i<246780;i++)
        SD_ReadBlock(i*512,buff,512);
  while (1)
  {
  }
 }
再插上USB接口,这时就发现PC机找不到SD卡了,PC一直处于忙状态,我的疑问是:
    对SD卡连续读写操作会破坏FAT32的数据么?或者还是有别的原因呢?请楼主帮我分析下。
沙发
香水城| | 2009-1-6 21:39 | 只看该作者

我很难判断你这种非正规操作的后果和这种后果的确切原因

USB_Init()之后,STM32的USB模块将尝试与PC联接,这个时候应该给CPU留出足够的时间,让它在规定的时间内与PC完成枚举过程,但你却在这个时候用其它操作(或使用用更高优先级的中断)占用掉所有CPU的时间,抢占了USB需要的所有资源,这样导致的后果是——不可预知。

如果你没有对USB和这个例程有深入的了解,我劝你不要这样操作。

使用特权

评论回复
板凳
fangui|  楼主 | 2009-1-6 21:53 | 只看该作者

加延时之后呢?

那您的意思是如果我 while (bDeviceState != CONFIGURED); 之后加很长的延时是不是问题就可以解决呢?或者还是需要判断一些某些标志位呢?

使用特权

评论回复
地板
香水城| | 2009-1-6 22:07 | 只看该作者

不好意思,我无法判断这种后果的确切原因

正如我前面说的,我不能确切地知道真正的原因,因此我也没有真正的合适的解决办法。

但是你可以尝试在等到(bDeviceState == CONFIGURED)之后,再进行这种耗时的操作,也许情况会有所改善。当然前提是你的操作不能破坏PC对SD卡的操作,要知道USB枚举完成之后,PC仍会对USB设备进行操作,具体什么操作除了微软的人,没有人说得清楚。

使用特权

评论回复
5
香水城| | 2009-1-6 22:12 | 只看该作者

好的做法是:不要在一个循环中连续地读SD卡

这不符合真正的实际操作,实际应用中,一定是读出几个扇区后,要处理读出的数据,进行各种运算,然后再继续读出一些扇区,再进行运算或传送到其它通信接口,如此循环往复。

使用特权

评论回复
6
mcuisp| | 2009-1-6 22:20 | 只看该作者

呵呵,不能在中断和主程序里面同时读卡的。

实际上,这个例子里面你完全不能在USB来中断后还有SD卡操作,否则肯定完蛋。

使用特权

评论回复
7
香水城| | 2009-1-6 22:24 | 只看该作者

我没有看过这个例程,如果例程中果真是在USB中断中操作SD...

如果例程中果真是在USB中断中操作SD,那么你这样操作肯定有问题,我相信例程中的SD卡操作函数肯定不是可重入的。

谢谢mcuisp的提醒。

使用特权

评论回复
8
fangui|  楼主 | 2009-1-6 23:42 | 只看该作者

usb是有中断

usb是有中断的,那这样的话,在主程序里面即使是不连续读,读单个block也是有问题的咯,这么说,这个历程只能作为u盘用了,我现在是想把它改成fat32,单片机和PC机可同时访问SD卡,解决和PC交互数据的问题,香主有什么好主意么?或者ST公司有没有fat32的历程呢?

使用特权

评论回复
9
香水城| | 2009-1-7 07:55 | 只看该作者

要使用这个例程实现单片机和PC机可同时访问SD卡,需增加互

楼主的问题是函数的重入问题,所以必须解决防止函数的重入,即增加互斥功能。

因此,这个问题根本不是FAT32的问题。

使用特权

评论回复
10
fangui|  楼主 | 2009-1-8 11:44 | 只看该作者

还有个问题

多谢香主给穿了条裤子,我把程序改了一下,是这样操作的:

void SDInit()
{
    SD_Init();
    SD_GetCardInfo(&SDCardInfo);
    SD_SelectDeselect((u32) (SDCardInfo.RCA << 16));
    SD_EnableWideBusOperation(SDIO_BusWide_4b);
    SD_SetDeviceMode(SD_DMA_MODE);

}
void Fat32Test()
{
    int i,j;
    char txt[30];
    u32 buff[128];    

    signed short temp;
    RCC_Config();
    SDInit();
    for(i=0;i<128;i++)
        buff=0x55555555;
    //SD_WriteMultiBlocks(0x2602200,buff,512,20);

    SD_Erase(0x00,246780*512);
    for(i=50;i<100;i++)
    {
    
        //SD_Erase(i*512,(i+1)*512);
        SD_WriteBlock(i*512,buff,512);
        Delayms(100);
    }    
}

int main(void)
{

#ifdef DEBUG
    debug();
#endif
  Fat32Test();
  while (1)
  {


  }
}
发现还是不能对SD卡连续读写操作,具体表现为
只有0x000256这个block被写了0x55555555其他的都没有被操作,这是怎么回事,是不是SD卡的库函数有bug呢?还是SD卡不支持连续操作呢?或者需要读某些SD卡寄存器呢?

使用特权

评论回复
11
alien2006| | 2009-1-8 12:31 | 只看该作者

估计楼主跟我遇到的问题类似啊

我刚才试了你的程序,4BIT方式下莫名其妙的,有得块写了有的块没写上,不过删除都是正常的,我后来把SD_EnableWideBusOperation(SDIO_BusWide_4b);
改成SD_EnableWideBusOperation(SDIO_BusWide_1b);就正常了!
    你试试看!另外你在看看4BIT方式下读是否正确呢?
我之前的问题https://bbs.21ic.com/club/bbs/bbsView.asp?boardid=49,我是试验了4BIT方式读取就有问题,正好你也在研究SDIO,帮我也试试看

使用特权

评论回复
12
fangui|  楼主 | 2009-1-8 12:48 | 只看该作者

好的

使用特权

评论回复
13
fangui|  楼主 | 2009-1-8 12:53 | 只看该作者

我的改了后也还是写不了

使用特权

评论回复
14
香水城| | 2009-1-8 12:57 | 只看该作者

如果你使用的函数来自STM32固件库例程,这只是一个Demo

请楼上各位最好能打开对应的函数,分析一下它的操作过程,我不敢保证它在所有情况下都是正确的,因为这个例程只是用来演示STM32的SDIO模块能够操作SD卡,例程的目的不是为了提供一个使用的SD函数库。


另外,我简单地看了一下这个函数:SD_WriteMultiBlocks(),它的第2个参数writebuff的长度必须是第3个参数(BlockSize)与第4个参数(NumberOfBlocks)的乘积。

好像块写操作开始后,SD_WriteBlock()函数即返回,函数返回时编程才刚刚开始,还没有结束,你应该使用其它命令保证编程结束后,才能开始下一个块的编程操作,仅仅Delayms(100)是不够的。

使用特权

评论回复
15
alien2006| | 2009-1-8 13:30 | 只看该作者

改成1BIT还不行的话,你试试把SD卡的时钟降低看看

sdcard.c中把
#define SDIO_TRANSFER_CLK_DIV              ((u8)0x1) 
改大些,改成6以上看看,我之前试过1BIT 方式无论读还是写都是很OK的,我只是4BIT 才不正常

使用特权

评论回复
16
fangui|  楼主 | 2009-1-8 13:40 | 只看该作者

我改成((u8)0x4)也不正常

我改成((u8)0x4)也不正常,试试你的6看看

使用特权

评论回复
17
alien2006| | 2009-1-8 13:45 | 只看该作者

另外可以先不用DMA来试验

改成Status=SD_SetDeviceMode(SD_POLLING_MODE);
先试验,这样程序结构比较清晰,你可以一步步调试,轮询模式下是它要等待数据都处理完了才返回的,另外你
Status = SD_WriteBlock(i*512, buff, 512);
加一个Status来调试,看看返回的错误代码是多少
之前我就在关注一楼的内容,当时我也正在调试SDIO,当时我就怀疑不是USB的问题,而是SDIO读写的问题导致的

使用特权

评论回复
18
alien2006| | 2009-1-8 13:55 | 只看该作者

刚刚又想起来

你的SD卡电路是怎么样的?按照SD卡的规范,除了CLK外其他的脚都必须上拉10K~100K的电阻

使用特权

评论回复
19
fangui|  楼主 | 2009-1-8 14:30 | 只看该作者

都有上拉

都有上拉的,我的问题主要是读和擦除都正常,但是现在写就有问题,死机了,SD_WriteBlock这个函数里面有一写while(),不知道是不是这些引起的,我再好好研究它的库看看

使用特权

评论回复
20
fangui|  楼主 | 2009-1-8 14:49 | 只看该作者

问题好像是它的这个DMA不好用

问题好像是它的这个DMA不好用,改成SD_POLLING_MODE就可以了,alien2006你的QQ是多少啊,我可以加你么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

87

帖子

0

粉丝