完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
原发及代码下载 http://sites.google.com/site/btvnlue/stm32/dmasd 本文对STM32的SPI3读写SD卡进行讨论,读写使用直接模式,DMA模式,和DMA中断模式,并尝试对各种模式进行比较 一般来讲,使用DMA模式的优点在于,节省主程序资源,在直接对CPU/MCU编程的环境中,DMA模式类似于线程的效果。尤其在对实时处理比较严格的环境,如视频播放或采集,DMA会发挥重要作用,主程序更着眼于进行资源分配和流程控制。
rcc->ahbenr |= 0x02; //enable dma2spi3->cr2 = 0x3; // enable spi3 dma 使用DMA的中断功能,需要对NVIC和系统向量表vtor初始化这里只使用SPI3接受中断,DMA2的Channel1,IRQ56 nvic->iser.at[1] = 0x01000000; //enable IRQ56scb->vtor = (unsigned int)(&__Vectors) & 0x3FFFFF80;
unsigned char sd_bytedata(unsigned char cmd) { unsigned char output; while (((spi3->sr)&0x2)==0) {} //TXE empty spi3->dr = cmd; while (((spi3->sr)&0x1)==0) {} //RXNE empty output = (unsigned char)(spi3->dr); return output;}
DMA接受,读操作,接收缓存的内存指针自动增移,发送缓存为固定,数据长度相同 dma2->ch1.ccr = 0x0080; //MINC:yes P->M dma2->ch1.cndtr = cnt; dma2->ch1.cpar = (unsigned int)&(spi3->dr); dma2->ch1.cmar = (unsigned int)rtn; dma2->ch2.ccr = 0x0010; //MINC:no M-> dma2->ch2.cndtr = cnt; dma2->ch2.cpar = (unsigned int)&(spi3->dr); dma2->ch2.cmar = (unsigned int)cmd; DMA发送,写操作,发送缓存的内存指针自动增移,接收缓存为固定,数据长度相同 dma2->ch1.ccr = 0x0000; //MINC:no P->M dma2->ch1.cndtr = cnt; dma2->ch1.cpar = (unsigned int)&(spi3->dr); dma2->ch1.cmar = (unsigned int)rtn; dma2->ch2.ccr |= 0x0090; //MINC:yes M-> dma2->ch2.cndtr = cnt; dma2->ch2.cpar = (unsigned int)&(spi3->dr); dma2->ch2.cmar = (unsigned int)cmd; 主程序通过监视DMA的EVENT事件标志进行流程控制 while ((dma2->isr & 0x20) == 0); //check finish event while ((dma2->isr & 0x02) == 0); //check finish event 停止DMA,清除事件控制器,消除对下次操作影响 dma2->ifcr = 0xFF; //clear event
中断模式可以在中断函数中加入流程控制逻辑,更多节省主程序资源,对于像SD卡操作逻辑,在没有SDIO专用控制器帮助的情况下,DMA中断模式似乎是必须的选择。但程序难度增加,调试更加困难,尤其在纠错处理方面,需要更大的精力投入。 中断函数由于没有参数,犹如数据缓冲,及控制变量最好设置成全局变量使用中断函数不再监视事件寄存器,流程控制可以使用用户变量,定义各个状态变量 unsigned int dma_inv_state; #define SD_DMA_DAT_ONCE 0x1#define SD_DMA_RESPONSE 0x2#define SD_DMA_DATATOKEN 0x4#define SD_DMA_READDATA 0x10#define SD_DMA_WRITEDATA 0x20#define SD_DMA_COMPLETE 0x100 DMA读写操作前对中断标志设置 if (dma_inv_state) { dma2->ch1.ccr |= 0x2; // interrupt setup } 中断处理程序首先等待发送结束,然后清除事件,否则中断会不断被触发然后可以进行用户的流程操作 while ((dma2->isr & 0x20) == 0); //check finish event channel2 sd_stop_dma(); if (dma_inv_state & SD_DMA_RESPONSE) { } else if (dma_inv_state & SD_DMA_DATATOKEN) { } else if (dma_inv_state & SD_DMA_READDATA) { } else if (dma_inv_state & SD_DMA_COMPLETE) { } 主程序中对状态变量进行监控 while (dma_inv_state & SD_DMA_DAT_ONCE);
本程序实现DMA对双缓冲的读入,读入SD卡中的所有页,主程序对缓存页执行CRC校对 while ((ii |
|
相关推荐
4个回答
|
|
有没有具体的数据对比?
|
|
|
|
不好意思,没有做实际时测
实际上,对SD卡的读写速度取决于卡本身的速度,各种方式的差异并不是很大, 这里DMA和中断试验的目的是让主程序有时间执行用户逻辑,比如例程中,CRC计算的所有时间都可以在DMA方式下节省下来 CRC的执行时间取决于算法和MCU的主频速度 卡数据的读写和CRC计算的长者决定了缓冲的填充周期 |
|
|
|
CRC是一个可选项目,不是必须的项目.在SD卡读写的时候,可以不经过CRC计算的.只需要初始化的时候关闭即可.
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 06:42 , Processed in 0.777569 second(s), Total 53, Slave 46 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号