特别想写一篇文章,怕以后忘了这份宝贵的经历和经验。
芯片:LPC2368
目标:支持9600,14400,19200,38400,57600,115200各个波特率通讯。
Fosc:12000000
Fcclk:Fosc*4
Fpclk:Fcclk/4
UART:3
其实,照着网上一般的参数配置方法,RTU模式下,8bit数据位长度,2个停止位,CRC32校验,等等等,程序运行起来之后,就已经能支持9600,14400,19200,38400,57600。就是最后的115200不能支持。
把各个波特率下的结果放在下面:
波特率 DLM+DLL 基数 公式 结果
9600: 78 16 三者相乘 11980800
14400: 52 16 同上 11980800
19200: 39 16 同上 11980800
38400: 19 16 同上 11673600
57600: 13 16 同上 11980800
115200: 6 16 同上 11059200
公式的来源是芯片的说明文档:16*Baud_rate = (UnDLM,UnDLL)*Fpclk (无小数分频,上面数据使用了这个公式)
((MulVal+DivAddVal)/DivAddVal)*16*Baud_rate = (UnDLM,UnDLL)*Fpclk (有小数分频)
可以看到,没有使用小数分频情况下,当波特率是115200时,算得的频率和12000000相差很大。反过来,用12000000除以一些参数获得的波特率于115200也相差很大。其他的其实也相差,不过没这么大,在允许的范围内。
所以现在就需要使用小数分频对这个计算公式进行修正,而计算公式是芯片去执行的,所以可以获得效果。
为了使用小数分频,需要用到UnFDR寄存器。其实我们不用管这个MulVal和DivAddVal具体啥意思,就依照这个公式,像数学求解那样算就行了。这是一个艰难的过程,由网上的经验数据可以得到,当MulVal = 12,DivAddVal = 1的时候,带入公式,算得的频率与12000000相差很小。能实现通讯。
缺点:这么多波特率,要程序自己适应,自己依照实际波特率去进行小数分频修正的话,肯定是需要一个算法的。一个笨办法,就是if语句,因为常用波特率也就这么多,几个if够用了。当然自己可以实现一个算法,输入参数是波特率等等参数,输出参数是Muval,DivAddVal的建议值。设置UnFDR寄存器,大功告成。
一开始看到这个公式:UARTn波特率 <= 最大波特率( (Fpclk/(16*(2+数据位+奇偶位+校验位))) )算得最大支持波特率是57600,我还以为不能支持115200呢,遂在ZLG论坛上提问,结果没人鸟我;又在CSDN嵌入式论坛上提问,但没有获得满意的答案;后又在QQ群里面提问,依然没有人鸟。感慨,还是靠自己啊。其实这个公式是有关什么自适应波特率的。这个可能是另外一个概念,目前没用过,不太清楚。
最大支持波特率计算:其实我猜就是用Fpclk/16就行了,最大只是理论上,可是存在的那个最大必定导致UnDLM,UnDLL有值,也必定小于Fpclk/16,所以,这个Fpclk/16就是所能支持的最大波特率。
谢谢观赏!