串口通信USART的波特率误差计算GD32、STM32

UART通信的误差计算:

接收方与发送方频率不准,可能引起累积误差?

晶振时间积累误差

比如发送器和接收器,两边的晶振,发生了最大的相反方向的漂移,内置8MHz晶振误差精度0.5% ,两边累积最大误差达到1%

内置8MHz晶振,实际则为 8 MHz*(+ -1.005) = 7.96MHz~ 8.04MHz 接收方和发送方,晶振都不准,这将对通信产生不确定影响。

下图是两个晶振的误差对比

晶振

频率精度

60s误差

ms误差

us误差

通信误差

通信速度230400bit/s

内部8Mhz

+-5000ppm (0.5%)

60s ±0.3s

1000ms ±5ms

1 000 000 us ± 5000us

4.34us ±0.0217us

外部8MHz

+-30ppm (0.003%)

60s ± 0.0018s

1 000 000 us ± 30us

从上面表格可以看出晶振误差对单片机系统时间的影响。

假设,通信速度230400bit/s , 则发送1bit数据的时间 = 1000000us / 230400bit = 4.34±0.0217us

每发1bit 数据时间消耗为 4.34±0.0217us 误差为±0.5%

可以想象,如果连续发100个bit,误差时间会积累到2.17us!当误差积累到1/2bit的时候,接收器的这个位就错开了。 导致数据偏移 ,发生错误。

不过,我们的UART有开始位,停止位,每10bit数据发完,都会重新从开始位、停止位、来重新检测边沿信号。再确定开始点。

因此这部分的积累误差,没有影响!因为UART的数据帧最多也就是10bit左右

晶振不准导致配置出来产生误差?

如果你知道真实频率就不会,因为可以调节分频值,最后达到标准频率

但,如果你不知道晶振发生了漂移,想当然,仍然使用标准频率进行计算,那就会有较大误差。

我们用最坏的情况做一个假设

在这个设置下 230400bps 8n1

不准的两个晶振( 8MHz ±1% ):

->内置7.92MHz不准晶振的发送设备1

->内置8.08MHz不准晶振的接收设备2

导致不准的外设频率:

发送设备1的外设频率 PCLK1 = PLL1 = (IRC7.92M/2) * 4 = 15.84 MHz

接收设备2的外设频率 PCLK2 = PLL2 = (IRC8.08M/2) * 4 = 16.16 MHz

最多分配频率 : 每1bit数据,能分配的频率数 ( PCLK / 波特率):

发送设备1 每1bit数据最多分配的时钟个数 = 15,840,000 / 230400 = 68.75 Hz/bit

接收设备2 每1bit数据最多分配的时钟个数 = 16,160,000 / 230400 = 70.14 Hz/bit

过采样设置:

由于过采样技术要求,1bit数据最少分配x8个采样时钟!默认一般是x16个采样时钟!

所以上面我们给每bit分配的频率,还要再除上16或者8

除出来这个数(也就是USARTDIV)>1 ,时钟才能完全撑得起这个采样率。

(否则,时钟频率都没那么快,1bit数据怎么采样16次?)

过采样数,也就是手册中常看到的。过采样倍率 =  (8*(2-OVER8)) 

 OVER8寄存器的值 =0表示  x16采样,

OVER8寄存器的值 =1表示  x8采样

对于GD32这种,带入进去算出来,就是x8或者x16倍过采样。

计算期望中的分频系数:

此时熟悉的公式就出来了:USARTDIV = PCLK1 / (波特率*(8*(2-OVER8)) )

正常PCLK= 36.00 MHz设备  USARTDIV = 36,000,000 / ( 230400 *16 ) = 9.765625 (100%)

正常PCLK= 16.00 MHz设备  USARTDIV = 16,000,000 / ( 230400 *16 ) = 4.340278 (100%)

晶振发生偏移的 发送设备1 USARTDIV1 = 15,840,000 / ( 230400 *16 ) = 4.297 (98.9999%)

晶振发生偏移的 接收设备2 USARTDIV2 = 16,160,000 / ( 230400 *16 ) = 4.384 (101.00159%)

只要USARTDIV   >1,则表明MCU的运行频率,可以撑得起来这个采样率。

根据期望的分频系数,再设置USART_BAUD 寄存器 :

根据上面算出的带小数点的分频系数 USARTDIV,需把整数部分和小数部分分开。

小数部分*16,然后四舍五入,取整填入到小数部分的位中。如果这个值超过16要进位到整数部分。

而整数部分,则直接转换成16进制。最后将两部分用 " | "拼起来,就是USART_BAUD  寄存器的值了。

下面是实际的转换过程:

比如:

正常PCLK= 36.00 MHz 的设备算出 USARTDIV = 9.765625  四舍五入下 9.77 

然后把9 和 0.77分别处理。9就是0x9, 0.77先要乘以16 =12.32 取整数=12 ,那么12就是0xC

所以配置寄存器USART_BAUD   =   0x9| 0xC  =0x9C

同理:

正常PCLK= 16.00 MHz设备 USARTDIV = 4.340 ≈ 4.30

配置寄存器USART_BAUD  =    0x4 | 0x5   (0.34*16 = 5.44 ≈ 5 ) = 0x45

