OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3629|回复: 5

STM32F103ZET6 UART2 DMA 发送数据发不出来

[复制链接]

22

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2013-11-6
在线时间
31 小时
发表于 2020-10-23 11:32:10 | 显示全部楼层 |阅读模式
1金钱

HI

   我想使用STM32F103ZET6 UART2 连接蓝牙串口模块,实现DMA收发数据,目前UART2 DMA接收数据没有问题,但是使用DMA发送数据时,没有异常也不会报错,但是数据没有发出来,以下是UART2 初始化,以及DMA初始化的代码。

bluetooth.c (uart2相关代码)

uint8_t uart2_dma_rx_buf[UART2_TRANSFER_BUFF_SIZE];
uint8_t uart2_dma_tx_buf[UART2_TRANSFER_BUFF_SIZE];
volatile unsigned char BLUETOOTH_DMA_REC_Flag = 0;
void bluetoothInit(u32 baudrate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOG, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
   
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);  
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);

USART_InitStructure.USART_BaudRate = baudrate;
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_Rx | USART_Mode_Tx;

USART_Init(USART2, &USART_InitStructure);
USART_ClearFlag(USART2,USART_FLAG_TC);
USART_ClearFlag(USART2,USART_FLAG_IDLE);

configUsart2Dma();
//Enable
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void)
{
uint32_t len;        
if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
{
  len = UART2_TRANSFER_BUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel6);
  USART_ClearITPendingBit(USART2, USART_IT_IDLE);
  
  (void)USART2->SR;
  (void)USART2->DR;
  BLUETOOTH_DMA_REC_Flag = 1;
  rbWrite(puart1_rb, uart2_dma_rx_buf, len);
  DMA_Cmd(DMA1_Channel6, DISABLE);
  DMA_ClearFlag(DMA1_FLAG_TC6);
  DMA_SetCurrDataCounter(DMA1_Channel6,UART2_TRANSFER_BUFF_SIZE);
  DMA_Cmd(DMA1_Channel6, ENABLE );
}
}
void bluetoothSendData(u8 *buf,u8 len)
{
uint8_t t;
  for(t=0;t<len;t++)
{     
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);   
  USART_SendData(USART2,buf[t]);
}  

while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);  
}

dma.c

volatile uint8_t dma1_is_idle = 1;
void configUsart2Dma(void)
{
DMA_InitTypeDef  DMA_InitStructure;
/* Enable the DMA periph */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* Common DMA configuration */
DMA_InitStructure.DMA_BufferSize = UART2_TRANSFER_BUFF_SIZE;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/* DMA Memory to Peripher */
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)uart2_dma_tx_buf;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);

/* DMA Peripher to Memory */
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)uart2_dma_rx_buf;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);

/* Enable the USART2 Rx and Tx DMA1 requests */
  USART_DMACmd(USART2, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);

DMA_Cmd(DMA1_Channel6, ENABLE);
}
int8_t usingdma_send_frame(DMA_Channel_TypeDef *DMA_Channelx,uint16_t ndtr)
{
if (dma1_is_idle) {
  printf("dma1_is_idle == 1 ndtr = %d\r\n", ndtr);
  dma1_is_idle = 0;
  DMA_SetCurrDataCounter(DMA_Channelx,ndtr);
  DMA_Cmd(DMA_Channelx, ENABLE);
  printf("before while GetFlagStatus\r\n");
  while(!DMA_GetFlagStatus(DMA1_FLAG_TC7));
  printf("after while GetFlagStatus\r\n");
  DMA_ClearFlag(DMA1_FLAG_TC7);
  DMA_Cmd(DMA1_Channel7, DISABLE);
  dma1_is_idle = 1;
  return 0;
} else {
  printf("dma1_is_idle == 0");
  return -1;
}
}

sys.c (NVIC 相关配置)
void NVIC_Configuration(void)
{
NVIC_InitTypeDef   NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//ENABLE UART2 IRQ
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


目前无论使用 usingdma_send_frame 还是 bluetoothSendData 都没法把数据发送出来,但是也不会报报错,请问是哪里有问题,劳烦各位大神帮忙给解决下,不胜感激!

最佳答案

查看完整内容[请看2#楼]

每次发送都应重新配置发送DMA,参考: 代码仓库:https://github.com/Prry/stm32-uart-dma 详细实现:https://acuity.blog.csdn.net/article/details/108367512
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2020-10-23 11:32:11 | 显示全部楼层
回复

使用道具 举报

3

主题

808

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3888
金钱
3888
注册时间
2017-3-7
在线时间
1694 小时
发表于 2020-10-23 16:35:41 | 显示全部楼层
试试用cubemx生成下,看直接用hal的api发送有没有问题
回复

使用道具 举报

22

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2013-11-6
在线时间
31 小时
 楼主| 发表于 2020-10-23 19:26:59 | 显示全部楼层
Acuity 发表于 2020-10-23 12:29
每次发送都应重新配置发送DMA,参考:
代码仓库:https://github.com/Prry/stm32-uart-dma
详细实现:htt ...

参考您的代码,每次发送之前,都重新配置了DMA,现象还是一样,产生了DMA传输完成的中断,我在DMA1_Channel7_IRQHandler里面加了断点,数据传输完成了,但是串口没有数据,奇怪了,还有可能哪里的问题呢?
回复

使用道具 举报

22

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2013-11-6
在线时间
31 小时
 楼主| 发表于 2020-10-23 19:41:01 | 显示全部楼层
a5820736 发表于 2020-10-23 16:35
试试用cubemx生成下,看直接用hal的api发送有没有问题

使用开发板自带的非DMA的发送方式没有问题
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2020-10-24 16:07:01 | 显示全部楼层
axlinux 发表于 2020-10-23 19:26
参考您的代码,每次发送之前,都重新配置了DMA,现象还是一样,产生了DMA传输完成的中断,我在DMA1_Chann ...

这个情况,很大可能性是DMA配置哪里不对,再检查下配置,也没有太多技巧。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 20:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表