UART 空闲中断+DMA接收流程

在项目中利用UART空闲中断接收外部信号,利用DMA接收,实现外部到内存的传输。通过分析其它文章的代码,大概如下:

  /* 配置 DMA Stream */
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{ 
  DMA_InitStructure.DMA_Channel = chx;  //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = par;//DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = mar;//DMA 存储器地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到存储器模式
  DMA_InitStructure.DMA_BufferSize = ndtr;//数据传输量 
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式 
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);//初始化DMA Stream
  DMA_Cmd(DMA_Streamx, ENABLE);                      //开启DMA传输 
}
  /* 配置 UART IDEAL */
void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
	u8 clear;
	u8 a=0;
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //
	{
		Res = 1;									//Event mask
		clear= USART1->DR;				//remove the mask of ideal
		clear=USART1->SR;
		USART_ClearITPendingBit(USART1,USART_IT_IDLE);//
		num= SEND_BUF_SIZE-DMA_GetCurrDataCounter(DMA2_Stream5);//get the num of transfer
		a=SEND_BUF_SIZE-DMA_GetCurrDataCounter(DMA2_Stream5);
		printf("the num of transfer = %d",a);
		a=0;
		DMA_Cmd(DMA2_Stream5, DISABLE); 
	}

其中,去除空闲中断标志:

		clear= USART1->DR;
		clear=USART1->SR;
		USART_ClearITPendingBit(USART1,USART_IT_IDLE);
主函数的部分函数
内容:将DMA接收到内存的信息通过串口发送
	while(1)
	{
		if(Res==1)
		{
			LED1=!LED1;
			Res=0;
			for(j=0;j<20;j++)
			{
				USART_SendData(USART1,SendBuff[j]);
				while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=SET){};
			} 
			for(j=0;j<20;j++)
			{
			SendBuff[j]=33;
			}
			MYDMA_Enable(DMA2_Stream5 ,SEND_BUF_SIZE);			
		}  
	}

问题:三次接收信息如下,可以发现DMA只进行了一次传输,后续传输量为0,无信息传输
在这里插入图片描述将USART1_IRQHandler函数中断的 DMA_Cmd(DMA2_Stream5, DISABLE); 和主函数中的MYDMA_Enable(DMA2_Stream5 ,SEND_BUF_SIZE); 注释掉,程序运行结果如下(第二行):
在这里插入图片描述分析:DMA不进行关闭和开启处理,能够正常进行依次传输,个人分析可能是因为 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式 ,此次为单次传输,传输量达到ndtr或者关闭DMA传输,都意味着此次传输完成,即使在开启也没用。
解决方案:DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;改成:DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;运行结果如下(第三行)
在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值