OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...

查看: 8684|回复: 34

SD卡SPI DMA模式FatFs读写,速度超1MB/s

[复制链接]

  离线 

3

主题

326

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1558
金钱
1558
注册时间
2014-12-19
在线时间
517 小时
发表于 2015-10-10 13:58:23 | 显示全部楼层 |阅读模式
正点原子公众号

采用SPI DMA方式读写SD卡,适用于STM32F4。FatFs版本为最新的R0.11a。
一次读写512、1024、2048或4096字节,连续读写10s,然后计算读写速度。
测试的是一张8G的三星TF卡,以下是从串口获取的读写速度情况。
start reading ARTOGARD.WAV
fr: 0 num: 19522 br: 512
speed: 976.1kB/s
start reading ARTOGARD.WAV
fr: 0 num: 10866 br: 1024
speed: 1086.6kB/s
start reading ARTOGARD.WAV
fr: 0 num: 7660 br: 2048
speed: 1532.0kB/s
start reading ARTOGARD.WAV
fr: 0 num: 4827 br: 4096
speed: 1930.8kB/s

start writing 512.BIN
fr: 0 num: 6610 br: 512
speed: 330.5kB/s
start writing 1024.BIN
fr: 0 num: 3837 br: 1024
speed: 383.7kB/s
start writing 2048.BIN
fr: 0 num: 4037 br: 2048
speed: 807.4kB/s
start writing 4096.BIN
fr: 0 num: 3366 br: 4096
speed: 1346.4kB/s

SPI DMA方式核心部分代码如下,详见源码。

[C] 纯文本查看 复制代码
void SD_DMA_Config(void)
{
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHB1PeriphClockCmd(SD_DMA_RCC, ENABLE);

    DMA_DeInit(SD_DMA_RX_STREAM);
    DMA_DeInit(SD_DMA_TX_STREAM);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SD_SPI->DR));
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //!!!
    DMA_InitStructure.DMA_BufferSize = 0; //!!!

    DMA_InitStructure.DMA_Channel = SD_DMA_RX_CHANNEL;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; //!!!
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_Init(SD_DMA_RX_STREAM, &DMA_InitStructure);

    DMA_InitStructure.DMA_Channel = SD_DMA_TX_CHANNEL;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; //!!!
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
    DMA_Init(SD_DMA_TX_STREAM, &DMA_InitStructure);

    SPI_I2S_DMACmd(SD_SPI, SPI_I2S_DMAReq_Rx, ENABLE);
    SPI_I2S_DMACmd(SD_SPI, SPI_I2S_DMAReq_Tx, ENABLE);
}

SD卡读取设置(写入类似)
[C] 纯文本查看 复制代码
// 设置接收通道
SD_DMA_RX_STREAM->CR |= DMA_MemoryInc_Enable; //自增
SD_DMA_RX_STREAM->M0AR = (uint32_t)pBuffer;
SD_DMA_RX_STREAM->NDTR = BlockSize;
//DMA_SetCurrDataCounter(SD_DMA_RX_STREAM, BlockSize);

// 设置发送通道
SD_DMA_TX_STREAM->CR &= ~DMA_MemoryInc_Enable; //不自增
SD_DMA_TX_STREAM->M0AR = (uint32_t)&Dummy_Send;
SD_DMA_TX_STREAM->NDTR = BlockSize;
//DMA_SetCurrDataCounter(SD_DMA_TX_STREAM, BlockSize);

// 启动
SD_DMA_RX_STREAM->CR |= DMA_SxCR_EN; //先启动接收
//DMA_Cmd(SD_DMA_RX_STREAM, ENABLE);
while(!(SD_DMA_RX_STREAM->CR & DMA_SxCR_EN));
//while(DMA_GetCmdStatus(SD_DMA_RX_STREAM) == DISABLE);
SD_DMA_TX_STREAM->CR |= DMA_SxCR_EN; //再启动发送
//DMA_Cmd(SD_DMA_TX_STREAM, ENABLE);
while(!(SD_DMA_TX_STREAM->CR & DMA_SxCR_EN));
//while(DMA_GetCmdStatus(SD_DMA_TX_STREAM) == DISABLE);

