ll库dma串口发送代码实现
时间: 2023-09-10 20:06:24 浏览: 162
基于HAL库的stm32f103单片机实现DMA+串口的接收、发送数据功能代码
以下是使用ll库实现dma串口发送的示例代码:
```c
#include "stm32f4xx_ll_bus.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_gpio.h"
#include "stm32f4xx_ll_usart.h"
#define USARTx USART1
#define USARTx_CLK_ENABLE() LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1)
#define USARTx_TX_GPIO_CLK_ENABLE() LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA)
#define USARTx_TX_PIN LL_GPIO_PIN_9
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_TX_AF LL_GPIO_AF_7
#define DMAx_CLK_ENABLE() LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2)
#define USARTx_DMAx_CLK_ENABLE() LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2)
#define USARTx_TX_DMA_CHANNEL LL_DMA_CHANNEL_4
#define USARTx_TX_DMA_STREAM LL_DMA_STREAM_4
#define USARTx_TX_DMA_FLAG_TC LL_DMA_FLAG_TC4
#define USARTx_TX_DMA_FLAG_HT LL_DMA_FLAG_HT4
#define USARTx_TX_DMA_FLAG_TE LL_DMA_FLAG_TE4
#define USARTx_TX_DMA_FLAG_DME LL_DMA_FLAG_DME4
#define USARTx_TX_DMA_IRQn DMA2_Stream4_IRQn
#define USARTx_TX_DMA_IRQHandler DMA2_Stream4_IRQHandler
#define TXBUFFERSIZE (COUNTOF(aTxBuffer) - 1)
#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
uint8_t aTxBuffer[] = "DMA USART example\n\r";
__IO uint32_t uwTxIndex = 0;
void Configure_DMA(void)
{
DMAx_CLK_ENABLE();
LL_DMA_SetPeriphRequest(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_REQUEST_4);
LL_DMA_SetMode(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_MODE_NORMAL);
LL_DMA_SetChannelPriorityLevel(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_PRIORITY_LOW);
LL_DMA_SetDataTransferDirection(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
LL_DMA_SetPeriphIncMode(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_PERIPH_NOINCREMENT);
LL_DMA_SetMemoryIncMode(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_MEMORY_INCREMENT);
LL_DMA_SetPeriphSize(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_PDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA2, USARTx_TX_DMA_STREAM, LL_DMA_MDATAALIGN_BYTE);
/* Enable DMA transfer complete/error interrupts */
LL_DMA_EnableIT_TC(DMA2, USARTx_TX_DMA_STREAM);
LL_DMA_EnableIT_TE(DMA2, USARTx_TX_DMA_STREAM);
NVIC_SetPriority(USARTx_TX_DMA_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(USARTx_TX_DMA_IRQn);
}
void Configure_USART(void)
{
LL_USART_InitTypeDef USART_InitStruct;
USARTx_CLK_ENABLE();
USARTx_TX_GPIO_CLK_ENABLE();
LL_GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
LL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
LL_USART_StructInit(&USART_InitStruct);
USART_InitStruct.BaudRate = 115200;
USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
USART_InitStruct.Parity = LL_USART_PARITY_NONE;
USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX;
USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
LL_USART_Init(USARTx, &USART_InitStruct);
LL_USART_EnableDMAReq_TX(USARTx);
LL_USART_Enable(USARTx);
}
int main(void)
{
Configure_DMA();
Configure_USART();
while (1)
{
}
}
void USARTx_TX_DMA_IRQHandler(void)
{
/* Check the DMA transfer complete flag */
if(LL_DMA_IsEnabledIT_TC(USARTx_TX_DMA_STREAM) && LL_DMA_IsActiveFlag_TC4(DMA2))
{
LL_DMA_ClearFlag_TC4(DMA2); /* Clear transfer complete flag */
uwTxIndex++;
if (uwTxIndex == TXBUFFERSIZE)
{
uwTxIndex = 0;
}
LL_DMA_SetMemoryAddress(DMA2, USARTx_TX_DMA_STREAM, (uint32_t)&aTxBuffer[uwTxIndex]);
LL_DMA_SetDataLength(DMA2, USARTx_TX_DMA_STREAM, TXBUFFERSIZE - uwTxIndex);
LL_DMA_EnableStream(DMA2, USARTx_TX_DMA_STREAM); /* Start DMA transmission */
}
/* Check the DMA transfer error flag */
if(LL_DMA_IsEnabledIT_TE(USARTx_TX_DMA_STREAM) && LL_DMA_IsActiveFlag_TE4(DMA2))
{
/* Call Error function */
while (1)
{
}
}
}
```
在上述代码中,首先需要配置串口和DMA,然后在主函数中进入死循环。当串口发送缓冲区为空时,DMA开始传输数据。当DMA传输完成时,会触发中断,将发送缓冲区的指针移动到下一个位置,并继续启动DMA传输。如果DMA传输出错,则进入错误处理函数。
注意,上述代码仅供参考,具体实现可能会因为硬件平台和使用的ll库版本而有所不同。
阅读全文