Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C STM32 DMA传输错误_C_Stm32_Spi_Dma - Fatal编程技术网

C STM32 DMA传输错误

C STM32 DMA传输错误,c,stm32,spi,dma,C,Stm32,Spi,Dma,我使用STM32F407VTG6控制器,并尝试使用DMA从SPI接收数据。然后我想在DMA完全传输中断上处理数据。但当发生完全传输中断时,我看到TEIF(传输错误中断标志)被设置。在此之后,无法启动DMA。这是我代码的一部分: static void DmaInit() { DMA_InitTypeDef dma; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA for Rx dma.DMA_Channel =

我使用STM32F407VTG6控制器,并尝试使用DMA从SPI接收数据。然后我想在DMA完全传输中断上处理数据。但当发生完全传输中断时,我看到TEIF(传输错误中断标志)被设置。在此之后,无法启动DMA。这是我代码的一部分:

static void DmaInit()
{
 DMA_InitTypeDef dma;

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

 // DMA for Rx
 dma.DMA_Channel = DMA_Channel_3;
 dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
 dma.DMA_Memory0BaseAddr = 0; // will be set later
 dma.DMA_DIR = DMA_DIR_PeripheralToMemory;
 dma.DMA_BufferSize = 1; // will be set later
 dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
 dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
 dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
 dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
 dma.DMA_Mode = DMA_Mode_Normal;
 dma.DMA_Priority = DMA_Priority_High;
 dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
 dma.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
 dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;
 dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
 DMA_DeInit(DMA2_Stream2);
 DMA_Init(DMA2_Stream2, &dma);

 // Enable DMA Interrupt on complete transfer
 NVIC_EnableIRQ(DMA2_Stream2_IRQn);
 DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);
}

// It run on external interrupt
static void DmaStart(uint32_t bufferSize, uint32_t* rxBuffer)
{ 
 // Start DMA for reading
 DMA2_Stream2->NDTR = bufferSize;
 DMA2_Stream2->M0AR = (uint32_t)rxBuffer;
 DMA_Cmd(DMA2_Stream2, ENABLE);
}

static void SpiInit()
{
  SPI_InitTypeDef spi;

  // Enable clock for SPI
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

  // SPI settings
  SPI_StructInit(&spi);
  spi.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  spi.SPI_Mode = SPI_Mode_Master;
  spi.SPI_DataSize = SPI_DataSize_8b;
  spi.SPI_CPOL = SPI_CPOL_Low;
  spi.SPI_CPHA = SPI_CPHA_2Edge;
  spi.SPI_NSS = SPI_NSS_Soft;
  spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
  spi.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_Init(SPI1, &spi);
  SPI_Cmd(SPI1, ENABLE);

  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
}

我这几天刚完成SDIO+DMA,一些笔记可能对你有用:

  • 在启用流之前清除标志

    DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_FEIF2|DMA_FLAG_DMEIF2|DMA_FLAG_TEIF2|DMA_FLAG_HTIF2|DMA_FLAG_TCIF2);
    
  • 清除DMA_SxCR寄存器中的EN位,在DMA_Init()之前等待EN位被读取为0

  • 使用DMA_FIFOMode_Disable(直接模式)时,数据宽度由DMA_外围设备数据大小(PSIZE)确定,忽略DMA_内存数据大小(MSIZE)

  • 内存地址必须与选定的数据宽度(半字)对齐

  • 参考:

  • -第10章DMA控制器
  • STM32F4XX标准外设库

  • 只是我希望有人面对同样的问题,他有解决办法。谢谢你的回答。在DmaInit解决此问题之前调用DMA_Cmd(DMA2_Stream2,DISABLE)。
    DMA_Cmd(DMA2_Stream2, DISABLE);
    while (DMA2_Stream2->CR & DMA_SxCR_EN);