打印

STM32F207芯片下的SD卡读取怎么不成功?

[复制链接]
7943|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lorelia14|  楼主 | 2012-3-7 16:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用STM32F207开发SD卡读取操作,目前用的官方例程STM32F2xx_StdPeriph_Lib_V1.0.0调试SD卡的数据读取操作,有以下问题:
1、使用4bit宽度进行数据读取时,采用DMA方式只能接收到8个字节的正确数据,其它数据全不对。换成查询方式时,发现SDIO->STA报数据CRC校验错,可目前配置的SDIOCLK为12MHz,理论上不应该出现因为时钟速率过快导致读取错误。

2、使用1bit宽度进行数据读取时,无论采用DMA还是查询方式,数据接收正确,但无**常结束,检查下来是总也进不了中断处理程序SDIO_IRQHandler()。

网上看各位大虾的帖子,似乎没有人遇到这个情况,很头大,希望大家指点一二。

另外还想知道,用207来访问SD卡,采用120MHz的工作频率,能够支持的SD卡最高读取速率可以到多少呢?目前要做的方案是希望能够实现15MBytes/s的读取速度,不知道有没有人实现过?
沙发
adce| | 2012-3-7 20:52 | 只看该作者
我现在是F1 F2全成功....F4读成功无法写....
速度是F1不到1M   F2 是 1.2M   F4和F2差不多....

使用特权

评论回复
板凳
lorelia14|  楼主 | 2012-3-8 08:47 | 只看该作者
下面将我引用的官方代码列出,请楼上的指点一二吧。
主函数:
int main(void)
{
  RCC_ClocksTypeDef RCC_Clocks;

  /*!< At this stage the microcontroller clock setting is already configured,
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f2xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f2xx.c file
     */  
  SystemInit();
       
  /* SysTick end of count event each 10ms */
  RCC_GetClocksFreq(&RCC_Clocks);
//  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);

  NVIC_Configuration();// NVIC configuration
  GPIO_Init_Configuration();

  /* Turn on LEDs available on STM322xG-EVAL **********************************/
  STM_EVAL_LEDOn(LED2);
  STM_EVAL_LEDOn(LED3);
  STM_EVAL_LEDOn(LED4);

  /* Add your application code here
     */
  SDCard_Control();

  /* Infinite loop */
  while (1)
  {
  }
}

其中SDCard_Control()是我的SD卡操作程序:
void SDCard_Control(void)
{
  if(SD_Detect()== SD_PRESENT)
  {
    /*------------------------------ SD Init ---------------------------------- */
    if((Status = SD_Init()) != SD_OK)
      STM_EVAL_LEDOn(LED4);
        
    while((Status == SD_OK) && (SDCardOperation != SD_OPERATION_END))
    {
      switch(SDCardOperation)
      {
        /*-------------------------- SD Erase Test ---------------------------- */
        case (SD_OPERATION_ERASE):
        {
          SD_EraseTest();
          SDCardOperation = SD_OPERATION_BLOCK;
          break;
        }
        /*-------------------------- SD Single Block Read Test --------------------- */
        case (SD_OPERATION_READ_BLOCK):
        {
          SD_SingleBlockReadTest();
          SDCardOperation = SD_OPERATION_END;
          break;
        }      
        case (SD_OPERATION_END):
        {
          SD_SingleBlockReadTest();
          break;
        }      
      }
    }
  }
}
有关SD卡读取测试代码在SD_SingleBlockReadTest()中:
void SD_SingleBlockReadTest(void)
{
  if (Status == SD_OK)
  {
    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);

    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();

    /* Wait until end of DMA transfer */
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }
}

使用特权

评论回复
地板
lorelia14|  楼主 | 2012-3-8 09:05 | 只看该作者
代码里面用到的函数都是来自于官方提供的源代码,其中存疑的有:
1、SDIO中断进不去:在中断服务程序SDIO_IRQHandler中设断点,始终无法进入,因此在1bit宽度读取时,无**常结束读取操作。
    代码中对SDIO的中断配置在NVIC_Configuration()中调用到:
