当前位置:首页 > 公众号精选 > 嵌入式微处理器
[导读]平时使用串口打印出现乱码的,绝大部分原因是串口波特率没对。那么,我们怎么测量实际的波特率呢?在这之前,顺便一起回顾一下波特率的概念。什么是波特率、比特率?比特率(Bitrate)表示每秒钟传输的二进制位数,单位为比特每秒(bit/s)。波特率(Baudrate)表示每秒钟传送的码...

平时使用串口打印出现乱码的,绝大部分原因是串口波特率没对。那么,我们怎么测量实际的波特率呢?在这之前,顺便一起回顾一下波特率的概念。

什么是波特率、比特率?

  • 比特率(Bitrate)表示每秒钟传输的二进制位数,单位为比特每秒(bit/s)。

  • 波特率(Baudrate)表示每秒钟传送的码元符号的个数,是衡量数据传送速率的指标。

  • 码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。


常见的通讯传输中,用 0V 表示数字 0, 5V 表示数字 1,那么一个码元可以表示两种状态 0 和 1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致。


如果在通讯传输中,有 0V、2V、 4V 以及 6V 分别表示二进制数 00、 01、 10、 11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半。因为很多常见的通讯(比如串口通讯)中一个码元都是表示两种状态,所以大家常常直接以波特率来表示比特率 。

串口通讯协议

在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,其数据帧组成如下:


下面,我们来实际验证一下其数据帧是不是真的是这样的。编写如下代码:


代码很简单,就是使用串口不断地往外发数据0xAA(当然,发送其它数据也是可以的)。我们的串口配置如下:


我们可以使用示波器或者逻辑分析仪抓取实际信号看看数据是不是符合上面的帧格式。这里,我们使用逻辑分析仪抓取USART1的发送信号线(TX)


从实际结果中,我们可以看到的确是按帧格式来发的。这里可能会有人有疑问,上面那个数据帧的图片中有个空闲状态,这个又是什么呢?空闲、空闲,当然是没有在发数据时候的状态呀,我们把我们的代码改为:


在初始化完成之后只发送一次0xAA,逻辑分析仪抓到的数据为:


可见,空闲状态是个高电平。在上一个的范例中,我们一直在while循环中发送数据0xAA,所以就没有空闲状态。

在这个实验中,我们需要知道的是两个点是:

  • 串口发送数据是低位先发的。我们单片机发0xAA(10101010B),所以逻辑分析仪抓到的有效数据是01010101B

  • 单片机的串口使用的是TTL电平,为正逻辑电平信号。逻辑分析仪抓到的数据0对应着实际电压0~0.5V,数据1对应着实际电压2.4V-5V

经常与TTL电平标准做对比的是RS-232电平标准,如:


常见的电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进制逻辑 1,使用 0V 表示逻辑 0;而为了增加串口通讯的远距离传输及抗干扰能力,RS-232电平标准使用-15V 表示逻辑 1, 15V 表示逻辑 0。

在旧式的台式计算机中一般会有 RS-232 标准的 COM 口(也称 DB9 接口)  :


在这个示例程序中,我们设置的串口波特率为115200bps。在串口通讯中,码元只用1个二进制数来表示(即只有0 和 1两种状态),所以波特率与比特率在数值上是相等的。

而比特率表示的是每秒钟传输的二进制位数,那我们知道传一位数据的时间岂不是就可以反推出波特率是多少了吗?从逻辑分析仪中,我们可以知道发送一位数据的时间如下:


发送一位数据的时间大约为8.667us,所以1秒钟发送多少位数据是可以算出来的:


算出来的波特率为115380bps,与115200bps很相近。最终肯定是有一定的误差,这个误差产生的原因包括逻辑分析仪的质量及我们的测量环境等等因素。但是,这个误差也是在允许的范围内的,可以看看串口助手接收到的数据是不是正确的:


可见,数据接收正确,也就是波特率对的上了。

串口波特率对不上怎么解决?

在实际中。我们可能会遇到这样的情况,代码里配置的波特率与串口助手上设置的波特率一样了,但还是出现异常情况。

异常情况如我们往串口助手发送字符串,串口助手上本该显示的字符串出现了乱码。或者我们往串口助手发送一个数据,发现数据移位了。

出这种情况大多是波特率对应不上,我们就得自己检查我们的底层文件了,代码中的某个与波特率计算相关的值(时钟)与实际不匹配了,就会出现这样的现象,比如之前我的一位同事就遇到这样的情况就是这个原因导致的。

