在做UART功能之前,必定会面对一个问题, 在我目前的时钟频率下,我应该用何种波特率是最合适的?误码率是最低的。
针对EFM32,UART的过采样可以配制成4, 6, 8, 16次, 而分频系数为15bit,前13bit为整数,后2bit是小数位。总体的计算公式如下:
USARTn_CLKDIV = 256 x ((fHFPERCLK/(oversample x brdesired)) - 1)
USARTn_CLKDIV就是需要写入USART寄存器的值
但是在看USARTn_CLKDIV寄存器的时候,会发现寄存器有效位是从bit6~bit20。 这就是计算公式里有256的原因了。bit6~bit7是小数位。
由于大家选择的时钟源各种各样,而且波特率也各种各样,因此写了一段小代码来计算各种情况下的误码率。
例程:所有的结果请在IAR的Terminal I/O里面查看,或则直接在TermIO.log里查看。(Terminal log的输出,在仿真环境下,Debug-> logging-> Set terminal I/O log file 里面设置)
#include "stdlib.h"
#include "stdio.h"
//const signed long int csFreq[6] = {4.0,7.0,11.0,14.0,21.0,28.0};
float csFreq[7] = {4000000,7000000,11000000,14000000,21000000,28000000,32000000};
unsigned long Oversample[4] = {4, 6, 8, 16};
unsigned long Bandrate = 115200;
void main(void)
{
for(unsigned char j = 0; j < 4; j++)
{
printf("Oversample with %dx \n\r", Oversample[j]);
printf("Frequence DesiredBaudrate Div256 ActualBaudRate Error% \n\r");
for(unsigned char i = 0;i < 7;i++)
{
float Buffer;
float Buffer2;
Buffer = csFreq[i]/Oversample[j];
Buffer = Buffer / Bandrate;
Buffer = Buffer - 1;
signed long long Buffer4 = (signed long long)(Buffer * 1000);
Buffer4 = (Buffer4 + 5) / 10;
signed long long Buffer5;
if(Buffer4 % 25 > 12)
{
Buffer5 = Buffer4;
Buffer5 = Buffer4 % 100;
Buffer5 = (1 + Buffer5/25) * 25;
Buffer4 = Buffer4 - Buffer4 % 100;
Buffer4 = Buffer4 + Buffer5;
}
else
{
Buffer5 = Buffer4;
Buffer5 = Buffer4 % 100;
Buffer5 = (Buffer5/25) * 25;
Buffer4 = Buffer4 - Buffer4 % 100;
Buffer4 = Buffer4 + Buffer5;
}
Buffer = ((float)Buffer4)/100;
printf("%d ",(unsigned long)csFreq[i]);
printf("%d ",Bandrate);
printf("%f ",Buffer);
float Buffer3;
Buffer3 = csFreq[i] / (1 + Buffer) / Oversample[j];
printf("%f ",Buffer3);
Buffer3 = Buffer3 - Bandrate;
Buffer3 = Buffer3 / Bandrate;
printf("%f \n\r",Buffer3*100);
}
}
while(1);
}
输出结果如下:
Oversample with 4x
Frequence DesiredBaudrate Div256 ActualBaudRate Error%
4000000 115200 7.750000 114285.710938 -0.793654
7000000 115200 14.250000 114754.101563 -0.387065
11000000 115200 22.750000 115789.476563 0.511698
14000000 115200 29.500000 114754.101563 -0.387065
21000000 115200 44.500000 115384.617188 0.160258
28000000 115200 59.750000 115226.335938 0.022861
32000000 115200 68.500000 115107.914063 -0.079936
Oversample with 6x
Frequence DesiredBaudrate Div256 ActualBaudRate Error%
4000000 115200 4.750000 115942.031250 0.644124
7000000 115200 9.250000 113821.132813 -1.196933
11000000 115200 15.000000 114583.335938 -0.535299
14000000 115200 19.250000 115226.335938 0.022861
21000000 115200 29.500000 114754.093750 -0.387071
28000000 115200 39.500000 115226.335938 0.022861
32000000 115200 45.250000 115315.312500 0.100098
Oversample with 8x
Frequence DesiredBaudrate Div256 ActualBaudRate Error%
4000000 115200 3.250000 117647.062500 2.124186
7000000 115200 6.500000 116666.664063 1.273146
11000000 115200 11.000000 114583.335938 -0.535299
14000000 115200 14.250000 114754.101563 -0.387065
21000000 115200 21.750000 115384.617188 0.160258
28000000 115200 29.500000 114754.101563 -0.387065
32000000 115200 33.750000 115107.914063 -0.079936
Oversample with 16x
Frequence DesiredBaudrate Div256 ActualBaudRate Error%
4000000 115200 1.250000 111111.109375 -3.549384
7000000 115200 2.750000 116666.664063 1.273146
11000000 115200 5.000000 114583.335938 -0.535299
14000000 115200 6.500000 116666.664063 1.273146
21000000 115200 10.500000 114130.437500 -0.928440
28000000 115200 14.250000 114754.101563 -0.387065
32000000 115200 16.250000 115942.031250 0.644124
以上是特定的115200波特率在各种时钟源下的无码率。可以适当的修改源代码来计算其他情况i下的误码率