hal库开启DMA终端
时间: 2023-06-29 12:06:36 浏览: 174
在HAL库中,要使用DMA来传输数据,需要使用以下步骤:
1. 配置DMA控制器:配置DMA控制器的通道、传输方向、数据宽度、传输模式等参数。
2. 配置DMA传输完成中断:在DMA传输完成后,可以通过中断来通知CPU,从而进行后续的处理。需要在NVIC中开启DMA传输完成中断。
3. 配置DMA请求源:DMA传输需要一个请求源,可以是外设的数据寄存器或者是软件触发。需要根据具体情况选择合适的DMA请求源。
4. 初始化DMA:使用HAL_DMA_Init()函数初始化DMA。
5. 启动DMA传输:使用HAL_DMA_Start_IT()函数启动DMA传输,并在中断处理函数中进行数据处理。
下面是一个使用DMA传输USART数据的例子,仅供参考:
```c
/* 配置USART1使用DMA传输 */
uint8_t usart_rx_buf[BUF_SIZE];
uint8_t usart_tx_buf[BUF_SIZE];
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}
void MX_USART1_UART_Init(void)
{
/* USART1 parameter configuration */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* Enable DMA1 clock */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA1 Channel5 USART1_RX initialization */
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
/* DMA1 Channel4 USART1_TX initialization */
hdma_usart1_tx.Instance = DMA1_Channel4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
/* Link DMA_RX handle to USART1_RX */
__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
/* Link DMA_TX handle to USART1_TX */
__HAL_LINKDMA(&huart1, hdmatx, hdma_usart1_tx);
/* Enable DMA1 Channel5 USART1_RX */
HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&huart1.Instance->DR, (uint32_t)usart_rx_buf, BUF_SIZE);
/* Enable DMA1 Channel4 USART1_TX */
HAL_DMA_Start_IT(&hdma_usart1_tx, (uint32_t)usart_tx_buf, (uint32_t)&huart1.Instance->DR, BUF_SIZE);
/* Enable USART1 DMA TX request */
SET_BIT(huart1.Instance->CR3, USART_CR3_DMAT);
/* Enable USART1 DMA RX request */
SET_BIT(huart1.Instance->CR3, USART_CR3_DMAR);
}
/* USART1 DMA RX interrupt service routine */
void DMA1_Channel5_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_usart1_rx);
}
/* USART1 DMA TX interrupt service routine */
void DMA1_Channel4_IRQHandler(void)
{
HAL_DMA_IRQHandler(&hdma_usart1_tx);
}
/* USART1 interrupt service routine */
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
/* USART1 error interrupt service routine */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
/* Disable DMA */
HAL_DMA_Abort(&hdma_usart1_rx);
HAL_DMA_Abort(&hdma_usart1_tx);
/* Disable USART */
__HAL_UART_DISABLE(huart);
/* Clear error flags */
__HAL_UART_CLEAR_OREFLAG(huart);
__HAL_UART_CLEAR_NEFLAG(huart);
__HAL_UART_CLEAR_FEFLAG(huart);
__HAL_UART_CLEAR_PEFLAG(huart);
/* Enable USART */
__HAL_UART_ENABLE(huart);
/* Enable DMA */
HAL_DMA_Start_IT(&hdma_usart1_rx, (uint32_t)&huart->Instance->DR, (uint32_t)usart_rx_buf, BUF_SIZE);
HAL_DMA_Start_IT(&hdma_usart1_tx, (uint32_t)usart_tx_buf, (uint32_t)&huart->Instance->DR, BUF_SIZE);
/* Enable USART DMA TX request */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable USART DMA RX request */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
}
```
在上述代码中,使用DMA传输USART数据的关键步骤是:
1. 使用HAL_DMA_Init()函数初始化DMA控制器。
2. 使用HAL_DMA_Start_IT()函数启动DMA传输,并在中断处理函数中进行数据处理。
3. 使用__HAL_LINKDMA()宏将DMA句柄与USART句柄关联起来。
4. 使用SET_BIT()宏使能USART的DMA传输请求。
阅读全文