首页 > 其他分享 >野火STM32第35章 SDIO读写测试 实验过程犯的错误:卡在while(SD_GetStatus() != SD_TRANSFER_OK);

野火STM32第35章 SDIO读写测试 实验过程犯的错误:卡在while(SD_GetStatus() != SD_TRANSFER_OK);

时间:2023-06-06 23:14:47浏览次数:36  
标签:DMA OK TRANSFER DMA2 SDIO FLAG InitStruct SD

看完书,我自己重新写了一遍代码。

写代码过程中,对DMA以下标绿的部分很不以为意。

 1 void SD_DMA_TxConfig(uint32_t *DMA_Tx_Buf, uint32_t BufferSize)
 2 {
 3     DMA_InitTypeDef DMA_InitStruct;
 4     
 5     /*Clock Enable-----In GPIO Config*/
 6     
 7     /*Flag Clear----------------------------*/
 8     DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);
 9     
10     /*!< DMA2 Channel4 disable */
11    DMA_Cmd(DMA2_Channel4, DISABLE);
12     
13     /*-------------- Reset DMA init structure parameters values ------------------*/
14   DMA_InitStruct.DMA_PeripheralBaseAddr = SD_FIFO_ADDR;
15   DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)DMA_Tx_Buf;
16   DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
17   DMA_InitStruct.DMA_BufferSize = BufferSize / 4;  //除以4,把字转成字节单位
18   DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
19   DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
20   DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
21   DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
22   DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
23   DMA_InitStruct.DMA_Priority = DMA_Priority_High;
24   DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
25     
26     DMA_Init(DMA2_Channel4,&DMA_InitStruct);
27     DMA_Cmd(DMA2_Channel4, ENABLE);
28 }
29 
30 
31 /**
32     *@brief: Config_SD_DMA_Rx Function
33     Src:SD_card
34     Des:Buf
35     *@params:None
36     *@retvals:None
37 */
38 void SD_DMA_RxConfig(uint32_t *DMA_Rx_Buf, uint32_t BufferSize)
39 {
40     DMA_InitTypeDef DMA_InitStruct;
41     
42     /*Clock Enable-----In GPIO Config*/
43     
44     /*Flags Clear----------------*/
45     DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);//清除DMA标志位
46     
47     /*!< DMA2 Channel4 disable */
48     DMA_Cmd(DMA2_Channel4, DISABLE);    //SDIO为第四通道
49     
50     
51     /*-------------- Reset DMA init structure parameters values ------------------*/
52   DMA_InitStruct.DMA_PeripheralBaseAddr = SD_FIFO_ADDR;
    (代码同上,此处省略此处 DMA_InitStruct 结构体初始化......)
64     DMA_Init(DMA2_Channel4,&DMA_InitStruct);
65     DMA_Cmd(DMA2_Channel4, ENABLE);
66 }

 首先要分析的是这两个代码在哪里调用的?

在读单个块的函数中, SD_ReadBlock 通过下面的代码实现数据传输,其中第4行调用了SD_DMA_RxConfig()

1 #elif defined (SD_DMA_MODE)
2     SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);
3     SDIO_DMACmd(ENABLE);
4     SD_DMA_RxConfig((uint32_t *)readbuff, BlockSize);

//读多个块第4行为 SD_DMA_RxConfig((uint32_t *)readbuff, (NumberOfBlocks * BlockSize));

同理,在写单个块的函数 SD_WriteBlock 中,也有相同内容。

1 #elif defined (SD_DMA_MODE)
2   SDIO_ITConfig(SDIO_IT_DATAEND, ENABLE);
3   SD_DMA_TxConfig((uint32_t *)writebuff, BlockSize);
4   SDIO_DMACmd(ENABLE);

 

 

经过我的实验,上面代码下面这部分内容(DMA清楚标志)取掉也不会有影响。

但是为了程序的稳健性,最好还是加上。

 7     /*Flag Clear----------------------------*/
 8     DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);

但是不能没有这行代码:

10     /*!< DMA2 Channel4 disable */
11    DMA_Cmd(DMA2_Channel4, DISABLE);

一种原因是:在  SD_SingleBlockTest(void) 中,一开始进行写,已经使能了DMA传输,

当接下来进行读的时候,如果不先让DMA暂时停止(此时需要修改的DMA结构体参数还没改),那么可能导致数据传输的错乱。

也就是说:有可能DMA本来应该把数据从SD卡传到SDIO,但是由于DMA仍在工作。

