野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 19487|回复: 5

SD卡Polling模式单块读写出现FIFO上溢和下溢错误

[复制链接]
发表于 2014-5-28 20:45:01 | 显示全部楼层 |阅读模式
本帖最后由 daneiqi 于 2014-5-28 20:46 编辑

一、问题
    野火开发板上的SD卡测试程序包含擦除、单块读写、多块读写三个测试部分。涉及到数据传输的也就是单块读写函数、多块读写函数。开发板原配数据传输程序是用DMA方式,但我总想尝试一些使用Polling模式。
   因为SD卡测试程序的主要源文件*_sdio_sdcard.c来自于官方库,此文件开头也说可以使用Polling模式。但是,我尝试着这样去做,结果发现在读取block的时候,状态寄存器提示FIFO上溢出错误,而在写block的时候,提示FIFO下溢出错误。
    更确切的测试结果是:在数据控制寄存器DCTRL配置以后(DTEN使能),传输数据长度DLEN会加载到DCOUNT和FIFOCNT中,由于是单块写测试。所以,DCOUNT = 512(以字节为单位),FIFOCNT = 128(以字为单位);伴随着这两个寄存器的变化,状态寄存器STA变为0x45000。 但是,只要我往FIFO中写入一个字,DCOUNT = 512 - 4,FIFOCNT = 0,更奇怪的是STA = 0x10,也就是FIFO下溢出。可是32个字的FIFO,我才只写入一个字呀。
    为啥,请赐教。

二、附录
附:SD_WriteBlock 相关测试代码

#if defined (SD_POLLING_MODE) //普通模式
  while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
  {
    if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
    {
      if ((512 - bytestransferred) < 32)
      {
        restwords = ((512 - bytestransferred) % 4 == 0) ? ((512 - bytestransferred) / 4) : (( 512 -  bytestransferred) / 4 + 1);
        for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
        {
          SDIO_WriteData(*tempbuff);
        }
      }
      else
      {
        for (count = 0; count < 8; count++)
        {
          SDIO_WriteData(*(tempbuff + count));
        }
        tempbuff += 8;
        bytestransferred += 8*4;
      }
    }
  }
  if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
    errorstatus = SD_DATA_TIMEOUT;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
    errorstatus = SD_DATA_CRC_FAIL;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
    errorstatus = SD_TX_UNDERRUN;
    return(errorstatus);
  }
  else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
  {
    SDIO_ClearFlag(SDIO_FLAG_STBITERR);
    errorstatus = SD_START_BIT_ERR;
    return(errorstatus);
  }
#elif defined (SD_DMA_MODE) //dma模式
  SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);  //数据传输结束中断
  SD_DMA_TxConfig((uint32_t *)writebuff, BlockSize); //配置dma,跟rx类似
  SDIO_DMACmd(ENABLE);  // 使能sdio的dma请求
#endif

三、配置模式
1、SDIO模式
2、时钟400KHz(有人说时钟太快容易出现溢出问题,关键是我的速度并不高)
3、轮训模式数据传输
回复

使用道具 举报

发表于 2014-5-29 23:29:02 | 显示全部楼层
用polling方式的话找一下ST官方5.01版本的SDIO程序,改掉了比较多的软件bug
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-31 11:20:51 | 显示全部楼层
  的确,我发现ST官方库3.5版本的外设驱动程序写的相当完美,但是它配备的应用example4.5版本的确有一些bug。比如说SD上电初始化程序并没有完全按照SD卡协议规定的流程去走,程序并没有那么完美。
  你给我提供的这条建议不错,我可以尝试一下,多谢了。
回复 支持 反对

使用道具 举报

发表于 2014-7-13 23:05:04 | 显示全部楼层
我测试过,4位模式,读写速度调成12M就行了~~~
回复 支持 反对

使用道具 举报

发表于 2014-12-9 10:58:01 | 显示全部楼层
楼主,现在这个问题有解决吗?望赐教
回复 支持 反对

使用道具 举报

发表于 2014-12-9 10:58:22 | 显示全部楼层
小新星q 发表于 2014-7-13 23:05
我测试过,4位模式,读写速度调成12M就行了~~~

调成12M依然是有问题..
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-9-22 14:36 , Processed in 0.052948 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表