串口通信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代表寄存器里是否开启8或者16倍采样的寄存器值。 OVER8=0表示 x16采样,OVER8=1表示 x8采样
对于GD32这种,带入进去算出来,就是8或者16
期望中的分频系数:
此时熟悉的公式就出来了: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%)
实际分频系数:
根据上面算出的带小数点的分频系数,要转换到寄存器里。需把整数部分和小数部分分开。
小数部分*16,然后四舍五入,填入到小数部分的位中,如果超过16要进位到整数部分。
整数部分,则直接转换成16进制。
两部分用 " | "拼起来,就是USART_BAUD 寄存器的值了。
下面是我们的换算过程
正常PCLK= 36.00 MHz设备 USARTDIV = 9.765625 ≈ 9.77
寄存器配置USART_BAUD = 0x9 | 0xC (0.77*16 = 12.32 ≈ 12 ) = 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%,则无需担心晶振引起的误差。
串口通信USART的波特率误差计算GD32、STM32相关推荐
- 单片机c语言波特率检测,基于MSP430系列微控制器串口通信时的波特率自动检测的实现...
通常微控制器通过串行接口与其它终端进行通信时,两个终端需要通讯波特率一致才能达到准确与可靠的通讯效果,串行波特率的自动检测(ABR)可以解决通信终端的波特率自动匹配问题,从而实现微控制器与PC或其它主 ...
- Proteus模拟STM32F103R6微控制器之串口通信USART的方法
Proteus模拟STM32F103R6微控制器之串口通信USART的方法,实验环境如下: 模拟软件:Proteus 8.11 SP0 开发环境:Keil MDK 5.33 参考资料:ST公司官方参考 ...
- 51单片机串口通信,及波特率计算
文章目录 串口基本认识 RS-232-C.RS-422与RS-485 关于串口的电平 串口通信 SCON SBUF:串行数据缓冲器 PCON IE 波特率计算 什么是波特率 实例计算 常用波特率及初值 ...
- STM32最小核心板F103串口通信USART
文章目录 一.串口协议和RS-232标准,RS232电平与TTL电平的区别,"USB/TTL转232"模块的工作原理 1.串口协议 2.RS-232标准 3.RS232电平与TTL ...
- 搭建机器人电控系统——通信协议——串口通信USART/UART、RS232、RS485及其实例
通信协议 串口通信详解 IIC通信详解 SPI通信详解 CAN通信详解 文章目录 通信协议 什么是串口? 串口分类 USART/UART.RS232.RS485的区别 串口协议原理 传输协议 需要定义 ...
- STM32串口通信USART练习
文章目录 一.STM32的USART介绍 二.USART串口通信实践 1.任务要求 2.所用器材 3.主要代码 4.代码解析 三.效果展示 四.总结 五.参考资料 一.STM32的USART介绍 通用 ...
- STC12C5A60S2串口通信(使用独立波特率发生器)
快速导航 STC12已封装好的函数库 使用STC12C5A60S2做串口通信波特率初始化可以使用STC-ISP波特率计算器自动生成 本Demo使用STC12独立波特率发生器,晶振11.0592,波特率 ...
- 九、【中级篇】串口通信(USART、IIC)、读取EEPROM
串行接口 1.串口简介 串口的工作模式 串口与并口的区别 不同电平标准的串口 开发板上的串口 2.USART/UART简介 USART/UART的配置 初始化USART1 发送与接收数据 3.串口解析 ...
- STM32串口通信-USART全面讲解
通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个全双工的串行通信设备:UART(Universal A ...
- STM32F767串口通信------USART中断接收
1.基础配置 点击右边NVIC 将USART3 全局中断优先级改为1. 点击右上角生成代码. 2.编写代码 由CubeMX提供IRQhandler函数,需要自己写callback函数,查询手册. 简单 ...
最新文章
- MySQL库目录下db.opt文件的作用
- php js统计链接点击次数,JS实现在线统计一个页面内鼠标点击次数的方法
- 封装方法公共文件common.js
- 提高 Java 代码质量
- eclipse 打开时候,弹出来 JVM terminated Exit code=2
- boost::hana::is_a用法的测试程序
- 自动生成存储过程的脚本
- Oracle精简客户端配置
- python 开发板 i2s_[Craftor原创] I2S总线接口设计(Verilog)
- 文档安全管理系统服务器地址是什么,一种文档安全管理系统登录方法及装置
- spark学习-31-spark2.2.0中Utils.getCallSite()的作用
- proguard 反编译_Android Studio项目结构,编译器,ProGuard
- MFC浮动窗口使用方法和注意事项
- oracle11g数据库登录01017,【数据库管理】ORA-01017错误及部分的常见典型案例-Go语言中文社区...
- java stream list转map
- int 、long 和long long 区别
- win10系统迁移到新的硬盘
- 【Steam VR 2.0】自定义按键 action 发布后无效的解决办法
- 服务器如何防止被攻击
- python登录系统账号检测_使用Python脚本检测邮件账户密码是否被泄漏,提高你的账户安全性...