OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16278|回复: 17

stm32 sdio官方例程修正

[复制链接]

3

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2011-12-23
在线时间
5 小时
发表于 2012-3-12 14:38:31 | 显示全部楼层 |阅读模式

这几天研究stm32操作sd卡,使用的是ST给的例程stm32_eval_sdio_sd.c,版本V4.5.0,遇到了如下问题,现一一解决。

1:SD_WaitReadOperation()或者SD_WaitWriteOperation()函数死循环

原因:数据传输错误导致传输中断,无法满足退出等待的判断条件。

代码分析:

SD_Error SD_WaitReadOperation(void)
{
  SD_Error errorstatus = SD_OK;
 
  while ((SD_DMAEndOfTransferStatus() == RESET) && (TransferEnd == 0) && (TransferError == SD_OK))
  {}

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

  return(errorstatus);
}

代码中用了while()是导致死循环的原因。TransferEnd ,TransferError 这两个参数是在中断中修改的, SD_DMAEndOfTransferStatus() 的结束条件是DMA传输结束。

看中断例程:

SD_Error SD_ProcessIRQSrc(void)
{
  if (StopCondition == 1)
  {
    SDIO->ARG = 0x0;
    SDIO->CMD = 0x44C;
    TransferError = CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
  }
  else
  {
    TransferError = SD_OK;
  }
  SDIO_ClearITPendingBit(SDIO_IT_DATAEND);
  SDIO_ITConfig(SDIO_IT_DATAEND, DISABLE);
  TransferEnd = 1;
  return(TransferError);
}

中断配置为数据传输结束中断SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);

数据传输出错导致传输中断的情况下,SD_DMAEndOfTransferStatus的判断为false,TransferEnd 和TransferError 的状态也不会改变,导致while循环无法退出。

解决:

中断配置为SDIO_ITConfig(SDIO_IT_RXOVERR|SDIO_IT_DTIMEOUT|SDIO_IT_DCRCFAIL|SDIO_IT_DATAEND, ENABLE);

中断例程修改:

SD_Error SD_ProcessIRQSrc(void)
{
 if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
 {
  SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
  TransferError = SD_DATA_TIMEOUT;
 }
 else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
 {
  SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
  TransferError = SD_DATA_CRC_FAIL;
 }
 else if (SDIO_GetFlagStatus(SDIO_FLAG_RXOVERR) != RESET)
 {
  SDIO_ClearFlag(SDIO_FLAG_RXOVERR);
  TransferError = SD_RX_OVERRUN;
 }
 else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
 {
  SDIO_ClearFlag(SDIO_FLAG_STBITERR);
  TransferError = SD_START_BIT_ERR;
 }
 else
 {
  if (StopCondition == 1)
  {
  SDIO->ARG = 0x0;
  SDIO->CMD = 0x44C;
  TransferError = CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
  }
  else
  {
  TransferError = SD_OK;
  }
 }
 
  SDIO_ITConfig(SDIO_IT_RXOVERR|SDIO_IT_DTIMEOUT|SDIO_IT_DCRCFAIL|SDIO_IT_DATAEND, DISABLE);
  TransferEnd = 1;
  return(TransferError);
}

这么做的作用是发生错误时也会进入中断,即使dma没有结束,也能退出while循环。

 

2:sd_init()过程失败

可能性1:按照SD规范,初始化之前需要有74个或更多个clock让sd卡同步,例程中把clock开起来后直接发送cmd0,没有同步clock,所以先修改SD_PowerON函数内SDIO_ClockCmd(ENABLE);调用之后增加200us延时。

可能性2:发生SDIO_FLAG_DCRCFAIL错误。

修改SDIO_TRANSFER_CLK_DIV 来修改数据传输速率。

按照ST例程的注释,数据传输速率不能超过25M,但是原先配置SDIO_TRANSFER_CLK_DIV=0,按照72M主频计算的话传输速度达到72/2=36M,不出错就怪了。

我现在配置SDIO_TRANSFER_CLK_DIV=2后正常。

可能性3:固件库使用不正确。使用V4.5的例程,固件库需要用V3.5.0的,试过3.2的固件库会失败。

 

3:SD_DMAEndOfTransferStatus函数内没有清标志位,按照datasheet,标志位是由手动清除的。

