你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
mariawin 提问时间:2014-12-4 11:48 /
大家好!
首次使用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);
  // 将数据放入缓冲区队列中
  // ....  
}
}

// UART4的DMA发送中断入口
void DMA1_Stream4_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_Stream4, DMA_IT_TCIF4) == SET )
{
  //DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
  DMA_Cmd(DMA1_Stream4, ENABLE);
  DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4);
  TestIO();  
  DMA_Cmd(DMA1_Stream4, ENABLE);
}
}


收藏 评论5 发布时间:2014-12-4 11:48

举报

5个回答
mariawin 回答时间:2014-12-4 14:54:15
将上述初始化功能复用到USART1,USART1可以实现数据的接收与发送。
莫非UART4不能使用DMA发送?

mariawin 回答时间:2014-12-4 16:53:41
本帖最后由 mariawin 于 2014-12-4 16:54 编辑

已解决。
该问题是由于IO口初始化造成的,将IO口初始变更为如下情况,就可以解决:

// 串口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_Init(GPIOC, &GPIO_InitStructure);
        
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);        
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);

F103 上合起来初始化也是可以的,F407的USART1合起来也可以,但不知道为什么这个不行。
为了防止类似情况发生,以后还是一步步来吧。
霹雳之火 回答时间:2014-12-4 22:25:28
解决了就好
回答时间:2014-12-5 15:55:53
楼主把发送和接收的IO设置一样了。IO接收的要设置为输入,发送的要设置为输出。
愛不孤单 回答时间:2016-2-22 11:21:52
安 发表于 2014-12-5 15:55
楼主把发送和接收的IO设置一样了。IO接收的要设置为输入,发送的要设置为输出。 ...

楼主用的407的,设置方法和103的有点区别,你可以试试407

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版