本帖最后由 vt2017 于 2020-11-10 19:12 编辑
最近在做一个小项目,需要移植ST的例程到自己的开发板上,发现串口打印乱码,后来才发现是自己板子的晶振(HSE)频率和例程中提供的有所不同,而导致的。相信不少刚接触串口或者没有系统看过波特率的计算方法的兄弟们都遇到过这个问题,这里就简单分享下自己的经验吧。(讲的不对还请大佬们指点指点)
我这边在用的芯片是雅特力的AT32F403A,宣称是跟103完全兼容的,M4内核,主频更高,成本还低,看了下文档确实跟ST兼容做的比较好(寄存器这些很类似)。以前一直用的都是103,其实主频内核什么的我们一直用103也够用,估计老板主要考虑的还是成本才想要替换这款芯片的,只是苦了我们这些打下手的,(逃~~
所以下面的讲解都是基于AT32F403A or STM32F103 的做法,AT 在串口这部分确实跟 ST 做的兼容性很强。
首先,我们要知道串口的时钟是来自哪里,AT32F403 的 USART1 是由来自 APB1 提供,默认是120MHz;而有时候我们不知道 APB1 时钟频率是多少,此时建议通过 MCO 输出来查看真实的系统时钟(SYSCLK)是多少,并根据 RCC 的分频来推算出 APB1 时钟的频率。这里多说几句,其实很多时候串口配置的波特率和最终输出的波特率不一致,很大概率是系统时钟不匹配导致的。
总之一句话,第一步就是要确认串口时钟频率!我们把它记作:USART_CLK
然后,我们看下图只需要得到USARTDIV这个值即,就不赘述了。
最后,通常来说计算出来的 USARTDIV 这个值是一个小数,所以有点麻烦的是我们还需要将这个值分为整数和分数分别保存到串口寄存器中的。
那我们来举个例子,假设,我们已知的条件是,USART_CLK = 120 MHz,想要串口波特率为 115200 ,那么计算方法如下:
USARTDIV = 120000000/115200/16 = 65.1041666666
我们取小数点后两位来计算,即 65.10,
则写入 USARTDIV 整数值为:65;小数值为2(~ 0.1*16),转换为16进制:0x412,最后将 0x412 写入串口波特率寄存器即可。
注意:以上结果采用的四舍五入的近似计算
所以当我们知道主频和想要配置的波特率时,按照以上计算方法写入串口的波特率寄存器即可。
总结一下:确定串口本身的时钟频率,根据波特率来计算要配置的寄存器值,将寄存器值分为整数和小数,整数直接填入,小数需要乘以16再填入串口波特率寄存器
|