该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.