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

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管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版