STM32F412RET6使用DMA收发数据程序
时间: 2024-05-05 13:19:59 浏览: 119
以下是使用DMA收发数据的示例程序,包括了初始化、发送和接收的函数实现。
首先,需要初始化USART和DMA:
```c
void USART_DMA_Init(void)
{
DMA_HandleTypeDef hdma_usart_tx;
DMA_HandleTypeDef hdma_usart_rx;
// Enable DMA2 clock
__HAL_RCC_DMA2_CLK_ENABLE();
// Enable USART1 clock
__HAL_RCC_USART1_CLK_ENABLE();
// Configure DMA for USART1 TX
hdma_usart_tx.Instance = DMA2_Stream7;
hdma_usart_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart_tx.Init.Mode = DMA_NORMAL;
hdma_usart_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart_tx);
// Associate the initialized DMA handle to the USART handle
__HAL_LINKDMA(&huart1, hdmatx, hdma_usart_tx);
// Configure DMA for USART1 RX
hdma_usart_rx.Instance = DMA2_Stream2;
hdma_usart_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_usart_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart_rx);
// Associate the initialized DMA handle to the USART handle
__HAL_LINKDMA(&huart1, hdmarx, hdma_usart_rx);
// Enable DMA transfer complete interrupt
__HAL_DMA_ENABLE_IT(&hdma_usart_rx, DMA_IT_TC);
// Enable USART1 global interrupt
HAL_NVIC_SetPriority(USART1_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
```
然后,需要实现发送函数:
```c
void USART_DMA_Send(uint8_t *pData, uint16_t Size)
{
// Wait for DMA TX buffer to be ready
while (HAL_DMA_GetState(huart1.hdmatx) != HAL_DMA_STATE_READY);
// Disable DMA TX stream transfer
__HAL_DMA_DISABLE(huart1.hdmatx);
// Configure DMA TX stream transfer
HAL_DMA_Start_IT(huart1.hdmatx, (uint32_t)pData, (uint32_t)&huart1.Instance->DR, Size);
// Enable DMA TX stream transfer
__HAL_DMA_ENABLE(huart1.hdmatx);
}
```
最后,需要实现接收函数:
```c
void USART_DMA_Receive(uint8_t *pData, uint16_t Size)
{
// Wait for DMA RX buffer to be ready
while (HAL_DMA_GetState(huart1.hdmarx) != HAL_DMA_STATE_READY);
// Disable DMA RX stream transfer
__HAL_DMA_DISABLE(huart1.hdmarx);
// Configure DMA RX stream transfer
HAL_DMA_Start_IT(huart1.hdmarx, (uint32_t)&huart1.Instance->DR, (uint32_t)pData, Size);
// Enable DMA RX stream transfer
__HAL_DMA_ENABLE(huart1.hdmarx);
// Enable USART1
HAL_UART_Receive_IT(&huart1, pData, Size);
}
```
以上就是使用DMA收发数据的示例程序。需要注意的是,我们使用了循环DMA模式来接收数据,并启用了DMA传输完成中断。这样可以保证在接收到指定长度的数据后,及时通知CPU进行处理。同时,在发送数据时,我们需要等待DMA传输完成后再进行下一次传输。
阅读全文