该UART->RDR
寄存器没有缓冲区,它只保存最后一个完全接收到的字节。如果接收到另一个字节,它将被覆盖。
您应该确保RDR
每次在一个字节到达之后和接收到下一个字节之前读取 in 的值。有3种基本方法可以做到这一点。
RXNE
定期检查标志,并在设置时RDR
准确读取一次。重复直到你有整个数据包。读取一个字节RDR
清除RXNE
标志,等到它再次设置,然后再读取下一个字节。
置RXNEIE
位 inCR1
并启用对应于 UART in 的中断NVIC
。每次接收到一个字节时都会调用中断处理程序。处理程序一开始可以非常简单,只需将其读取RDR
并存储在缓冲区中即可。稍后您可以添加错误检查和恢复。不要忘记将中断处理程序接触的每个变量声明为volatile
.
首先设置DMA通道(默认USART1
映射到DMA1_Channel3
,可以重新映射,其他查看参考手册):
DMA1_Channel3->CPAR = (uint32_t)&USART1->RDR;
DMA1_Channel3->CMAR = (uint32_t)rxd; // start of receive array
DMA1_Channel3->CNDTR = 8; // 8 bytes to receive
DMA1_Channel3->CCR = DMA_CCR_MINC | DMA_CCR_EN; // Memory increment, enable
然后设置串口,并启用 DMA 接收USART1->CR3
。传输结束在DMA1->ISR
寄存器中发出信号,您可以在主程序中定期检查它,或者在DMA1_Channel3->CCR
( 和NVIC
) 中启用中断。您应该通过 清除中断标志DMA1->IFCR
,否则启用时您将获得无穷无尽的中断。要开始另一次传输,请CNDTR
再次设置寄存器。将 DMA 或中断处理程序触及的所有变量声明为volatile
.