stm32串口采用循环队列+DMA方式接收数据调试总结

最近在项目中给串口的接收添加DMA,遇到的问题:

1、“配置好”DMA后,但是DMA不工作

初始化串口1为接收、DMA1的通道3,并使能相应的外设,外设的时钟也全部打开,但是通过调试发现,DMA就是不传输数据。

问题点:忽视了DMA的请求映像

每个DMA控制器都分管着不同的外设DMA请求,通过查表发现串口1的接收只能映射到DMA1的通道5.因此DMA的通道选择错误。现粘贴串口一的中断处理程序如下:(以下程序并没有采用循环队列的方式接受数据)

static unsigned char APP_ComBuf[100];
unsigned char Receive_Message[100] = {0};
static int APP_iConter = 0;
void USART1_IRQHandler(void)                	
{
	u8 Res,i;
	OS_ERR err;
#ifdef SYSTEM_SUPPORT_OS	 	
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)   
  {
		   
       DMA_Cmd(DMA1_Channel5,DISABLE);    
       APP_iConter=USART1->DR;//
       APP_iConter=USART1->SR;
       APP_iConter=100-DMA_GetCurrDataCounter(DMA1_Channel5);//  
       APP_ComBuf[APP_iConter]=0;//
       DMA1_Channel5->CNDTR=100;//重新设置传输量,这一步是必须的。
			 if(APP_iConter>=6)
			 {
					for(i=0;i<APP_ComBuf[2];i++)
					{
						Receive_Message[i] = APP_ComBuf[i];
					}
				  memset(APP_ComBuf,0,sizeof(APP_ComBuf));					
				  OSTaskQPost((OS_TCB*	)&APPTCB,	
								     (void*		)Receive_Message,
								     (OS_MSG_SIZE)Receive_Message[2],
								     (OS_OPT		)OS_OPT_POST_FIFO,
				             (OS_ERR*	)&err);
			 }
       DMA_Cmd(DMA1_Channel5,ENABLE);  
  }
	 NVIC_Clear(USART1);

#ifdef SYSTEM_SUPPORT_OS	 
	OSIntExit();  											 
#endif
} 	

在设置好DMA的通道后,每收到数据后,使能DMA后,DMA会自动将串口接收到的数据搬运到存储区App_ComBuff中,如果没有DMA1_Channel5->CNDTR=100;这一步,或者该步配置错误,那么每当串口接收到的数据都会向存储区App_ComBuff中存储,App_ComBuff的地址递增。于此同时APP_iConter也在累积,APP_ComBuf[2]也不能被解析到,因为数据随着APP_ComBuf地址的递增,数据都往后存储,帧长度并未存储到APP_ComBuf[2]中,因此自己认为的APP_ComBuf[2]存储的是帧长度,但是APP_ComBuf[2]始终是0。再次理解一下 DMA1_Channel5->CNDTR=100;这句话的必要性,串口采用的是空闲中断接收数据,并非采用的是接收中断,因此当串口处于空闲中断时,这时候已经传输完成了一帧数据。因此,将 DMA1_Channel5->CNDTR=100;便可以在下次空闲中断时,将串口接收数据寄存器中的数据搬运到存储器中的首地址。这样for(i=0;i<APP_ComBuf[2];i++)这个for循环也才可以得以执行。另:DMA通道x的传输数量寄存器DMA_CNDTRx,当这个寄存器的内容为0时,无论通道是否开启,都不会发生任何数据传输。以上是本人通过DMA接收数据的运用的肤浅理解。

关于采用队列的方式接收串口数据,后面继续更新,谢谢。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值