Stm32 HAL_PPP_传输DMA和HAL_PPP_传输IT之间的实际区别是什么?

Stm32 HAL_PPP_传输DMA和HAL_PPP_传输IT之间的实际区别是什么?,stm32,dma,hal,Stm32,Dma,Hal,这两个过程都允许我通过UART传输数据,并在工作完成时调用ISR。因此,在我看来,乍一看他们做了同样的事情。你能解释一下区别是什么吗?即xxx_IT程序是否在内部使用DMA(设备)?你能举一个例子说明xxx\U DMA程序能做什么,xxx\U DMA程序不能做什么,反之亦然(我个人只知道M2M场景)?在什么情况下我应该使用xxx\U DMA而不是xxx\U IT?DMA传输在没有“后台”核心活动的情况下进行传输 每次接收或必须发送字符时,都会调用中断例程。在每个字节的传输或接收过程中,核心都处于

这两个过程都允许我通过UART传输数据,并在工作完成时调用ISR。因此,在我看来,乍一看他们做了同样的事情。你能解释一下区别是什么吗?即xxx_IT程序是否在内部使用DMA(设备)?你能举一个例子说明xxx\U DMA程序能做什么,xxx\U DMA程序不能做什么,反之亦然(我个人只知道M2M场景)?在什么情况下我应该使用xxx\U DMA而不是xxx\U IT?

DMA传输在没有“后台”核心活动的情况下进行传输

每次接收或必须发送字符时,都会调用中断例程。在每个字节的传输或接收过程中,核心都处于忙碌状态


在你的情况下,因为你不知道DMA是什么,这对你来说并不重要。由于DMA传输不会给您带来好处,您应该使用中断传输,因为它更容易设置。

DMA传输在没有“后台”核心活动的情况下进行传输

每次接收或必须发送字符时,都会调用中断例程。在每个字节的传输或接收过程中,核心都处于忙碌状态


在你的情况下,因为你不知道DMA是什么,这对你来说并不重要。由于DMA传输不会给您带来好处,您应该使用中断传输,因为它更容易设置。

DMA在MCU中作为一个单独的单元工作。传输数据和获取数据不需要CPU时间,正如这里提到的P_uj_u。通常在MCU中,dma有助于从各种总线(如UART、SPI)传输数据,也可以从其他模块(如DAC、ADC)传输数据,甚至在这些模块之间传输数据。如果您需要从RAM快速传输大缓冲区,或者从RAM快速传输大缓冲区,那么它非常方便。例如,示波器需要大量的adc样本。每个irq调用可能需要几微秒的时间,因此如果您需要1000个样本,则速度太慢,而且每个irq调用在处理有用数据时会中断MCU作业流。。所以DMA就是解决方案。使用IRQ,你必须自己处理数据,放入缓冲区等,这也是额外的时间。如果你有TX-RX,那么在IRQ需要更多的时间。而DMA只是在后台写入或读取缓冲区。下面是一个小例子:

#define BufferSize 50
uint8_t SPI_Buffer_Rx[BufferSize];
uint8_t SPI_Buffer_Tx[BufferSize];
//configuring  SPI

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_HF);
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_CalculateCRC(SPI2, DISABLE);

