空闲中断会在收到一个字节后指定时间内未收到下一个字节时产生,这样的话就可以在产生空闲中断时将收到的数据读走,而不会一直被缓存着,实现代码如下(在使能DMA接收的前提下):
- /* 初始化时使能空闲中断 */
- __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_IDLE);
- /* 串口中断处理函数中增加对空闲中断的处理 */
- void USART_IRQHandler(void)
- {
- uint32_t tmp = 0;
- if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_IDLE))
- {
- /* 清空闲中断标志位 */
- __HAL_UART_CLEAR_IDLEFLAG(&UartHandle);
- /* 停止DMA接收 */
- HAL_UART_DMAStop(&UartHandle);
- /* 得到已接收数据长度 */
- tmp = UartHandle.RxXferSize - __HAL_DMA_GET_COUNTER(UartHandle.hdmarx);
- if(0 != tmp)
- {
- /* 存入数据到fifo */
- }
- /* 再次开启DMA接收 */
- HAL_UART_Receive_DMA(&UartHandle, UartHandle.pRxBuffPtr, UartHandle.RxXferSize);
- }
- HAL_UART_IRQHandler(&UartHandle);
- }
理论上来说这样的话只要接收缓冲足够大,写入fifo的操作只会发生在产生空闲中断时,应该会大大缓解丢包的情况,但实际测试效果却不明显,并没有很好的处理突发数据的接收。
分析原因应该是由于DMA接收是不受控的,在处理空闲中断时短暂关闭了DMA的接收,而就是在这个关闭的过程中如果有新数据到来,则只能丢弃(并且会丢弃前面已接收的一部分数据),从而产生丢包。
|