打印
[STM32F3]

STM32F407ZG串口4配置为DMA收发但无法发送数据

[复制链接]
1044|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
elephant00|  楼主 | 2024-1-26 10:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好!
首次使用STM32f407芯片,在串口使用过程中,发现如下问题,请各位告诉帮忙解决,谢谢!
目的:串口4使用DMA收发数据
IO口:接收PC11, 发送PC10
问题:使用下列串口初始化,接收和发送的中断都可以正常产生,串口4可以接收数据,但无法发送数据,PC10端口示波器上无法捕捉到数据(发送0xaa数据)
串口配置如下所示:
初始化:
void UART4_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef  DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the UART4 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;   // UART4接收
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;   // UART4发送
NVIC_Init(&NVIC_InitStructure);
// 串口缓冲区初始化
memset(UART4_DMA_Rx, 0xaa, sizeof(UART4_DMA_Rx));
memset(UART4_DMA_Tx, 0xaa, sizeof(UART4_DMA_Tx));

// 时钟配置
/* Peripheral Clock Enable -------------------------------------------------*/
/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC , ENABLE);
/* Enable USART clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
/* Enable the DMA clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

// 串口IO口配置
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10 | GPIO_PinSource11, GPIO_AF_UART4);
// 串口设置
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(UART4, &USART_InitStructure);

DMA_DeInit(DMA1_Stream2);
DMA_DeInit(DMA1_Stream4);
DMA_StructInit(&DMA_InitStructure);
// DMA设置
/* Configure DMA Initialization Structure */
DMA_InitStructure.DMA_BufferSize = UART_DMA_BUF_NUM ;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralBaseAddr =(UINT32) (&(UART4->DR)) ;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/* Configure TX DMA */
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 发送DMA设计为正常模式,需要发送时再开启
DMA_InitStructure.DMA_Channel = DMA_Channel_4 ;
DMA_InitStructure.DMA_DIR =  DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (UINT32)UART4_DMA_Tx;
DMA_Init(DMA1_Stream4, &DMA_InitStructure);
/* Configure RX DMA */
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 接收DMA设计为循环收,否则接收一次后,无法正常接收到数据
DMA_InitStructure.DMA_Channel = DMA_Channel_4 ;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;
DMA_InitStructure.DMA_Memory0BaseAddr =(UINT32)UART4_DMA_Rx;
DMA_Init(DMA1_Stream2,&DMA_InitStructure);
// 使能串口
USART_Cmd(UART4, ENABLE);

/* Enable DMA USART TX Stream */
DMA_Cmd(DMA1_Stream2, ENABLE);  // RX
DMA_Cmd(DMA1_Stream4, ENABLE);  // TX

USART_DMACmd(UART4,USART_DMAReq_Tx,ENABLE);
USART_DMACmd(UART4,USART_DMAReq_Rx,ENABLE);
// 使能DMA中断
DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE);       //使能DMA1通道2发送完成中断
DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);       //使能DMA1通道4传输完成中断
}

中断函数:
// UART4的DMA接收中断入口
void DMA1_Stream2_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_Stream2, DMA_IT_TCIF2) == SET )
{
   //DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_TCIF2);
   DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2);
   DMA_Cmd(DMA1_Stream2, ENABLE);
  // 将数据放入缓冲区队列中
  // ....  
}
}

使用特权

评论回复
沙发
两只袜子| | 2024-1-29 16:29 | 只看该作者
检查DMA的源和目标地址是否正确设置

使用特权

评论回复
板凳
jcky001| | 2024-1-29 16:30 | 只看该作者
时钟或者中断配置有问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

968

主题

2962

帖子

7

粉丝