现象:使用CubeMX多次Generate Code发现串口初始化出现问题,DMA的CR寄存器除了中断位和使能位其他配置未能写入。调试时发现似乎写入寄存器CR时无效。此问题在仿真情况下不会发生
原因:在先配置UART后Generate Code回头再修改DMA配置,第二次Generate Code后会出现该问题。MX_DMA_Init()初始化函数中负责启动DMA2的时钟,而UART初始化里面也包含了部分DMA2的初始化配置。观察例程可判断正确顺序应该是先MX_DMA_Init()再MX_USART1_UART_Init(),但是在这种情况下,CubeMX的MX_USART1_UART_Init()和MX_DMA_Init()的顺序就会按照Generate Code的顺序。个人推测根本原因应该是在这种顺序下,DMA的时钟未启动而提前写入配置导致配置丢失。参见这篇文章。
解决方案:一定可行的办法是一次配置重建整个项目。在不推倒重来的前提下,可以在CubeMX中取消勾选UART和DMA,然后Generate Code,再按照原先配置勾选UART和DMA然后再Generate Code即可。或者暴力修改.ioc文件中的ProjectManager.functionlistsort,调换UART和DMA的顺序。在Project Manager下的Advanced Setting里面可以看到顺序。