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

关于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方式读取。好了,上面废话了那么多,下面进入正题。2 K5 o+ |) i0 P. }4 B5 W; q
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()数据读函数:! _4 l$ L: s6 ~" F; G# X
/*-----------------------------------------------------------------------*/
) C5 Z5 C, T6 N' w$ D/* Receive bytes from the card (bitbanging)                              */: U% }% n3 m( f- n5 e6 w
/*-----------------------------------------------------------------------*/
- r2 s# e$ R0 f$ i, C  munsigned char g_SPIDMASEND=0xFF;
: q5 h5 P# P6 Mstatic unsigned char DMA_Config_Flag=0;' z  {3 z# s3 N8 G) l/ c
static
* s  o, i& _) q  k9 G4 {! n) I3 Cvoid rcvr_mmc (4 A5 j0 H6 H  I) y9 b. Z
BYTE *buff, /* Pointer to read buffer *// e% R* J5 G/ A- s7 P+ C
UINT bc  /* Number of bytes to receive */) S) i- S% j- m
)
0 |6 X/ _3 V, i: e{
0 @: ~8 d& C4 k    if(bc>=50)7 S' ?/ {: r1 I1 o+ `# D1 Z
    {* B4 _+ |1 ?5 ~" d6 K
        if(DMA_Config_Flag==0)
' n" T4 @9 u# I  B        {% R. F5 p/ {* _( P' t8 m
            MYDMA_Config(DMA1_Channel4,(u32)&SPI2->DR,(u32)buff,bc,0x2080); //SPI2_DMA_RX
/ Z7 e5 X* o) Z1 w0 a            MYDMA_Config(DMA1_Channel5,(u32)&SPI2->DR,(u32)&g_SPIDMASEND,bc,0x1010);//SPI2_DMA_TX
2 M5 Q# ]1 m/ o- v. s/ ~            DMA_Config_Flag=1;
1 ^+ E/ U' u' n0 p2 b. k        }4 e, z- o+ V$ Y/ E! Y5 {2 A9 I
        else
" _: n! l( D+ ], F; W% l" {        {( v! f$ R3 p" d3 L. G( f! v
            DMA1_Channel4->CNDTR=bc;7 ~: ^1 Y3 n  ^% x
            DMA1_Channel4->CMAR=(u32)buff;0 d  B$ U4 x* s1 R
            DMA1_Channel5->CNDTR=bc;, f1 D1 w, S( e* @% f" A  ]1 e/ U6 U, \
        }$ L0 a0 p9 {1 e! |" ]) @
        while((SPI2->SR&2)==0);
) w& u& e( w) @5 M% Z) a        SPI2->DR;
8 q# }5 ^& d3 d4 K. }0 ~        SPI2->CR2|=3;  //enable TXDMA,RXDMA
! I. H- l( d- A                           
1 }+ {* O2 T6 P7 x. i( P/ K        MYDMA_Enable(DMA1_Channel4);
# R& x; Q9 D+ O" g* L4 y        MYDMA_Enable(DMA1_Channel5);* i, |' E% H( j% P) Q  J: _
////////////////////////////////////////////////////////# i" F( q: R0 i- M# ^: O! T. @
//参考 http://bbs.eeworld.com.cn/thread-250154-1-1.html
4 {3 Z$ x" |; C3 M' _////////////////////////////////////////////////////////
" M# d+ v& P0 S, I% j' r/ M! r' Q        7 N5 x4 _+ i- z/ ]6 a
        while(!(DMA1->ISR&(1DR=0xff;
* U& J( g8 ~. D' E" E/ j& V3 Q            while((SPI2->SR&1)==0);5 H( W4 ~# [% U
            *buff++ = SPI2->DR;
" t9 e+ n. Q9 g: \9 s        }# a8 _1 ]0 G- K! M: j# u
    }. j' u% k% s% C: Z5 d: a7 ]$ I" ]
}
8 a* E, `6 a, E6 ^. Q4 Q( c1 {当读取数据小于50时采用非DMA读写,大于等于50采用DMA读写,以提高效率。这样改写后,再测试读取同一文件的速度达到696KB/s,相比之前提升了近3/4,DMA的速度果然够快。大家也可以尝试一下。
- B* j9 K  l* [3 P 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发表:
" o; a! Z# f+ C1 z/ F就需要这么一点程序吗 " h1 ~" k$ j3 O0 v6 u7 U' b7 x
& N3 c  V" }9 l& V$ D4 h* [. L. Q; f
你好,最近我也在用CH376,也用DMA方式,能不能给个完整的程序,感激不尽啊!邮箱是:1373812024@qq.com
mengyy123 回答时间:2015-10-31 09:42:17
SD传输的时候一直卡在了DMA等待这里( a, z4 q9 Z3 Z- |  i- o* O% l
用野火的不行,换了安富莱的驱动就可以了
putiliaozu 回答时间:2017-8-3 09:58:36
nihaoshijie5188 回答时间:2018-2-22 15:42:47
希望大家可以多交流呀

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版