STM32 LL SPI TransmitReceive DMA - 中断未触发

问题描述 投票:0回答:1

我按照这个问题/教程STM32 SPI LL DMA Transmit使用DMA实现我自己的SPI TransmitReceive版本。

我的代码到目前为止运行良好,它基于低级驱动程序在 SPI 上发送/接收。

什么不起作用:当传输完成时,我想有一个中断,但无论我到目前为止尝试过什么:中断根本没有触发。

SPI 初始化一次:

// Note: called only once because the address of the peripheral does never change
// Configure RX
// LL_DMA_ConfigAddresses(DMA, DMA Channel, Source Addr, Dest Addr, Direction)
LL_DMA_ConfigAddresses(
    DMA1,
    LL_DMA_CHANNEL_2,
    LL_SPI_DMA_GetRegAddr(SPI1),
    (uint32_t)RXdata,
    LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2));

// Configure Tx
LL_DMA_ConfigAddresses(
    DMA1,
    LL_DMA_CHANNEL_3,
    (uint32_t)TXdata,
    LL_SPI_DMA_GetRegAddr(SPI1),
    LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3));

通过此代码重复启动传输:

// set RX
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)pRXdata);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, BufSz);
LL_SPI_EnableDMAReq_RX(SPI1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);

// set TX
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_3, (uint32_t)pTXdata);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, BufSz);
LL_SPI_EnableDMAReq_TX(SPI1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);

// Start SPI
LL_SPI_Enable(SPI1);

中断(传输完成和传输错误)“绑定”到 RX DMA 通道 - 就像 HAL 一样。

在(自动生成的)dma.c 文件中启用中断:

void MX_DMA_Init(void) {

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel2_IRQn interrupt configuration */
  NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),4, 0));
  NVIC_EnableIRQ(DMA1_Channel2_IRQn);
  /* DMA1_Channel3_IRQn interrupt configuration */
  NVIC_SetPriority(DMA1_Channel3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
  NVIC_EnableIRQ(DMA1_Channel3_IRQn);
}

CubeMX 中启用了 DMA 通道 2 和 3 的中断,我可以在中断向量表中找到这些函数。一般来说,中断是活动的,因为我可以看到 SysTic 中断触发。我还有一个定时器,它通过中断触发 SPI 传输。

void DMA1_Channel2_IRQHandler(void) 和 void DMA1_Channel3_IRQHandler(void) 存在于“stm32XXyyzzz_it.c”中。我向 DMA 通道 2 ISR 添加了一个计数器变量用于调试,该变量保持为 0 => ISR 从未被调用。

问题:我需要做什么才能使 DMA(通道 2)传输完成中断正常工作?

stm32 spi bare-metal
1个回答
0
投票

我找到了解决方案:问题不是 DMA 的设置,而是我只是在程序流程的早期禁用 DMA。 DMA 从未到达传输末尾,因此它不会触发“传输完成”IRQ。

上述代码有效且有效。我希望它能帮助其他人使用低级驱动程序实现自己的 SPI 功能。

© www.soinside.com 2019 - 2024. All rights reserved.