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

关于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方式读取。好了,上面废话了那么多,下面进入正题。
1 R: r% V, U! Y/ B( F7 uSPI既可以用工作于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()数据读函数:% a6 D, v& l. ^& y$ A
/*-----------------------------------------------------------------------*/
& |' j* z, Y/ w0 S; a# ~) Y/* Receive bytes from the card (bitbanging)                              */
( w! o, f  p% e) O4 S  o/*-----------------------------------------------------------------------*/: S/ l. n" U+ h9 C/ I3 T$ ~  D
unsigned char g_SPIDMASEND=0xFF;4 v2 ?& |; G9 S: v9 _7 m
static unsigned char DMA_Config_Flag=0;
( p  l9 V- H: a9 Gstatic$ K% S" F, t* d5 k) P
void rcvr_mmc (2 I0 |! `; M% N7 {6 @3 y' f) i  b
BYTE *buff, /* Pointer to read buffer */
/ X7 ]; ]0 u4 L  U8 S UINT bc  /* Number of bytes to receive */  F; \% a) O  _- U8 [' M: p
)$ D2 S/ y3 z; Q! m, B) a
{
1 z9 s* z3 l& y# ]8 a4 `6 h5 Y3 z    if(bc>=50)3 U0 g) q9 D# ?
    {
2 G2 h1 ~. K0 Q& A- Z% ~$ Q        if(DMA_Config_Flag==0)6 i; X; |: I: q+ }9 s
        {. E7 h. d- A9 e& {5 a+ _" v, G
            MYDMA_Config(DMA1_Channel4,(u32)&SPI2->DR,(u32)buff,bc,0x2080); //SPI2_DMA_RX
- V: G% w/ g, f0 Q* f9 m$ H            MYDMA_Config(DMA1_Channel5,(u32)&SPI2->DR,(u32)&g_SPIDMASEND,bc,0x1010);//SPI2_DMA_TX" G/ |3 O+ l1 r  Y- G
            DMA_Config_Flag=1;1 w# U% S" L9 a7 X2 ?% N' q
        }6 [, t2 n+ F) O. j
        else
4 A* o( {3 G) M. D# X' P8 ^( ^        {) r: I4 r' F; f0 ?
            DMA1_Channel4->CNDTR=bc;
% o; U9 k+ w! E* H$ r1 @            DMA1_Channel4->CMAR=(u32)buff;! p# j3 A% x& B5 h
            DMA1_Channel5->CNDTR=bc;# R& h2 N# x% k/ l# d3 j
        }
7 O4 c( o8 w8 j2 w6 r3 B- P        while((SPI2->SR&2)==0);
2 }7 H) c1 z4 z+ J" }6 m; j5 a3 C        SPI2->DR;7 _) ^# u+ f- a/ V* o
        SPI2->CR2|=3;  //enable TXDMA,RXDMA + E  D' f/ l5 ^2 E3 D$ e
                            9 T" e; P3 O! K. X  a
        MYDMA_Enable(DMA1_Channel4);
# ^# z# N3 x! R        MYDMA_Enable(DMA1_Channel5);! j/ F+ N6 D/ p1 ~' l
////////////////////////////////////////////////////////
" x/ I7 v( L# ?$ |; R8 t* O//参考 http://bbs.eeworld.com.cn/thread-250154-1-1.html3 _( Y( I4 O3 Z: D+ u  d
////////////////////////////////////////////////////////  x7 A: v6 u- U+ E/ J1 U
        . C0 d1 z; O* f1 {  _; K, O* x
        while(!(DMA1->ISR&(1DR=0xff;
. u1 g2 [  J, n            while((SPI2->SR&1)==0);
% Q0 @! Z! }, p% Q" Z7 K" ?            *buff++ = SPI2->DR;6 _, O3 a" e3 C/ I
        }
9 K9 k4 T% D! Q- x6 T5 m    }5 g) z  E+ L! V2 t
}3 z. Q3 U: U, h1 I' `* P
当读取数据小于50时采用非DMA读写,大于等于50采用DMA读写,以提高效率。这样改写后,再测试读取同一文件的速度达到696KB/s,相比之前提升了近3/4,DMA的速度果然够快。大家也可以尝试一下。
8 g& y/ T1 s0 v* w# D" M0 L9 X 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发表:& L5 j/ |3 I+ m$ u* s: D. Q* t$ i
就需要这么一点程序吗 
5 t$ Q' N; z7 g$ |3 }8 H+ ~* e
4 o3 j* O+ l4 I+ a' d/ Y! H你好,最近我也在用CH376,也用DMA方式,能不能给个完整的程序,感激不尽啊!邮箱是:1373812024@qq.com
mengyy123 回答时间:2015-10-31 09:42:17
SD传输的时候一直卡在了DMA等待这里: f7 W% S+ n; y4 {
用野火的不行,换了安富莱的驱动就可以了
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 手机版