// RX and TX DMA configuration
/* SPI_SLAVE_Rx_DMA_Channel configuration ---------------------------------*/
RCC_AHBPeriphClockCmd(SPI_SLAVE_DMA_CLK, ENABLE);
DMA_DeInit(SPI_SLAVE_Rx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI2->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&SPI_Buffer_Rx[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_SLAVE_Rx_DMA_Channel, &DMA_InitStructure);

/* SPI_SLAVE_Tx_DMA_Channel configuration ---------------------------------*/
DMA_DeInit(SPI_SLAVE_Tx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI2->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&SPI_Buffer_Tx[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_SLAVE_Tx_DMA_Channel, &DMA_InitStructure);
不深入讨论细节,您可以看到DMA可以直接处理来自SPI数据寄存器的数据

DMA_InitStructure.DMA_peripheraldbaseaddr=(uint32_t)(&(SPI2->DR))

您还可以在RAM中设置自己的缓冲区。它将通过DMA从SPI RX获取数据

DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)(&SPI_Buffer_Rx[0])

如您所见,与TX和RX相同

此外,您还可以控制大小、类型,例如:FIFO等。这取决于您的情况

当您有更复杂的体系结构或需要快速的数据流、读取和写入时,您肯定应该使用DMA。在ST32中,dma对每个外设都有具体的通道,因此您必须决定哪个外设应该有dma,哪个外设不应该有dma。尤其是当你的固件很复杂时。但通常并不缺少DMA信道。因此,如果您的MCU中有DMA,并且有适度的数据传输。为什么不使用它呢?
通常,MCU会被各种非常方便的功能、模块所束缚。我不明白为什么不使用这些函数?当有许多新的宝贵方法可以使其工作时,为什么任何人都应该只采用旧的已知方法呢?

DMA作为MCU中的一个独立单元工作。传输数据和获取数据不需要CPU时间,正如这里提到的P_uj_u。通常在MCU中,dma有助于从各种总线(如UART、SPI)传输数据,也可以从其他模块(如DAC、ADC)传输数据,甚至在这些模块之间传输数据。如果您需要从RAM快速传输大缓冲区,或者从RAM快速传输大缓冲区,那么它非常方便。例如,示波器需要大量的adc样本。每个irq调用可能需要几微秒的时间,因此如果您需要1000个样本,则速度太慢,而且每个irq调用在处理有用数据时会中断MCU作业流。。所以DMA就是解决方案。使用IRQ,你必须自己处理数据,放入缓冲区等,这也是额外的时间。如果你有TX-RX,那么在IRQ需要更多的时间。而DMA只是在后台写入或读取缓冲区。下面是一个小例子:

#define BufferSize 50
uint8_t SPI_Buffer_Rx[BufferSize];
uint8_t SPI_Buffer_Tx[BufferSize];
//configuring  SPI

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_HF);
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_CalculateCRC(SPI2, DISABLE);

// RX and TX DMA configuration
/* SPI_SLAVE_Rx_DMA_Channel configuration ---------------------------------*/
RCC_AHBPeriphClockCmd(SPI_SLAVE_DMA_CLK, ENABLE);
DMA_DeInit(SPI_SLAVE_Rx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI2->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&SPI_Buffer_Rx[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_SLAVE_Rx_DMA_Channel, &DMA_InitStructure);

/* SPI_SLAVE_Tx_DMA_Channel configuration ---------------------------------*/
DMA_DeInit(SPI_SLAVE_Tx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPI2->DR));
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&SPI_Buffer_Tx[0]);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BufferSize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_SLAVE_Tx_DMA_Channel, &DMA_InitStructure);
不深入讨论细节,您可以看到DMA可以直接处理来自SPI数据寄存器的数据

DMA_InitStructure.DMA_peripheraldbaseaddr=(uint32_t)(&(SPI2->DR))

您还可以在RAM中设置自己的缓冲区。它将通过DMA从SPI RX获取数据

DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)(&SPI_Buffer_Rx[0])

如您所见,与TX和RX相同

此外,您还可以控制大小、类型,例如:FIFO等。这取决于您的情况

当您有更复杂的体系结构或需要快速的数据流、读取和写入时,您肯定应该使用DMA。在ST32中,dma对每个外设都有具体的通道,因此您必须决定哪个外设应该有dma,哪个外设不应该有dma。尤其是当你的固件很复杂时。但通常并不缺少DMA信道。因此,如果您的MCU中有DMA,并且有适度的数据传输。为什么不使用它呢?
通常,MCU会被各种非常方便的功能、模块所束缚。我不明白为什么不使用这些函数?当有很多新的宝贵方法可以让它工作时,为什么任何人都应该只采用旧的、众所周知的方法呢?

你知道DMA是什么吗?你知道DMA是什么吗?