首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环模式下关于spi传输数据量的stm32F1 dma

循环模式下关于spi传输数据量的stm32F1 dma
EN

Stack Overflow用户
提问于 2018-06-16 10:34:16
回答 2查看 1.4K关注 0票数 0

我目前正在学习STM32F1xx使用DMA和SPI循环模式。我的目标是让STM32F1重复发送相同的数据。

我使用HAL_SPI_Transmit_DMA()生成的代码,以循环模式设置SPI,并使用cubeMX激活DMA传输。

我有一个数据缓冲区如下所示:

代码语言:javascript
复制
char dataBuf[10] = {'a','b','c','d','e','f','g','h','i','j'};

当我使用HAL_SPI_Transmit_DMA(&hspir1,dataBuf,10)时,它工作得很好。HAL_SPI_DMAStop(&hspi1);通过SPI反复发送字符,我可以使用STM32F1来阻止它。

但是,如果我只想重复发送dataBuf的5字节,使用HAL_SPI_Transmit_DMA(&hspir1,dataBuf,5),STM32就不能对此做出反应。它只是挂在某处却什么也不做。

我想知道为什么会这样。数据量是否需要与声明的缓冲区数组大小相同(实际上,这对我来说毫无意义)?如何使用循环模式发送所需的数据量?

Update1

我应该附加我的SPI和DMA设置,他们在这里。

SPI设置:

代码语言:javascript
复制
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
  _Error_Handler(__FILE__, __LINE__);
}

DMA设置:

代码语言:javascript
复制
hdma_spi1_tx.Instance = DMA1_Channel3;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
{
  _Error_Handler(__FILE__, __LINE__);
}

Update2

这是我使用代码进行的测试设置:

代码语言:javascript
复制
char spiDataBuf[10] = {'a','b','c','d','e','f','g','h','i','j'};
uint8_t runSPI = 0;

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
  //HAL_Delay(500);
  if(HAL_GetTick()-lastTick > 1)
  {
      //calColor2Data(&statusColor, 1);
      //updateWs2812();
      if(runSPI)
      {
          HAL_SPI_Transmit_DMA(&hspi1,spiDataBuf,5); 
          // or HAL_SPI_Transmit_DMA(&hspi1,spiDataBuf,10);
          runSPI = 0;
      }
      else
      {
          runSPI = 1;
          HAL_SPI_DMAStop(&hspi1);
      }

      lastTick = HAL_GetTick();
  }



/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

和逻辑输出:当我设置10个字节发送,它工作良好,STM32发送A.B.C.重复并按预期暂停。逻辑捕捉,请看下面的图片。

发送10个字节-概述

发送10个字节-结果

但是当我发送5个字节时,它似乎不能被stopped..Logic捕获--请看下面的图片。

发送5个字节-概述,无法停止

发送5字节-结果,但它确实多次发送5字节。

我的问题是,为什么当我将5个字节设置为发送时,DMA不能停止?

我测试了其他字节数。10,9,8字节工作。但是7,6,5,4,3 ,2 ,1字节不起作用。SPI DMA是那些不能停止的情况。

如果需要提供更多的信息,请告诉我。

谢谢。

诚挚的问候。

EN

回答 2

Stack Overflow用户

发布于 2018-06-17 10:01:59

检查你的数据大小。DMA和SPI工作在8位/16/位或32位模式下。我的猜测是,您的SPI期望每传输16位(或设置在16位模式)。然后,DMA发送的第5个字节没有填充SPI的TX缓冲区。这意味着SPI不会传输16位(因为它在等待另一个字节),这意味着TXE标志不会被设置,这意味着它不会从DMA请求下一个字节。

The fix:将SPI设置为8位模式。

票数 0
EN

Stack Overflow用户

发布于 2020-11-03 21:23:48

同样的问题。调试显示它跳过HAL_SPI_TxCpltCallback,但仍在上升HAL_SPI_TxHalfCpltCallback。降低SPI的速度对我有用。hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50887132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档