OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5402|回复: 13

spi dma方式读写sd卡程序一直卡死,不能写入数据,求大佬帮助

[复制链接]

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2020-1-17
在线时间
28 小时
发表于 2020-4-9 15:49:45 | 显示全部楼层 |阅读模式
本帖最后由 冻冻的冰冰 于 2020-4-9 17:10 编辑

#include "dma.h"
#include "sys.h"

uint8_t DMA2_Config(void)
{

DMA_InitTypeDef  DMA_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
  
  DMA_DeInit(DMA2_Stream0);
DMA_DeInit(DMA2_Stream3);

while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE){}//等待DMA可配置

  /* 配置 DMA Stream SPI_RX*/
  DMA_InitStructure.DMA_Channel = DMA_Channel_3;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;;//DMA外设地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
  DMA_InitStructure.DMA_BufferSize = 512;//数据传输量
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;//存储器4个节拍一次突发
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;//外设4个节拍一次突发
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);//初始化DMA2 Stream0
  
while (DMA_GetCmdStatus(DMA2_Stream3) != DISABLE){}//等待DMA可配置  
  
   /* 配置 DMA Stream SPI_TX*/
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到存储器模式
  DMA_Init(DMA2_Stream3, &DMA_InitStructure);//初始化DMA2 Stream 3

SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Rx,ENABLE); //使能SPI的DMA接收请求
SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE); //使能SPI的DMA发送请求