// 等待完成
while(!((SD_DMA->HISR & RESERVED_MASK) & SD_DMA_TX_TCIF));
//while(!DMA_GetFlagStatus(SD_DMA_TX_STREAM, SD_DMA_TX_TCIF));
while(!((SD_DMA->LISR & RESERVED_MASK) & SD_DMA_RX_TCIF));
//while(!DMA_GetFlagStatus(SD_DMA_RX_STREAM, SD_DMA_RX_TCIF));

// 清除完成标志
SD_DMA->LIFCR = SD_DMA_RX_TCIF & RESERVED_MASK; //清除接收完成标志
//DMA_ClearFlag(SD_DMA_RX_STREAM, SD_DMA_RX_TCIF);
SD_DMA->HIFCR = SD_DMA_TX_TCIF & RESERVED_MASK; //清除发送完成标志
//DMA_ClearFlag(SD_DMA_TX_STREAM, SD_DMA_TX_TCIF);

// 停止
SD_DMA_TX_STREAM->CR &= ~DMA_SxCR_EN;
//DMA_Cmd(SD_DMA_TX_STREAM, DISABLE);
while(SD_DMA_TX_STREAM->CR & DMA_SxCR_EN);
//while(DMA_GetCmdStatus(SD_DMA_TX_STREAM) == ENABLE);
SD_DMA_RX_STREAM->CR &= ~DMA_SxCR_EN;
//DMA_Cmd(SD_DMA_RX_STREAM, DISABLE);
while(SD_DMA_RX_STREAM->CR & DMA_SxCR_EN);
//while(DMA_GetCmdStatus(SD_DMA_RX_STREAM) == ENABLE);

STM32F3与F4的DMA存在一些区别,故DMA部分的代码需要作相应修改,详见附件。

SPI_DMA_TEST.rar

8.7 MB, 下载次数: 16590

SD_SPI_DMA_STM32F3.rar

9.75 KB, 下载次数: 1052

回复

使用道具 举报

  离线 

72

主题

2720

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3420
金钱
3420
注册时间
2014-8-4
在线时间
660 小时
发表于 2015-10-10 15:08:40 | 显示全部楼层
谢谢分享,有时间了试试~~~
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

  离线 

21

主题

125

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2013-1-10
在线时间
10 小时
发表于 2015-10-10 15:43:53 | 显示全部楼层
我用10M以太网  通F407向闪迪的tf卡内写数据 通过sdio+znfat  传输+写入一个15M 的数据 竟然用了我27分钟 太长了
个人博客www.xiaovdiy.cn
https://shop100764513.taobao.com/
回复 支持 反对

使用道具 举报

  离线 

499

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
129612
金钱
129612
注册时间
2010-12-1
在线时间
1163 小时
发表于 2015-10-10 18:15:09 | 显示全部楼层
谢谢分享....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

  离线 

15

主题

78

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2012-11-21
在线时间
9 小时
发表于 2015-10-12 22:20:03 | 显示全部楼层
正点原子公众号
谢谢分享。。。
回复 支持 反对

使用道具 举报

  离线 

44

主题

186

帖子

4

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2012-9-1
在线时间
65 小时
发表于 2015-10-13 18:55:15 | 显示全部楼层
标记一下,也许有用,谢谢分享
回复 支持 反对

使用道具 举报

  离线 

3

主题

326

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1558
金钱
1558
注册时间
2014-12-19
在线时间
517 小时
 楼主| 发表于 2015-10-13 19:01:38 | 显示全部楼层
回复【7楼】yklstudent:
---------------------------------
适用于STM32F3代码见附件。
回复 支持 反对

使用道具 举报

  离线 

20

主题

120

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
230
金钱
230
注册时间
2015-6-4
在线时间
5 小时
发表于 2015-10-19 13:00:55 | 显示全部楼层
学习了,以后有时一定好好学学!
回复 支持 反对

使用道具 举报

  离线 

