搜索
查看: 736|回复: 1

[求助] USART3 用DMA发送只能发送一次,是什么问题呢?

[复制链接]

该用户从未签到

2

主题

3

帖子

0

蝴蝶豆

新手上路

最后登录
2019-10-5
发表于 2019-5-27 18:22:16 | 显示全部楼层 |阅读模式
单片机STM32F103R8T6,环境IAR8.22
请各位大神帮忙看下:

/*******************************************************************************
* Function Name  : void USART3_Init(u32 baud)
* Description    : 初始化USART2    TXA2  RXA3
* Input          : 无
* Output         : 无
* Return         : 无
*******************************************************************************/
void USART3_Init(u32 baud)
{
  GPIO_InitTypeDef GPIO_InitStructure;   //定义结构体
  USART_InitTypeDef USART_InitStructure; //定义结构体
//  NVIC_InitTypeDef NVIC_InitStruct;
  
  // 第1步:打开GPIO和USART部件的时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);//打开PIOA口的时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //打开UART_3的时钟
  
  // 第2步:将USART Tx的GPIO(PB10)配置为推挽复用模式
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置PB口时钟
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  //第3步:将USART Rx的GPIO配置为浮空输入模式
  //  将USART Rx的GPIO(PB11)配置为浮空输入模式
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置PB口时钟
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  
  //第4步:配置USART参数
  
  USART_InitStructure.USART_BaudRate =baud;  //设置波特率4800、9600、19200、38400、115200
  USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据
  USART_InitStructure.USART_StopBits = USART_StopBits_1;  //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(USART3, &USART_InitStructure);    // 串口3初始化
  
  
  //  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // 开启 USART 接收缓冲区非空中断
  //  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);   // 开启 USART 发送缓冲区空中断
  
  USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);  //开启 USART1 总线空闲中断
  
  
  //第5步:使能 USART, 配置完毕
  USART_Cmd(USART3, ENABLE);  //使能或失能USART
  USART_ClearFlag(USART3, USART_FLAG_TC);     //清除发送完成标志
  USART3_DMA_TxConfig();
}


void USART3_DMA_TxConfig(void)
{
  DMA_InitTypeDef DMA_InitStruct;
  
  /*开启DMA时钟*/
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  
  
  DMA_Cmd(DMA1_Channel2,DISABLE);                                     //close DMA Channel
  
  DMA_DeInit(DMA1_Channel2);  
  
  /*设置DMA源:串口数据寄存器地址*/
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&USART3->DR);    //内存--->外设
  
  /*内存地址(要传输的变量的指针)*/
  DMA_InitStruct.DMA_MemoryBaseAddr = (u32)uart3.sendBuf;
  
  /*方向:从内存到外设*/  
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
  
  /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/
  DMA_InitStruct.DMA_BufferSize = uart3.sendLen;
  
  /*外设地址不增*/     
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  
  /*内存地址自增*/
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
  
  /*外设数据单位*/
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  
  /*内存数据单位 8bit*/
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;  
  
  /*DMA模式:不断循环*/
  DMA_InitStruct.DMA_Mode = DMA_Mode_Normal ;
//  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;  
  
  /*优先级:中*/
  DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;  
  
  /*禁止内存到内存的传输 */
  DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
  
  
  /*配置DMA1的2通道*/     
  DMA_Init(DMA1_Channel2, &DMA_InitStruct);
  
  DMA_ClearFlag(DMA1_FLAG_GL4);  
  
  //DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);  //配置DMA发送完成后产生中断  
  DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);  //open DMA send inttrupt
  /*使能DMA*/
//  DMA_Cmd (DMA1_Channel2,ENABLE);
  
  USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);  
  
}


//下面是调试函数,每500ms调用一次,执行一次发送
int debug = 0;
void USART3_DealRev(void)
{
  static long t=0;
  
  t++;
  if(t>2)
  {
    debug = 2;
    t = 0;
  }
  if(debug == 1)
  {
    for(int i= 0; i<50; i++)
      uart3.sendBuf[i] = i+1;
    uart3.sendLen = 50;
   
    USART3_SendData((unsigned char *)uart3.sendBuf,uart3.sendLen );
    uart3.sendLen = 0;
    debug = 0;
  }
  else if(debug == 2)
  {
    for(int i= 0; i<50; i++)
      uart3.sendBuf[i] = i+1;
    DMA_SetCurrDataCounter(DMA1_Channel2, 50);
    DMA_Cmd (DMA1_Channel2,ENABLE);
    debug = 0;   
  }
}

//中断函数一直不进入
void DMA1_Channel2_IRQHandler(void)
{
  if(DMA_GetITStatus(DMA1_IT_TC1))
  {
    uart3.sendLen = 0;
    DMA_ClearITPendingBit(DMA1_IT_GL1); //清除全部中断标志
    DMA_Cmd(DMA1_Channel2, DISABLE);          //处理完,重开DMA
  }
}





回复

使用道具 举报

该用户从未签到

5

主题

246

帖子

172

蝴蝶豆

金牌会员

最后登录
2021-3-26
发表于 2019-5-27 23:50:34 | 显示全部楼层
DMA_Cmd(DMA1_Channel2, DISABLE);          //处理完,重开DMA
你这是重开?

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-9 20:32 , Processed in 1.170691 second(s), 34 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

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