大鼻子JOJO 2023-03-20 20:48 采纳率: 75%
浏览 95
已结题

STM32使用SPI的DMA通道读写SD卡时程序卡死怎么办?

stm32使用SPI用dma通道写SD卡程序卡死

在不使用DMA的情况下是正常读写的,但是改用DMA以后运行时卡死,大概是在这个位置,检测传输完成标志位循环中卡死

#if EN_SPI_Tx_DMA  //如果使用SPI发送的DMA            
        DMA_Cmd(DMA1_Channel3,ENABLE); //使能DMA1通道3发送指令    
        while(DMA_GetFlagStatus(DMA1_FLAG_TC3)==RESET);//等待DMA传输完成
        {
            printf("1");
          DMA_Cmd(DMA1_Channel3,DISABLE);//关闭DMA1通道3指令
          DMA_ClearFlag(DMA1_FLAG_TC3);  //清除传输完成标志位;
        }    

另外DMA和SPI的配置如下:

void DMA_Tx_Init( DMA_Channel_TypeDef* DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize)
{
    DMA_InitTypeDef DMA_InitStructure={0};

    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );

    DMA_DeInit(DMA_CHx);
    
    DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr;
    DMA_InitStructure.DMA_MemoryBaseAddr = memadr;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = bufsize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init( DMA_CHx, &DMA_InitStructure );
    
    
    //DMA_Cmd(DMA1_Channel3,DISABLE); //关闭DMA1通道3发送指令    
}

void SPIx_Init(uint16_t speed)
{
  uint16_t tmp;

  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  
  //SPI_FLASH_SPI pins: SCK--PA5
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //SPI_FLASH_SPI pins: MISO--PA6 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //SPI_FLASH_SPI pins: MOSI--PA7 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  //SPI_FLASH_SPI_CS_PIN pin: CS--PA4
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  SPI_CS_HIGH();

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI1设置为两线全双工
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;      //设置SPI1为主模式
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;    //SPI发送接收8位帧结构
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;    //串行时钟在不操作时,时钟为高电平
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    //第二个时钟沿开始采样数据
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        //NSS信号由软件(使用SSI位)管理
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
  SPI_InitStructure.SPI_CRCPolynomial = 7;            //CRC值计算的多项式
  SPI_Init(SPI1, &SPI_InitStructure);

  switch(speed)     //设置波特率预分频的值
  {
    case 2:
      tmp = SPI_BaudRatePrescaler_2;break;
    case 4:
      tmp = SPI_BaudRatePrescaler_4;break;
    case 8:
      tmp = SPI_BaudRatePrescaler_8;break;
    case 16:
      tmp = SPI_BaudRatePrescaler_16;break;
    case 32:
      tmp = SPI_BaudRatePrescaler_32;break;
    case 64:
      tmp = SPI_BaudRatePrescaler_64;break;
    case 128:
      tmp = SPI_BaudRatePrescaler_128;break;
    case 256:
      tmp = SPI_BaudRatePrescaler_256;break;
    default:
      break ;
  }
  SPI_InitStructure.SPI_BaudRatePrescaler=tmp;    //波特率预分频值
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);
}

uint32_t buf2[512];//SD卡数据缓存区

DMA_Tx_Init( DMA1_Channel3, (u32)&SPI1->DR, (u32)buf2, 512 );
  • 写回答

3条回答 默认 最新

  • 我爱OJ 2023-03-20 21:17
    关注
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 3月28日
  • 已采纳回答 3月20日
  • 创建了问题 3月20日

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程