499

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
129612
金钱
129612
注册时间
2010-12-1
在线时间
1163 小时
发表于 2016-6-1 20:21:14 | 显示全部楼层
cool
回复 支持 反对

使用道具 举报

  离线 

499

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
129612
金钱
129612
注册时间
2010-12-1
在线时间
1163 小时
发表于 2016-6-1 20:22:36 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  离线 

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2016-6-3
在线时间
15 小时
发表于 2016-7-12 12:30:14 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  离线 

1

主题

8

帖子

0

精华

新手入门

积分
39
金钱
39
注册时间
2015-9-6
在线时间
4 小时
发表于 2016-7-12 13:38:55 | 显示全部楼层
楼主好人,谢谢分享
回复 支持 反对

使用道具 举报

  离线 

1

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
314
金钱
314
注册时间
2012-5-8
在线时间
75 小时
发表于 2016-7-13 08:40:26 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  离线 

8

主题

33

帖子

0

精华

高级会员

Rank: 4

积分
831
金钱
831
注册时间
2015-9-1
在线时间
161 小时
发表于 2016-7-13 09:44:47 | 显示全部楼层
感谢  正需要
回复 支持 反对

使用道具 举报

  离线 

14

主题

84

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
220
金钱
220
注册时间
2012-10-11
在线时间
64 小时
发表于 2016-7-15 19:31:37 | 显示全部楼层
谢谢楼主的分享,DMA模式SPI
回复 支持 反对

使用道具 举报

  离线 

12

主题

77

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
346
金钱
346
注册时间
2014-1-22
在线时间
41 小时
发表于 2016-7-20 15:46:37 | 显示全部楼层
谢谢楼主,我用FATF32读取SD卡文件太慢,感觉你的程序帮助很大
任何一件事情,只要心甘情愿,总是能够变得简单。
回复 支持 反对

使用道具 举报

  离线 

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-2-7
在线时间
5 小时
发表于 2016-8-12 19:58:01 | 显示全部楼层
楼主好人
年轻即出发, 一天两天算不了什么。hold~
回复 支持 反对

使用道具 举报

  离线 

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2015-2-7
在线时间
5 小时
发表于 2016-8-12 20:15:17 | 显示全部楼层
谢谢分享,有时间了试试~~~
年轻即出发, 一天两天算不了什么。hold~
回复 支持 反对

使用道具 举报

  离线 

87

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
906
金钱
906
注册时间
2016-3-26
在线时间
116 小时
发表于 2016-8-25 11:42:58 | 显示全部楼层
雨山 发表于 2015-10-10 15:43
我用10M以太网  通F407向闪迪的tf卡内写数据 通过sdio+znfat  传输+写入一个15M& ...

你好 朋友,你的问题解决了吗?我现在学这块,跟你的一样,也是网络传数据保存在SD卡,用的时间也是很久,如果你的问题已经解决了可以帮助我一下吗?
回复 支持 反对

使用道具 举报

  离线 

1

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2010-12-14
在线时间
53 小时
发表于 2016-11-27 09:28:54 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

  离线 

53

主题

369

帖子

0

精华

高级会员

Rank: 4

积分
948
金钱
948
注册时间
2016-6-15
在线时间
442 小时
发表于 2016-11-27 10:07:15 | 显示全部楼层
SPI有这么快吗?楼主SPI频率多少?
回复 支持 反对

使用道具 举报

magicigloo 该用户已被删除
发表于 2017-1-8 03:40:24 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

  离线 

1

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2012-11-5
在线时间
25 小时
发表于 2017-2-11 10:16:34 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

  离线 

0

主题

3

帖子

0

精华

新手入门

积分
40
金钱
40
注册时间
2016-12-15
在线时间
8 小时
发表于 2017-2-28 13:41:04 | 显示全部楼层
谢谢楼主的分享,但是我在修改IO口后,发现没办法烧录呀Erase Failed!,是不是PB4在其他地方还有使用呢,我PB4作为SW的复位脚用的
回复 支持 反对

使用道具 举报

  离线 

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2011-5-17
在线时间
18 小时
发表于 2017-3-5 18:22:47 | 显示全部楼层
不错,楼主可以试试高速SPI,42M的SPI速度 可以极大提升读卡速度
回复 支持 反对

