STM32F103C8T6 HAL_SPI_Transmit_DMA doesn't work well

huangapple go评论62阅读模式
英文:

STM32F103C8T6 HAL_SPI_Transmit_DMA doesn't work well

问题

我正在编写基本的SPI回环示例,使用STM32F103C8T6和CubeMX(spi1为主,spi2为从)。SPI2配置为DMA循环模式

第二个DMA调用存在问题:
hal_status = HAL_SPI_Receive_DMA(&hspi2, u8_SPI2_RxBuff, sizeofBuff);
hal_status返回hal_busy
但当我将DMA更改为中断时,它运行良好:

英文:

I am writing basic SPI loopback example with STM32F103C8T6 with CubeMX( spi1 is master and spi2 is slave). SPI2 is configured with DMA Circular mode

  /* USER CODE BEGIN 2 */
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
	hal_status = HAL_SPI_Transmit_DMA(&hspi2, u8_SPI2_TxBuff, sizeofBuff); //OK
	HAL_Delay(1000);
	HAL_SPI_Receive(&hspi1,u8_SPI1_RxBuff,sizeofBuff,100);
	HAL_Delay(1000);
	hal_status = HAL_SPI_Receive_DMA(&hspi2, u8_SPI2_RxBuff, sizeofBuff); // HAL BUSY
	HAL_Delay(1000);
	HAL_SPI_Transmit(&hspi1,u8_SPI1_TxBuff,sizeofBuff,100);
	HAL_Delay(1000);
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
  /* USER CODE END 2 */

There is an problem at the second DMA call :
hal_status = HAL_SPI_Receive_DMA(&hspi2, u8_SPI2_RxBuff, sizeofBuff);
hal_status return hal_busy
But when i change DMA to interrupt, it works well:

  /* USER CODE BEGIN 2 */
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
	hal_status = HAL_SPI_Transmit_IT(&hspi2, u8_SPI2_TxBuff, sizeofBuff);
	HAL_Delay(1000);
	HAL_SPI_Receive(&hspi1,u8_SPI1_RxBuff,sizeofBuff,100);
	HAL_Delay(1000);
	hal_status = HAL_SPI_Receive_IT(&hspi2, u8_SPI2_RxBuff, sizeofBuff);
	HAL_Delay(1000);
	HAL_SPI_Transmit(&hspi1,u8_SPI1_TxBuff,sizeofBuff,100);
	HAL_Delay(1000);
	HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
  /* USER CODE END 2 */

Am I missing some step with DMA?

答案1

得分: 1

Circular buffer mode是DMA的一个特性,正如你所指出的。当你使用DMA启动传输,并启用了循环缓冲模式,那么传输将会一直运行,除非你手动停止它。因此,根据你的第一个代码示例,对于SPI2,你有以下代码:

HAL_SPI_Transmit_DMA(&hspi2, u8_SPI2_TxBuff, sizeofBuff);
HAL_SPI_Receive_DMA(&hspi2, u8_SPI2_RxBuff, sizeofBuff); // HAL BUSY

HAL返回HAL_BUSY是因为你的DMA传输没有停止,它只是在缓冲区周围循环。你需要使用HAL_SPI_DMAStop()首先停止它。

你的第二个代码示例之所以工作(或者至少没有报告HAL_BUSY)是因为基于中断的传输和接收例程没有实现循环缓冲区。它们只是发送(或接收)一次缓冲区,然后停止。

英文:

Circular buffer mode is a feature of the DMA as you noted. When you start your transmit with DMA, with circular buffer mode enabled, then the transmit will run forever unless you manually stop it. Therefore, from your first code sample, for SPI2, you have this:

HAL_SPI_Transmit_DMA(&hspi2, u8_SPI2_TxBuff, sizeofBuff);
HAL_SPI_Receive_DMA(&hspi2, u8_SPI2_RxBuff, sizeofBuff); // HAL BUSY

The HAL is returning HAL_BUSY because your DMA transmit has not stopped. It is just looping around and around your buffer. You would need to first stop it with HAL_SPI_DMAStop().

The reason your second code sample works (or at least doesn't report HAL_BUSY) is that the interrupt driven transmit and receive routines don't implement a circular buffer. They just send (or receive) the buffer once, and then stop.

huangapple
  • 本文由 发表于 2023年7月4日 23:08:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613920.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定