STM32F401用标准库配置串口2的dma,并用串口dma发送数据给上位机,请详细编写相关代码
时间: 2023-07-16 19:17:32 浏览: 98
STM32 自定义HID 设备, 通过快传输接收上位机发来的数据。上位机使用Libusb库函数实现,接口简单
5星 · 资源好评率100%
好的,下面是详细的代码实现过程。
首先,我们需要在 CubeMX 中配置串口2和DMA。进入 CubeMX 后,在 Pinout 标签下,选择 USART2,并将其设置为 Alternate Function 模式。然后,在 Configuration 标签下,将 USART2 的 Mode 设置为 Asynchronous,Baud Rate 设置为 115200,Data Bits 设置为 8,Stop Bits 设置为 1,Parity 设置为 None。最后,在 DMA 标签下,选择 DMA1 和 Stream 6,将其设置为 Memory-to-Peripheral 模式,Data Size 设置为 Byte,Priority 设置为 High,Memory Increment Mode 和 Peripheral Increment Mode 均设置为 Enable,以及 Circular Mode 设置为 Disable。
接下来,我们需要在 main.c 文件中添加以下头文件和全局变量:
```c
#include "stm32f4xx_hal.h"
#include "string.h"
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
char tx_buffer[20] = "Hello, world!\r\n";
```
其中,`huart2` 是串口2的句柄,`hdma_usart2_tx` 是串口2的 DMA 发送通道的句柄,`tx_buffer` 是要发送的数据缓存。
然后,在 `main()` 函数中添加以下代码:
```c
/* 初始化 HAL 库 */
HAL_Init();
/* 配置系统时钟 */
SystemClock_Config();
/* 初始化串口2 */
MX_USART2_UART_Init();
/* 初始化 DMA */
MX_DMA_Init();
/* 启动 DMA 传输 */
if (HAL_UART_Transmit_DMA(&huart2, (uint8_t*)tx_buffer, strlen(tx_buffer)) != HAL_OK) {
Error_Handler();
}
/* 进入主循环 */
while (1) {
/* 空操作 */
}
```
在上面的代码中,我们首先初始化了 HAL 库和系统时钟,然后分别调用 `MX_USART2_UART_Init()` 和 `MX_DMA_Init()` 函数初始化串口2和 DMA。接着,我们调用 `HAL_UART_Transmit_DMA()` 函数启动 DMA 传输,将 `tx_buffer` 中的数据发送出去。最后,进入一个无限循环,等待 DMA 传输完成。
最后,我们需要实现 MX_USART2_UART_Init() 和 MX_DMA_Init() 函数。具体代码如下:
```c
void MX_USART2_UART_Init(void) {
/* 配置串口2 GPIO */
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USART2_TX GPIO 配置 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2_RX GPIO 配置 */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 配置串口2 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK) {
Error_Handler();
}
}
void MX_DMA_Init(void) {
/* 配置 DMA 传输句柄 */
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK) {
Error_Handler();
}
/* 将 DMA 传输句柄与串口2的 DMA 发送通道关联 */
__HAL_LINKDMA(&huart2, hdmatx, hdma_usart2_tx);
/* 启动 DMA 中断 */
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
}
```
在上面的代码中,`MX_USART2_UART_Init()` 函数主要是配置串口2的 GPIO 和初始化串口2。其中,我们先调用 `HAL_GPIO_Init()` 函数配置 USART2_TX 和 USART2_RX 的 GPIO,然后使用串口2的句柄 `huart2` 来初始化串口2。
`MX_DMA_Init()` 函数主要是初始化串口2的 DMA 发送通道。其中,我们首先配置了 DMA 传输句柄 `hdma_usart2_tx`,然后使用 `__HAL_LINKDMA()` 宏将其与串口2的 DMA 发送通道关联起来。最后,我们启动了 DMA 中断,以便在 DMA 传输完成时及时处理。
最后,需要实现 DMA1_Stream6_IRQHandler() 函数来处理 DMA 中断。具体代码如下:
```c
void DMA1_Stream6_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_usart2_tx);
}
```
在上面的代码中,我们只是简单地调用 `HAL_DMA_IRQHandler()` 函数处理 DMA 中断。
至此,我们就完成了 STM32F401 用标准库配置串口2的 DMA 并用串口 DMA 发送数据的过程。完整代码如下:
阅读全文