使用道具 举报

  离线 

1

主题

5

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2015-3-17
在线时间
3 小时
发表于 2017-3-29 15:51:28 | 显示全部楼层
谢谢楼主,通过借鉴学习,解决了我的问题,非常感谢啊!!!
回复 支持 反对

使用道具 举报

  离线 

2

主题

31

帖子

0

精华

高级会员

Rank: 4

积分
594
金钱
594
注册时间
2017-3-17
在线时间
37 小时
发表于 2017-3-30 09:01:06 | 显示全部楼层
谢谢分享....
回复 支持 反对

使用道具 举报

  离线 

12

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
150
金钱
150
注册时间
2016-9-24
在线时间
26 小时
发表于 2017-4-6 17:50:59 | 显示全部楼层
好,谢谢分享
回复 支持 反对

使用道具 举报

  离线 

10

主题

17

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2017-4-7
在线时间
20 小时
发表于 2017-4-10 06:51:11 | 显示全部楼层
你给的是平均值吧,一个一个时间来看,写入SD卡的速度稳定吗?里面会不会有一些很奇怪的写入时间?
回复 支持 反对

使用道具 举报

  离线 

44

主题

298

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
208
金钱
208
注册时间
2016-9-9
在线时间
84 小时
发表于 2017-4-10 08:34:25 | 显示全部楼层
如果SDIO方式读写SD卡,用DMA速度多快,不用多块?
回复 支持 反对

使用道具 举报

  离线 

4

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
104
金钱
104
注册时间
2015-1-15
在线时间
17 小时
发表于 2017-6-20 08:51:55 | 显示全部楼层
楼主, 你好我把你的代码移植到了STM32F103 上面, SPI用的是SPI3, 最后速度是这样子的, 感觉差的好多。。。
--------SD Card Info--------
start reading ARTOGARD.WAV
fr: 0 num: 1000 br: 512
speed: 50.0kB/s
start reading ARTOGARD.WAV
fr: 0 num: 666 br: 1024
speed: 66.6kB/s
start reading ARTOGARD.WAV
fr: 0 num: 400 br: 2048
speed: 80.0kB/s
start reading ARTOGARD.WAV
fr: 0 num: 222 br: 4096
speed: 88.8kB/s
start writing 512.BIN
fr: 0 num: 930 br: 512
speed: 46.5kB/s
start writing 1024.BIN
fr: 0 num: 324 br: 1024
speed: 32.4kB/s
start writing 2048.BIN
fr: 0 num: 234 br: 2048
speed: 46.8kB/s
start writing 4096.BIN
fr: 0 num: 143 br: 4096
speed: 57.2kB/s
回复 支持 反对

使用道具 举报

  离线 

1

主题

8

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2017-8-31
在线时间
8 小时
发表于 2018-6-1 11:00:54 | 显示全部楼层
bbssuiji 发表于 2017-6-20 08:51
楼主, 你好我把你的代码移植到了STM32F103 上面, SPI用的是SPI3, 最后速度是这样子的, 感觉差的好多。 ...

您好,能否分享下移植代码,我正在调试这方面程序,没有DMA的SPI,读取SD卡速度只有40kB/s。
回复 支持 反对

使用道具 举报

  离线 

5

主题

110

帖子

0

精华

高级会员

Rank: 4

积分
609
金钱
609
注册时间
2015-11-26
在线时间
121 小时
发表于 2018-6-1 14:49:02 | 显示全部楼层
可以参考st官方的sd fatfs dma读写    支持rtos   大数据读写都不影响调度
回复 支持 反对

使用道具 举报

  离线 

6

主题

128

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
208
金钱
208
注册时间
2018-4-18
在线时间
10 小时
发表于 2018-6-19 16:54:09 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

  离线 

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2018-6-14
在线时间
12 小时
发表于 2018-6-27 18:57:03 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

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

本版积分规则




关闭

"原子哥”推荐上一条 /1 下一条

QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-7-17 03:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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