我们用STM32的时候,一般都是使用外部晶振,比如STM32F103系列,可输入的外部晶振的范围是4~16MHz


经验值往往是8MHz,而且一般的demo工程底层代码里默认的也是设置为8MHz,比如:


但是,如果实际晶振贴的不是8M的话,就出问题了(比如串口波特率就不正确了)。追根溯源,串口波特率是配进USART_Init函数中的,打开这个函数:


计算串口波特率需要一个apbclock变量,而这个值得来源从RCC_GetClocksFreq函数来,再打开这个函数:


所以要注意的是,HSE_VALUE这个值要与实际做对应。

遇到这种问题找谁说理去?经验就是不断踩坑、不断积累的一个过程,早点遇到坑可能也是一件好事。像类似底层的问题很少遇到,但是一旦遇到那就得比较棘手的问题了,需要很有耐心地去查找。

能用稳定的芯片是一件很幸福的事情,用不稳定、不成熟的芯片的时候,那个才是真的难啊,遇到问题真是让人怀疑人生啊,软件、硬件、芯片都可能有问题……

以上就是本次的笔记分享,希望各位喜欢!如有错误欢迎指出,谢谢!


END
作者:ZhengN来源:嵌入式大杂烩版权归原作者所有,如有侵权,请联系删除。
嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

USR-N580是有人物联网新开发的一款工业级8串口服务器,8串口独立工作、互不影响;双网口设计,支持交换机功能,可级联,有效扩展串口数量;采用Arm Cortex-M7方案,数据传输速度快且稳定可靠;内部集成TCP/I...

关键字: 物联网 RS485 串口通讯 串口 串口服务器 交换机

点击上方嵌入式开发圈 记得关注我们哦! 【134.1   应用层的“半双工”和“全双工”。】        应用层的“半双工”。主机与从机在程序应用层采用“一问一答”的查询模式,主机是主动方,从机是被动方,主机问一句从机...

关键字: 应用层 串口通讯 双机

单片机在控制本地的外围期间时,信息的交互是通过8位并行数据总线进行的,但是在较大规模的现代控制系统中,单片机还需要控制远端的设备,可以利用单片机的串行通信模块,在学习了RS-232串口通信的原理和时序后,学习了利用RS-...

关键字: 串口通讯 单片机 数据传输

在学习单片机和进行单片机产品开发过程中,我们通常使用仿真器作为调试程序的有力工具。但仿真器价格昂贵,对于初学者和一般个人开发人员很难承受。为此,我们选用了带ISP 功能的AT89S51/52 系列单片机,不需要仿真器也能...

关键字: 串口通讯 在线系统 可编程器

一、串口通讯常识1.串口角色解析2.串口通讯参数串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。波特率:这是一个

关键字: 串口通讯 驱动程序

资源使用说明:2410+LINUX、UART(即RS-232串口)全双工通信、RS-485半双工通信局部程序框图及其设计说明:调试记录及调试结果:MODBUS总结:...

关键字: 2410 串口通讯 modbus协议 ascii模式

这两天在某嵌入式系统做了个串口通讯程序,遇到了每次只接收8个字节的问题。相信很多人都遇到了。上网一查资料,找到串口配置结构体struct termios中的c_cc[VTIME] 和 c_cc[VMI

关键字: 串口通讯 嵌入式系统

前言:串口通讯对于所有的嵌入式工程师十分常见,对于一个与外界交互的系统必须依赖一些手段,比如串口、USB、红外、GPRS之类的数据通讯传输方式。而串口作为一种廉价的短距离可靠的通讯方式得到了广泛应用。废话少说

关键字: 51 串口通讯 编程 软件架构

1、根据波特率和时钟频率设置T2L、T2H的初值2、通过辅助寄存器AUXR,设置T2启动运行,极其运行方式3、通过ES打开串口中断、通过EA打开总中断1、主函数中可以直接使用SBUF=0xXX;向串口发送数据2、接收完数...

关键字: 串口通讯 单片机

串口通讯中发送的关键字一般为16进制数,输出的数据也是16进制数,有负数存在时候要特殊处理。常用处理方法有两种:1、较为常用的是高位定义,高位为1代表负数,为0代表正数,当为负数显示时,采用补码显示。2、将整

关键字: 串口通讯 编程

嵌入式微处理器

1170 篇文章

关注

发布文章

编辑精选

技术子站

关闭