STM32F401用配置串口2的dma,并用串口dma发送数据给上位机,请只用c语言标准库详细编写相关代码
时间: 2023-11-22 20:56:53 浏览: 50
以下是使用STM32F401的标准库配置串口2的DMA发送数据的代码:
```c
#include "stm32f4xx.h"
#include <string.h>
#define BUFFER_SIZE 50
char buffer[BUFFER_SIZE] = "Hello, world!\r\n"; // 发送的数据
uint8_t dma_tx_complete = 0; // DMA传输完成标志位
void DMA1_Stream6_IRQHandler(void)
{
if ((DMA1->HISR & DMA_HISR_TCIF6) != 0) // 判断是否传输完成
{
dma_tx_complete = 1;
DMA1->HIFCR |= DMA_HIFCR_CTCIF6; // 清除传输完成标志位
}
}
void USART2_DMA_Init(void)
{
/* 使能DMA1时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
/* 配置DMA1 Stream6,用于USART2 TX */
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)buffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = strlen(buffer);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream6, &DMA_InitStruct);
/* 配置串口2 */
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx;
USART_Init(USART2, &USART_InitStruct);
USART_Cmd(USART2, ENABLE);
/* 配置USART2 DMA传输 */
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
/* 配置DMA1 Stream6中断 */
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = DMA1_Stream6_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
/* 启动DMA传输 */
DMA_Cmd(DMA1_Stream6, ENABLE);
}
int main(void)
{
/* 初始化串口2和DMA */
USART2_DMA_Init();
while (1)
{
if (dma_tx_complete)
{
dma_tx_complete = 0;
/* 发送完成后进行其他操作 */
}
}
}
```
以上代码中,我们首先定义一个缓冲区 `buffer`,用于存储要发送的数据。然后在 `USART2_DMA_Init` 函数中,我们依次进行以下操作:
1. 使能DMA1时钟
2. 配置DMA1 Stream6,用于USART2 TX。注意,我们将 `DMA_Mode` 设置为 `DMA_Mode_Normal`,表示只传输一次数据,传输完成后自动停止。
3. 配置串口2,将其设置为仅发送数据。
4. 配置USART2 DMA传输,使USART2能够使用DMA发送数据。
5. 配置DMA1 Stream6中断,以便在DMA传输完成后进行相应操作。
6. 启动DMA传输。
在主循环中,我们等待DMA传输完成标志位 `dma_tx_complete` 被置位,表示数据发送完成。发送完成后,我们可以执行其他操作。需要注意的是,如果 `DMA_Mode` 被设置为 `DMA_Mode_Circular`,则DMA传输将一直循环进行,此时需要在合适的时机停止DMA传输。