你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于SPI的DMA方式读写SD卡

[复制链接]
waytoanswer 发布时间:2012-12-28 23:24
近期在做CH376的驱动,由于官方提供了参考手册,和驱动程序,在稍加移植后测试了简单的U盘读写函数,获取设备信息等功能并测试了读取文件的速度。由于之前移植了FATFS读写SD卡,想对比一下二者读写速度如何,于是采用内部RTC测时间加UART输出结果的方式测量了一下读文件的速度,测试结果CH376读取U盘速度约260KB/s(采用SPI接口,时钟为18MHz),SPI读取SD卡11M的MP3文件约330KB/s左右(SPI时钟为18MHz),后来优化了一下读SD卡的函数,速度提升390KB/s。可还是觉得速度不够快,于是考虑用DMA方式读取。好了,上面废话了那么多,下面进入正题。6 {. y; ~. B% Q2 d
SPI既可以用工作于DMA发送方式,也可以工作于DMA接收方式。SPI 采用DMA发送时一般没什么问题,然而接收时则出问题了。虽然都配置好了SPI_RX的DMA通道,也将SPI->CR2里的RXDMAEN置位了,但始终接收不到SD卡的数据,程序始终在等待DMA传输完成位置位。虽然知道SPI只有在DR写入数据开始发送时才会输出时钟,但在做DMA接收时认为时钟是自动输出的,于是始终解决不了问题,后来在网上找了很久,终于找到一个帖子,里面说的情况跟我遇到的类似,从中了解到SPI在DMA接收时并没有时钟输出,后来想想,这种SPI DMA接收应该是工作在从机模式的吧,因为主机会发送时钟。如果需要工作在主机接收模式,则还是要靠写DR来发送时钟,为此可以在开启接收DMA的同时开启发送DMA,并且接收DMA的优先级高于发送DMA,发送DMA配置为内存到外设,内存地址不自增,发送字节数与接收字节数相同,并且始终发送0xFF,这样发送通道的DMA每发送完一字节,RXNE置位,触发接收通道DMA,由于接收通道DMA优先级高于发送DMA,于是接收DMA接收一字节,而后TXE置位,又触发发送DMA,像这样循环,从而实现了SPI 的DMA连续接收数据。下面附上移植的FATFS里的rcvr_mmc()数据读函数:
% O( V. Z1 {& k( t: m2 o/*-----------------------------------------------------------------------*/  ?& Y6 `0 n: x
/* Receive bytes from the card (bitbanging)                              */
% u# H7 i/ a7 l) v0 G/*-----------------------------------------------------------------------*/9 T; f4 g+ ~) {. u/ b
unsigned char g_SPIDMASEND=0xFF;
2 L/ O3 F# f- zstatic unsigned char DMA_Config_Flag=0;7 K- P! t3 Y$ @9 G; Y" t, o
static  m9 ~  {1 [( M" O4 [4 ?
void rcvr_mmc (
+ ^+ O$ S1 k; g( Q: l7 @ BYTE *buff, /* Pointer to read buffer */
1 G& O6 ]5 |6 D+ ] UINT bc  /* Number of bytes to receive */
0 j. |/ R. X6 x! })9 l' w! P( U( G1 K- n
{% m% F4 _. G  F6 P1 W/ \/ m5 E4 p
    if(bc>=50)! `2 Z' |& O2 v2 j
    {
: M' d0 t+ {# ^2 t6 k        if(DMA_Config_Flag==0)
. Z" o* r7 b/ o" m        {
* g- C; C, u" K  ]6 b            MYDMA_Config(DMA1_Channel4,(u32)&SPI2->DR,(u32)buff,bc,0x2080); //SPI2_DMA_RX/ `1 }0 T% L/ e, W4 E
            MYDMA_Config(DMA1_Channel5,(u32)&SPI2->DR,(u32)&g_SPIDMASEND,bc,0x1010);//SPI2_DMA_TX6 y8 {7 b4 Q: J9 }1 \; y
            DMA_Config_Flag=1;$ P: D  f0 a8 Z4 ]! I4 i
        }
  A8 B! y8 K: ]6 c5 u% M' {, w        else. S+ p$ S5 t+ I6 z- v9 b0 s
        {/ x( y, _5 O1 E, {+ H
            DMA1_Channel4->CNDTR=bc;
* u+ Y# Y# q, ?            DMA1_Channel4->CMAR=(u32)buff;* V1 s$ o. t: L# K# V$ _: |) f
            DMA1_Channel5->CNDTR=bc;6 U9 v$ k1 _8 D( ]  O# N( N, D
        }
6 d$ y$ U. b& D. Z5 Y8 Z        while((SPI2->SR&2)==0);
. y9 y/ l  N0 @) W+ L" x, D) W3 r  n        SPI2->DR;
8 p1 b+ j7 l. Q# M/ }3 Q* g        SPI2->CR2|=3;  //enable TXDMA,RXDMA , t5 P' t( \* n% _* {- C
                           
" d. y/ Q6 W/ F' }- ^1 V* A! m+ o# D$ X        MYDMA_Enable(DMA1_Channel4);! j( E: O% K/ O8 U1 T
        MYDMA_Enable(DMA1_Channel5);5 W$ g7 k* [( [: E
////////////////////////////////////////////////////////* k) t) b; M/ x5 v# U" E
//参考 http://bbs.eeworld.com.cn/thread-250154-1-1.html
5 O4 x" L, Z+ P5 L" u////////////////////////////////////////////////////////2 O: K9 B  l( `: s3 g
        
0 y) q! k$ S, h. P/ A$ r        while(!(DMA1->ISR&(1DR=0xff;
. d( c- S2 h: F7 R3 S8 B' e            while((SPI2->SR&1)==0);* {: n6 W) u* ~9 P# }8 N: G
            *buff++ = SPI2->DR;
; m% x( H0 Y. L        }
- M2 S/ [- Q5 N    }
2 A# ?5 i+ Z1 F: M# \}
2 ]" l: g% N0 ~, h( C& y当读取数据小于50时采用非DMA读写,大于等于50采用DMA读写,以提高效率。这样改写后,再测试读取同一文件的速度达到696KB/s,相比之前提升了近3/4,DMA的速度果然够快。大家也可以尝试一下。
# W- q  h8 j( c/ a- z 09_1.jpg
赞 收藏 4 评论9 发布时间:2012-12-28 23:24

举报

9个回答
waytoanswer 回答时间:2012-12-29 13:57:24

RE:关于SPI的DMA方式读写SD卡

求围观啊
gideon518j 回答时间:2013-1-22 15:08:20

回复:关于SPI的DMA方式读写SD卡

 好文! 用DMA的性能都杠杠的。
creep 回答时间:2013-5-13 11:27:08

RE:关于SPI的DMA方式读写SD卡

求个完整例程。谢谢
lvlovelive 回答时间:2013-5-30 18:08:56

回复:关于SPI的DMA方式读写SD卡

好东东啊,学习了……
liucl2008 回答时间:2013-7-13 11:21:26

RE:关于SPI的DMA方式读写SD卡

就需要这么一点程序吗
pbSTM32 回答时间:2014-3-20 21:13:46

回复:关于SPI的DMA方式读写SD卡

回复第 6 楼 于2013-07-13 11:21:26发表:
" u# V9 p$ L" [) Q$ F) c# y就需要这么一点程序吗 
& H$ _* w/ G+ i: m9 |& M. g5 e4 z& }/ c& d0 Y
你好,最近我也在用CH376,也用DMA方式,能不能给个完整的程序,感激不尽啊!邮箱是:1373812024@qq.com
mengyy123 回答时间:2015-10-31 09:42:17
SD传输的时候一直卡在了DMA等待这里
4 o3 J: \3 @) R7 F( _/ b% C用野火的不行,换了安富莱的驱动就可以了
putiliaozu 回答时间:2017-8-3 09:58:36
nihaoshijie5188 回答时间:2018-2-22 15:42:47
希望大家可以多交流呀
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版