STM32 总线空闲 + DMA 方式接收

  cheney

    STM32 的 USART 支持一个总线空闲中断,如果这个中断和DMA配合,能够较好的实现接收不定长数据的功能。

    总线空闲中断是在检测到在接收数据后,数据总线上一个字节的时间内,没有再接到数据后发生。也就是RXNE位被置位之后,才开始检测,只被置位一次,除非再次检测到RXNE位被置位,然后才开始检测下一次的总线空闲。

    ##函数

    
    	// 配置串口3
    	void USART3_Init(void)
    	{
    		// 使能PORTB口时钟
    		RCC->APB2ENR |= APB2_IOPB_EN;
    		// 使能串口3时钟                                            
    		RCC->APB1ENR |= APB1_USART3_EN;                                         
    		
    		// IO口模式设置
    		GPIOB->CRH &= 0xFFFF00FF;
    		// IO状态设置
    		GPIOB->CRH |= 0x00008B00;                                               
    		
    		// 复位串口3
    		RCC->APB1RSTR |= APB1_USART3_EN;                                        
    		// 停止复位
    		RCC->APB1RSTR &= ~(APB1_USART3_EN);                                     	 
    		
    		// 波特率
    		USART3->BRR = (ulMantissa << 4) + ulFraction;                           
    		// 收发允许,1位停止,无校验位.
    		USART3->CR1 = (0x200C | ulParity | ulData);                             
    		// 停止位
    		USART3->CR2 |= ulStop;                                                  
    		// 设置DMA
    		DMA_Config(DMA1_Channel2, 1, (ulong)&USART3->DR,(ulong)NULL, 256);      
    		// 发送dma使能
    		USART3->CR3 |= 1 << 7;
    		// 设置DMA                                                  
    		DMA_Config(DMA1_Channel3, 0, (ulong)&USART3->DR,(ulong)NULL, 256);       
    		// 接收dma使能 
    		USART3->CR3 |= 1 << 6;
    		// 开启DMA                                                   
    		DMA_Enable(DMA1_Channel3,(u32)l_ucRecvBuf[2],256);						
    		//
    		USART3->CR1|=1<<8;     //PE中断使能
    		USART3->CR1|=1<<4;     //空闲中断使能
    		NVIC_SetPriority(USART3_IRQn, 0);
    		NVIC_EnableIRQ(USART3_IRQn);
    	} 
    	
    	// 串口3的中断服务函数
    	void USART3_IRQHandler(void)
    	{
    		u8 tmp;
    		u8 len;
    		
    		// 响应空闲中断
    		if( USART3->SR & (1<<4) )
    		{
    			// 清除状态标志
    			tmp = USART3->DR;
    			// 获取本次传输数据长度
    			len = DMA1_Channel3->CNTR;
    			len = 256 - len;
    			// do 
    		}
    	}
    
    

    #得
    无论帧是否等长、无论帧中是否包含长度信息、无论是否包含同步位 都能有较好的效果。

    ##失
    必须保证单个数据帧是连续的发送过来的,发送端最好是DMA控制的。如果帧数据被间隔,将被拆为两个帧。