晶振发生偏移的 发送设备1 USARTDIV1 = 4.297 ≈ 4.30

寄存器配置USART_BAUD  =    0x4 | 0x5   (0.30*16 = 4.8 ≈ 5 ) = 0x45

晶振发生偏移的 接收设备2 USARTDIV2 = 4.384 ≈ 4.38

寄存器配置USART_BAUD  =    0x4 | 0x6   (0.38*16 = 6.08 ≈ 6 ) = 0x46

根据实际的寄存器设置,这里反算出了,实际中的分频系数

正常PCLK= 36.00 MHz设备 实际USARTDIV = 9 + ( 12/ 16) = 9.75

正常PCLK= 16.00 MHz设备 实际USARTDIV = 4 + ( 5/ 16 ) = 4.3125

发送设备1 实际USARTDIV1 = 4 + ( 5/ 16 ) = 4.3125

接收设备2 实际USARTDIV2 = 4 + ( 6 /16 ) = 4.375

由于:USARTDIV = PCLK / ( 实际波特率*16)

则:实际波特率 = PCLK /( USARTDIV *16)

这样就算出了实际的波特率了。 这样对比标准的波特率,就知道误差了。

编写了一个计算器,有兴趣的朋友可以试试。

GD32、STM32串口波特率计算器USART误差计算器预分频计算器_gd32波特率,stm32串口通信计算器-C文档类资源-CSDN下载编写了一个计算器,有兴趣的朋友可以试试。可以计算串口通信USART、UART的波特率,通信误差,预分gd32波特率更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/weixin_46801290/85256363?spm=1001.2014.3001.5501

PCLK Hz

PCLK MHz

过采样

标准波特率

波特率误差

实际波特率

期望分频系数

实际分频系数

15840000

15.84

16

230400

-0.36%

229565 

4.297 

4.3125

16160000

16.16

16

230400

0.20%

230857 

4.384 

4.375

16000000

16

16

115200

-0.08%

115108 

8.681 

8.6875

16000000

16

16

230400

0.64%

231884 

4.340 

4.3125

16000000

16

16

460800

-0.79%

457143 

2.170 

2.1875

16000000

16

16

921600

2.12%

941176 

1.085 

1.0625

36000000

36

16

230400

0.16%

230769 

9.766 

9.75

72000000

72

16

921600

0.16%

923077 

4.883 

4.875

72000000

72

16

115200

0.00%

115200 

39.063 

39.0625

72000000

72

16

2250000

0.00%

2250000 

2.000 

2

72000000

72

16

230400

0.16%

230769 

19.531 

19.5

72000000

72

16

115200

0.00%

115200 

39.063 

39.0625

8000000

8

16

230400

-0.79%

228571 

2.170 

2.1875

4000000

4

16

115200

-0.79%

114286 

2.170 

2.1875

16MHz的外设频率 ,设置成921600bps 误差2.12%,有点大,但我赌它能勉强通信。

总误差在<2.5% 都可以通讯,但可靠的角度来看误差<1%,甚至更小才好!

这个下面的表,是从官方手册里面截的, 和我上面Excel表格里计算出来的一致。

波特率

PCLK 36MHz

PCLK 72MHz

序号

标准波特率

Kbps

实际波特率

实际分频系数USARTDIV

误差%

实际波特率

实际分频系数USARTDIV

误差%

1

2.4

2.400

937.5

0%

2.4

1875

0%

2

9.6

9.600

234.375

0%

9.6

468.75

0%

3

19.2

19.2

117.1875

0%

19.2

234.375

0%

4

57.6

57.6

39.0625

0%

57.6

78.125

0%

5

115.2

115.384

19.5

0.15%

115.2

39.0625

0%

6

230.4

230.769

9.75

0.16%

230.769

19.5

0.16%

7

460.8

461.538

4.875

0.16%

461.538

9.75

0.16%

8

921.6

923.076

2.4375

0.16%

923.076

4.875

0.16%

9

2250

2250

1

0%

2250

2

0%

10

4500

不可能

不可能

不可能

4500

1

0%

如果晶振频率偏移了1%,并且我们不知道它偏移了,仍然设置正常晶振的值会怎样?

回到最初的问题,以上都是基于,我们知道晶振的具体频率才能准确设置分频的。

但,如果我们误以为晶振是16MHz但它实际上是15.84MHz,或者16.16MHz,它会增加多少差多少呢?

PCLK Hz

PCLK MHz

过采样

标准波特率

波特率误差

实际波特率

期望分频系数

实际分频系数

15840000

15.84

16

230400

-0.36%

229565 

4.297 

4.3125(误以为PCLK =16MHz 所以设置这个值)

16160000

16.16

16

230400

1.65%

234203 

4.384 

4.3125(误以为PCLK =16MHz 所以设置这个值)

16000000

16

16

230400

0.64%

231884 

4.340 

4.3125

看到上表中,误差明显增大了, 1.65 % + 0.36% = 2.01% 总偏差 > 2%了。

所以如果晶振发生了漂移,对通信是有影响的。收发两边的晶振如果频率相差>2%,那就要考虑晶振引起的通信误差问题了。

如果是±0.5%以内的误差是可以接受的, 如果使用稳定的外部晶振,那晶振的误差仅为±0.003%,则无需担心晶振引起的误差。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值