【问题标题】:STM32H7 SPI DMA transfer, always in busy transfer state, HAL_SPI_STATE_BUSY_TXSTM32H7 SPI DMA传输,一直处于忙传输状态,HAL_SPI_STATE_BUSY_TX
【发布时间】:2019-10-01 13:31:57
【问题描述】:

我正在尝试使用 DMA 在 SPI 中传输数据,因为我的 Hal 状态是 HAL_SPI_STATUS_BUSY_TX。所需的状态是 HAL_SPI_STATE_READY。我想通过 SPI 发送一些批量数据和命令(单字节)。是否可以分别在 DMA 和非 DMA 模式之间切换。如图所示,它在 while 中循环。

hdma1_tx.Instance                 = DMA1_Stream7;
hdma1_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
hdma1_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
hdma1_tx.Init.MemBurst            = DMA_MBURST_INC4;
hdma1_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
hdma1_tx.Init.Request             = DMA_REQUEST_SPI1_TX;
hdma1_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
hdma1_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
hdma1_tx.Init.MemInc              = DMA_MINC_ENABLE;
hdma1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma1_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
hdma1_tx.Init.Mode                = DMA_NORMAL;
hdma1_tx.Init.Priority            = DMA_PRIORITY_LOW;

if(HAL_DMA_Init(&hdma1_tx) != HAL_OK)
{
  // Error
}

/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmatx, hdma1_tx); 

/* Configure the DMA handler for Transmission process */
hdma_rx.Instance                 = DMA1_Stream1;
hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
hdma_rx.Init.Request             = DMA_REQUEST_SPI1_RX;
hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode                = DMA_NORMAL;
hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;

HAL_DMA_Init(&hdma_rx);

/* Associate the initialized DMA handle to the the SPI handle */
__HAL_LINKDMA(hspi, hdmarx, hdma_rx);

/*##-4- Configure the NVIC for DMA #########################################*/ 
/* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn); 

HAL_NVIC_SetPriority(SPI1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);

HAL_STATUS 必须是 HAL_SPI_STATE_READY。

我的数据长度加载到 NDTR 中。

启用 SPI 后 NDTR = 0x00

【问题讨论】:

  • 我在不同的芯片(STM32G4)上遇到了非常相似的问题;原来是配置问题。我将留下一个指向 EESE 答案的链接,我在其中按问题和解决方案描述,以防其他人发现这个问题:electronics.stackexchange.com/a/606613/194340

标签: c++ c embedded


【解决方案1】:

我将 TX DMA 流从 DAM1_Stream7 更改为 DMA1_Stream2,它得到了解决。不知道为什么不在 stream7 工作的根本原因。

【讨论】:

    【解决方案2】:

    可能导致此类问题的一个原因是存储要发送的数据的变量放置在错误的 RAM 区域中,请查看您的映射文件并修改链接描述文件

    你可以在这里找到更多 https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

    【讨论】:

    • 谢谢你,Hossam Alzomor。我已经在 >RAM_D2 部分配置了 dma 缓冲区。并对齐数据。尽管如此,问题仍然相同。我检查了 DMA 寄存器,S7NDTR(数据寄存器)是 0x0。我的流位被禁用,因此数据寄存器处于写入模式,即使这样我的数据也没有填充到寄存器中。在参考手册中明确提到,如果DATA寄存器为空,则无法进行传输。
    • 如果缓存已启用,请尝试禁用它
    • 是的,我禁用了缓存,我的数据缓冲区加载地址也是 RAM_D2。我仔细检查了它。不知道为什么我的数据寄存器是0x00。
    • 我发现我的NDTR寄存器正在加载要传输的数据数量,当SPI启用时,NDTR寄存器变为0x00。而我的状态是 HAL_DMA_STATE_BUSY,并且锁在循环中。
    猜你喜欢
    • 2019-02-21
    • 2012-11-20
    • 2018-11-13
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 2012-01-26
    • 2012-09-27
    • 2019-08-11
    相关资源
    最近更新 更多