ST意法半导体
直播中

王平

8年用户 1428经验值
私信 关注
[问答]

HAL库SPI DMA批量传输数据量最大为2^16,有没有办法改成上限为2^32?

HAL库SPI DMA批量传输数据量最大为2^16,有没有办法改成上限为2^32

回帖(2)

邱敏

2025-3-8 10:51:04
实际上传输数量是受到硬件约束,硬件寄存器就是16位的。

如果超过65565后,可以试试使用循环模式。

利用办半完成中断和全部完成中断来做相应的处理。
当然处理的时间要小于一半的时间。
举报

旧念

2025-3-10 17:43:56

在使用STM32的HAL库进行SPI DMA传输时,默认情况下,DMA传输的数据量是受限于DMA传输计数器的位宽。对于STM32的DMA控制器,通常传输计数器的位宽是16位,因此单次DMA传输的最大数据量为2^16(即65536字节)。


如果你希望实现更大的数据传输(例如2^32字节),可以考虑以下几种方法:


1. 分段传输


你可以将大数据传输分成多个小段,每段的数据量不超过2^16字节。在每次DMA传输完成后,通过DMA传输完成中断或回调函数来启动下一段传输。这种方法不需要修改硬件或库,但需要在软件中进行额外的处理。


   #define MAX_DMA_TRANSFER_SIZE 65536

   void SPI_Transmit_DMA_Large(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
   {
       uint32_t remainingSize = Size;
       uint8_t *pCurrentData = pData;

       while (remainingSize > 0)
       {
           uint16_t transferSize = (remainingSize > MAX_DMA_TRANSFER_SIZE) ? MAX_DMA_TRANSFER_SIZE : remainingSize;
           HAL_SPI_Transmit_DMA(hspi, pCurrentData, transferSize);
           pCurrentData += transferSize;
           remainingSize -= transferSize;

           // 等待当前传输完成
           while (HAL_SPI_GetState(hspi) != HAL_SPI_STATE_READY);
       }
   }

2. 使用双缓冲模式


某些STM32系列支持DMA的双缓冲模式。你可以配置两个DMA缓冲区,当一个缓冲区正在传输时,另一个缓冲区可以准备下一批数据。通过这种方式,可以实现连续的大数据传输。


3. 使用硬件特性


某些STM32系列(如STM32F4、STM32F7、STM32H7等)的DMA控制器支持更大的传输计数器位宽(例如32位)。如果你的STM32芯片支持更大的DMA传输计数器,你可以直接配置DMA传输计数器的位宽为32位。


例如,在STM32H7系列中,DMA传输计数器可以配置为32位。你可以通过修改DMA初始化代码来设置更大的传输计数器:



   hdma_spi_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
   hdma_spi_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi_tx.Init.DataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi_tx.Init.Mode = DMA_NORMAL;
   hdma_spi_tx.Init.Priority = DMA_PRIORITY_HIGH;
   hdma_spi_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi_tx.Init.MemBurst = DMA_MBURST_SINGLE;
   hdma_spi
举报

更多回帖

发帖
×
20
完善资料,
赚取积分