4:SD_ReadBlock()发生SDIO_FLAG_DCRCFAIL错误。

一开始是实践发现,先执行一下SD_ReadMultiBlocks函数,以后再执行SD_ReadBlock就正常了。很奇怪的现象吧。后来查阅了一些资料,发现SD卡的block大小并不是固定的,可以配置为512,1024等,于是怀疑是block大小配置不正确导致。检查发现SD_ReadBlock操作之前没有设置sd卡block大小,也就是cmd16,加入这个代码就像行了

  /*!< 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);
  }

其实这个操作并不是每次读操作都要执行的,如果中途不改变block大小,只要初始化的时候设置一次就可以了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-3-12 15:25:02 | 显示全部楼层
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2012-5-4
在线时间
0 小时
发表于 2012-5-28 15:14:38 | 显示全部楼层
回复【楼主位】quqw:
---------------------------------
请教楼主官网SD例程在哪可以下载,谢谢?
回复 支持 反对

使用道具 举报

72

主题

251

帖子

0

精华

高级会员

Rank: 4

积分
597
金钱
597
注册时间
2012-3-29
在线时间
7 小时
发表于 2012-5-29 09:56:21 | 显示全部楼层
给个改好的例程就好了。
回复 支持 反对

使用道具 举报

8

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2012-5-22
在线时间
0 小时
发表于 2012-5-29 10:17:53 | 显示全部楼层
顶一个,希望能够提供新的SD例子下载地址,谢谢
回复 支持 反对

使用道具 举报

12

主题

216

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2011-4-7
在线时间
3 小时
发表于 2012-6-1 00:14:55 | 显示全部楼层
在ourdev.cn找到一个

STM32基于3.5固件库 SDIO+4bit模式驱动的FatFS(0.07e).zip

1.16 MB, 下载次数: 2847

回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2012-7-21
在线时间
0 小时
发表于 2012-8-4 11:20:00 | 显示全部楼层
顶一个
回复 支持 反对

使用道具 举报

7

主题

33

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
231
金钱
231
注册时间
2012-7-11
在线时间
0 小时
发表于 2012-8-6 08:38:10 | 显示全部楼层
原子的板子 好像不能用SDIO模式吧。。。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-6 09:17:25 | 显示全部楼层
回复【8楼】liash:
---------------------------------
是的
我的没有SDIO.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2012-12-20
在线时间
0 小时
发表于 2012-12-21 13:00:37 | 显示全部楼层
原代码能上传分享一下吗?!
谢谢
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2012-5-19
在线时间
0 小时
发表于 2013-7-19 15:54:07 | 显示全部楼层
12321321321312321321321321312321
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-19 19:46:45 | 显示全部楼层
回复【10楼】longline:
---------------------------------
论坛搜索.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-7-25
在线时间
0 小时
发表于 2013-7-30 07:54:51 | 显示全部楼层
先顶一下再看内容
回复 支持 反对

使用道具 举报

15

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-10-13
在线时间
0 小时
发表于 2014-12-3 21:48:28 | 显示全部楼层
回复【6楼】lixupeng:
---------------------------------
哥,你这个测试通过了!?  为什么我测试没有通过!?  疯了、
回复 支持 反对

使用道具 举报

12

主题

216

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2011-4-7
在线时间
3 小时
发表于 2014-12-5 15:15:02 | 显示全部楼层
 回复【14楼】 MichealLee :
---------------------------------



我没试过。。
回复 支持 反对

使用道具 举报

54

主题

194

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
430
金钱
430
注册时间
2013-11-2
在线时间
0 小时
发表于 2015-1-6 13:14:37 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
原子哥,你的战舰不能使用SDIO吗?我看引脚都引出来了,只要把跳线帽换一下就行了啊,正在调SDIO,千万不要坑我
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-6 23:12:06 | 显示全部楼层
回复【16楼】周小样:
---------------------------------
可以啊
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

134

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1793
金钱
1793
注册时间
2015-3-13
在线时间
273 小时
发表于 2020-11-24 19:38:26 | 显示全部楼层
block设置512,仍然发生SDIO_FLAG_DCRCFAIL错误,无法解决
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 20:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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