同时,在SD_ReadBlock代码中,SDIO_DMACmd(ENABLE);在SD_DMA_RxConfig的前面。因此DMA把数据从SDIO传到SD卡了。

 

总结一下:就是在多次进行不同方向的DMA传输的时候,记得暂时现将DMA功能关闭一下,防止误操作,本来不应该传输的传出去了。

标签:DMA,OK,TRANSFER,DMA2,SDIO,FLAG,InitStruct,SD
From: https://www.cnblogs.com/FBsharl/p/17461955.html

相关文章

  • haproxy.router.openshift.io/disable_cookies
    haproxy.router.openshift.io/disable_cookies是OpenShift中Route对象的一个注解,用于控制是否禁用HAProxy负载均衡器在请求和响应中添加Cookie。当该注解设置为true时,HAProxy负载均衡器将不会在请求和响应中添加Cookie。这对于一些特定的应用程序场景可能非常有用,例......
  • RDS 、HDFS、 mapreduce 、spark 、hive、 hbase 、zookeeper 、kafka 、flume、mysql
    这些技术是大数据领域的常用组件,它们之间的配置文件依赖关系如下:RDS是一种关系型数据库,可以独立安装和使用,不需要依赖其他组件。HDFS是Hadoop分布式文件系统,通常与MapReduce一起使用。在Hadoop集群中,HDFS需要配置core-site.xml和hdfs-site.xml两个文件,其中core-site......
  • 带paramter的驱动(book.ko)
    1,代码1/*2*asimplekernelmodulesupportingparameters3*4*Copyright(C)2014BarrySong([email protected])5*6*LicensedunderGPLv2orlater.7*/89#include<linux/init.h>10#include<linux/module.h>1112......
  • Cookie、localStorage、sessionStorage
    本文参考了以下视频cookie、localStorage和sessionStorage的区别及应用实例浏览器本地存储CookieCookie是一种存储机制HTTPCookie(也叫WebCookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据(一般不超过4kb)。浏览器会存储cookie并在下次向同一......
  • 基于《PythonCookbook》的学习(3)——利用 Shell 通配符做字符串匹配
    fnmatch模块提供了fnmatch()和fnmatchcase()两个函数可以使用通配符模式对文本进行匹配fnmatch所完成的匹配操作有点介乎于加单的字符串方法和全功能的正则表达式之间。感觉蛮鸡肋的…:(......
  • 基于《PythonCookbook》的学习(1)——针对任意多的分隔符拆分字符串
    问题:需要将字符串拆分为不同的字段,但是分隔符(以及分隔符之间的空格)在整个字符串中并不一致re.split()方法比str.split()方法更为灵活,可以为分隔符指定多个模式re.split()方法返回一个list目标字符串:In[15]:lineOut[15]:'asdasdsadas,,,,sdfdsfi///ds...ds/essd//s......
  • Zookeeper
    zookeeperZooKeeper是一个开源的分布式应用程序协调服务简单来说可以理解为zookeeper=文件系统+监听通知机制应用场景:集群管理、服务器状态感知分布式应用配置管理统一命名服务分布式锁小总结:为客户提供写数据功能数据不大状态信息数据为客户提供读取据功能......
  • 如何把一个报表从2分钟优化到1秒?---GaussDB数据库
    报表优化系列文章----如何把一个报表从2分钟优化到1秒?优化需求:报表名:外部数据查询报表\EDM004-外部数据查询量业务类型_部门编号需求说明:原报表SQL运行时长2分钟,感觉慢,让DBA看看是否有优化的空间,给优化一下。优化人:4K/weicat:wx120890945优化日期:2022-03-03数据库类型:Ga......
  • 2_Transferring Files, Passwordless login & Managing multiple servers
     原文:https://www.codewithharry.com/blogpost/transferring-files-passwordless-login-ubuntu-20-04/ TransferringFiles,Passwordlesslogin&ManagingmultipleserversInthispost,Iwillshowyouhowtoavoidenteringpasswordsmultipletimeswhilema......
  • ARN [main-SendThread(db99:2222)] zookeeper.ClientCnxn: Session 0x0 for server n
    1.2014-07-2117:24:36,310WARN [main-SendThread(db99:2222)]zookeeper.ClientCnxn:Session0x0forservernull,unexpectederror,closingsocketconnectionandattemptingreconnectjava.net.ConnectException:拒绝连接     ......