return 0;
}
//从sd卡读取一个数据包的内容时候启动DMA传输
//buf:数据缓存区
//len:要读取的数据长度.
uint8_t DMA2_Star_SPI_RX(uint8_t *buffer,uint16_t len)
{
    uint8_t temp=0xff;
  /*SPI作为主机进行数据接收时必须要主动产生时钟,因此此处必须有DMA2 Stream 3的配合*/
    while (DMA_GetCmdStatus(DMA2_Stream3) != DISABLE){}//等待DMA可配置  
  DMA2_Stream3->NDTR = len;//数据传输量
  DMA2_Stream3->M0AR = (uint32_t)&temp;//DMA 存储器0地址
  DMA2_Stream3->CR|=0<<10;//将DMA流3设置为内存地址非自增方式
   
  while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE){}//等待DMA可配置  
  DMA2_Stream0->M0AR = (uint32_t)buffer;

  DMA_Cmd(DMA2_Stream0,ENABLE); //首先使能数据流0
  DMA_Cmd(DMA2_Stream3,ENABLE); //其次使能数据流3
   
  while(!DMA_GetFlagStatus(DMA2_Stream0,DMA_FLAG_TCIF0)==1){}; //等待DMA流0接收数据完成
  DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_TCIF3); //清除DMA通道0的传输完成标志
  
  DMA_Cmd(DMA2_Stream0,DISABLE);
  DMA_Cmd(DMA2_Stream3,DISABLE);//使DMA流0和3停止工作
  
   while (DMA_GetCmdStatus(DMA2_Stream3) != DISABLE){}//等待DMA可配置
  DMA2_Stream3->CR|=1<<10;  //将DMA流3恢复为内存地址自增方式
   
   return 0;
}
//向sd卡写入一个数据包的内容 512字节 启动DMA传输
//buf:数据缓存区
uint8_t DMA2_Star_SPI_TX(uint8_t *buffer)
{
  while (DMA_GetCmdStatus(DMA2_Stream3) != DISABLE){}//等待DMA可配置
  DMA2_Stream3->NDTR=512; //设置要传输的数据长度
  DMA2_Stream3->M0AR= (uint32_t)buffer;//设置RAM缓冲区地址
  
  DMA_Cmd(DMA2_Stream3,ENABLE); //启动DMA传输 SPI->SRAM
  while(!DMA_GetFlagStatus(DMA2_Stream3,DMA_FLAG_TCIF3)==1){}; //等待DMA2流3传输完成
  DMA_ClearFlag(DMA2_Stream3,DMA_FLAG_TCIF3); //清除DMA2流3传输完成状态标记
  DMA_Cmd(DMA2_Stream3,DISABLE); //使DMA2流3停止工作
   
   return 0;
}
//从sd卡读取一个数据包的内容
//buf:数据缓存区
//len:要读取的数据长度.
//返回值:0,成功;其他,失败;
u8 SD_RecvData(u8*buf,u16 len)
{        
if(SD_GetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE
//    while(len--)//开始接收数据
//    {
//        *buf=SPI1_ReadWriteByte(0xFF);
//        buf++;
//    }
  DMA2_Star_SPI_RX(buf,len);
    //下面是2个伪CRC(dummy CRC)
    SD_SPI_ReadWriteByte(0xFF);
    SD_SPI_ReadWriteByte(0xFF);                    
    return 0;//读取成功
}
//向sd卡写入一个数据包的内容 512字节
//buf:数据缓存区
//cmd:指令
//返回值:0,成功;其他,失败;
u8 SD_SendBlock(u8*buf,u8 cmd)
{
u16 t;      
if(SD_WaitReady())return 1;//等待准备失效
SD_SPI_ReadWriteByte(cmd);
if(cmd!=0XFD)//不是结束指令
{
//  for(t=0;t<512;t++)SPI1_ReadWriteByte(buf[t]);//提高速度,减少函数传参时间
   DMA2_Star_SPI_TX(buf);
     SD_SPI_ReadWriteByte(0xFF);//忽略crc
     SD_SPI_ReadWriteByte(0xFF);
  t=SD_SPI_ReadWriteByte(0xFF);//接收响应
  if((t&0x1F)!=0x05)return 2;//响应错误                    
}                           
    return 0;//写入成功
}
希望能给点意见,谢谢大家了。
另附我的工程

SPI读写sd卡.zip

5.97 MB, 下载次数: 34

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2020-1-17
在线时间
28 小时
 楼主| 发表于 2020-4-11 14:44:48 | 显示全部楼层
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-4-11 16:24:21 | 显示全部楼层

回帖奖励 +3 金钱

回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2020-1-17
在线时间
28 小时
 楼主| 发表于 2020-4-16 22:01:18 | 显示全部楼层
nashui_sx 发表于 2020-4-11 16:24
http://www.openedv.com/forum.php?mod=viewthread&tid=301616&extra= 这个里面有

好的,我研究一下
回复 支持 反对

使用道具 举报

37

主题

477

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2285
金钱
2285
注册时间
2017-8-24
在线时间
375 小时
发表于 2020-6-4 16:55:00 | 显示全部楼层

回帖奖励 +3 金钱

DMA中断回调的时候看看标志
天然懒,天然呆
能吃会睡,未来可期
回复 支持 反对

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2021-12-28 15:11:19 | 显示全部楼层

回帖奖励 +3 金钱

帮顶   
回复 支持 反对

使用道具 举报

14

主题

821

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2070
金钱
2070
注册时间
2021-7-17
在线时间
647 小时
发表于 2021-12-28 15:11:49 | 显示全部楼层

回帖奖励 +3 金钱

帮顶   
回复 支持 反对

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2021-12-28 15:11:51 | 显示全部楼层

回帖奖励 +3 金钱

踩一踩  
回复 支持 反对

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-12-28 15:11:54 | 显示全部楼层

回帖奖励 +3 金钱

帮顶     
回复 支持 反对

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-12-28 15:12:15 | 显示全部楼层

回帖奖励 +3 金钱

感谢楼主分享   
回复 支持 反对

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2021-12-28 15:12:22 | 显示全部楼层

回帖奖励 +3 金钱

冲冲冲  
回复 支持 反对

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-12-28 15:12:36 | 显示全部楼层

回帖奖励 +3 金钱

楼主大大牛逼   
回复 支持 反对

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2021-12-28 15:12:52 | 显示全部楼层

回帖奖励 +3 金钱

确实强
回复 支持 反对

使用道具 举报

2

主题

592

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1458
金钱
1458
注册时间
2019-7-28
在线时间
137 小时
发表于 2021-12-28 15:13:08 | 显示全部楼层
SPI+DMA的话也没怎么用过
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 09:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表