void NVIC_SDIO_Configuration(void)  
{  
  NVIC_InitTypeDef NVIC_InitStructure;  

  /* Configure the NVIC Preemption Priority Bits*/   
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  // SDIO Interrupt ENABLE
  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
  块读取操作的代码:
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{
  SD_Error errorstatus = SD_OK;
  TransferError = SD_OK;
  TransferEnd = 0;
  StopCondition = 1;
       
  SDIO->DCTRL = 0x0;

  if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
  {
    BlockSize = 512;
    ReadAddr /= 512;
  }

  /*!< Set Block Size for Card */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);

  if (SD_OK != errorstatus)
  {
    return(errorstatus);
  }
   
  SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
  SDIO_DataInitStructure.SDIO_DataLength = NumberOfBlocks * BlockSize;
  SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;
  SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToSDIO;
  SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
  SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
  SDIO_DataConfig(&SDIO_DataInitStructure);

  /*!< Send CMD18 READ_MULT_BLOCK with argument data address */
  SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)ReadAddr;
  SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_READ_MULT_BLOCK;
  SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  SDIO_SendCommand(&SDIO_CmdInitStructure);

  errorstatus = CmdResp1Error(SD_CMD_READ_MULT_BLOCK);

  if (errorstatus != SD_OK)
  {
    return(errorstatus);
  }

//  SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);
        SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);

  SDIO_DMACmd(ENABLE);
  SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, (NumberOfBlocks * BlockSize));

  return(errorstatus);
}
检查过SDIO->STA的状态为0x00000500,对应的标志是有的,可为啥不能进入中断呢?难道是没有打开中断?207中没有找到有关的说明嘛,请高手指点。

使用特权

评论回复
5
IJK| | 2012-3-8 10:23 | 只看该作者
ST的官方例程对SD卡的兼容性不会太好,LZ碰到的可能就是兼容性问题,可以换SD卡试试

使用特权

评论回复
6
lorelia14|  楼主 | 2012-3-8 10:26 | 只看该作者
找到原因了,原来是因为我用ST-LINK作为调试工具,在IAR下仿真时,程序下载总是失败,因此将原先下载到FLASH的程序改为下载到RAM中,结果没有将NVIC_VectTab声明到RAM中,所以中断无法产生。
参考了其它**,现在1bit和4bit的块读取已经可以实现,要测试一下最快可以实现的读取时间,不知道SD卡可以支持的最高读取速度是多少?哪个卡最快?

使用特权

评论回复
7
apple| | 2012-3-15 12:58 | 只看该作者
一般速度不会太快, 我们用207  IO口模拟SD总线访问, 最快读5M/秒

使用特权

评论回复
8
ilovezeno| | 2012-3-15 20:37 | 只看该作者
前几天看日本人的博客,stm32f4 使用sdio,超频优化后的结果是25427KB/s,不超频应该也有差不多一半的速度。。。。这样计算下来,stm32f2 应该也可以正常过10M/s的速度。
楼上各位好好检讨下自己的代码吧。。。。:lol

使用特权

评论回复
9
even777| | 2012-3-18 14:05 | 只看该作者
不知道楼主的SD卡最后的读写速度分别是多少,我现在也在做F207_SD卡这块,我需要SD卡的写入速度4MB/S以上,不知道楼主的做到了多少,望楼主回复一下,谢谢,我的QQ是252002415。再次感谢!

使用特权

评论回复
10
lorelia14|  楼主 | 2012-3-22 13:01 | 只看该作者
我只试了读SD卡,最快做到5.5MB/s,因为项目要求数据流至少要在15MB/s的级别,差的太远,后续工作就没有再接着尝试。

使用特权

评论回复
11
na239152605| | 2012-4-11 22:34 | 只看该作者
学习了!!!正在学SD卡!惆怅阶段!!!

使用特权

评论回复
12
yinyangdianzi| | 2012-4-12 10:03 | 只看该作者
这个官方有升级的例程。。。STM32F1XX升级STM32F2XX
www.st.com

使用特权

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

本版积分规则

0

主题

27

帖子

0

粉丝