把总线上的比特换成缓冲区里的字节
用逻辑分析仪去夹 UART、SPI、I²C 或 CAN 的信号线时,抓到的波形是按比特计的。可固件这一侧全是字节:64 个表项的接收缓冲区、12 个寄存器的映射表、上限 8 字节的数据场。每次在这两种视角之间来回,其实就是在除以 8;而凌晨三点盯着一帧校验失败的报文心算这个数,正是差一错误被带进量产版本的典型场景。
字节 = 比特 ÷ 8(等同于 比特 × 0.125)。一帧 108 比特的 CAN 2.0A 报文是 108 ÷ 8 = 13.5 字节的纯线上时间——其中只有 8 字节是你的数据。除法本身没什么难度,真正让人栽跟头的是:你刚才数的到底是哪一批比特。一个字节的应用数据,几乎从来不会在物理链路上刚好占八个比特时间,因为成帧、同步和检错都要在同一根线上分走位置。
线上比特与载荷比特
寄存器位宽
时序预算
一步步换算一次抓包结果
先想清楚你数的是哪种比特
先确定你要数的是载荷位,还是分析仪看到的每一个位。对一个 8N1 的 UART 字节来说,这两个答案分别是 8 和 10——同一个问题,两种结果。
把比特数填进去
在比特一侧输入数值,字节结果随打随变,整帧拆解可以一路看下来,不用按任何按钮。解码器导出的长数据常带空格或用逗号当小数点,两种写法都能识别,空格会被直接忽略。
把数字直接复制进代码
每个输入框的复制按钮给出的是不带单位、不带空格的纯数字,正好适合塞进 #define、缓冲区长度或一条测试断言。
回到示波器时把方向调过来
按交换单位按钮就能从字节反推比特——已知载荷是 32 字节、想知道它在线上要占多少比特时间时很好用。两个单位菜单都支持搜索,不离开本页也能跳到千比特或每秒字节数。
UART 成帧开销:从波特率到每秒有效字节数
经典的 8N1 配置给每个数据字节套上一个起始位和一个停止位,于是十个比特时间只送出八位载荷——固定 25 % 的开销。这就是为什么「波特率除以 8」这种粗算法,永远会把链路的真实吞吐说高了。
| 波特率(bit/s) | 粗算比特 ÷ 8 | 实际载荷(8N1,每字节 10 位) | 一个字节耗时 |
|---|---|---|---|
| 9 600 | 1 200 B/s | 960 B/s | 1 042 µs |
| 19 200 | 2 400 B/s | 1 920 B/s | 521 µs |
| 38 400 | 4 800 B/s | 3 840 B/s | 260 µs |
| 57 600 | 7 200 B/s | 5 760 B/s | 174 µs |
| 115 200 | 14 400 B/s | 11 520 B/s | 86.8 µs |
| 921 600 | 115 200 B/s | 92 160 B/s | 10.9 µs |
再加一位校验,一帧就变成十一个比特时间,9 600 波特下的载荷掉到大约每秒 873 字节。用两位停止位又要再让出一格。这些都不改变 ÷8 这条算式——它们改变的是你该往里面填多少比特。
对比不同帧格式时两栏都是活的
在任意一栏输入,另一栏立刻跟上,于是你可以一手拿着载荷数、一手拿着线上时间数来回比对,不用反复重输。
长突发的结果依然读得清
千位之间用空格分隔,特别大的抓包量会切到科学计数法,几百万比特的波形记录也不会变成一堵数字墙。
总线常用单位都在一个下拉菜单里
可搜索的单位菜单涵盖比特、千比特、字节以及各种每秒速率单位,CAN、SPI 或 UART 的数据换个说法就行,不必再翻别的页面。
数据不出实验台
页面加载完之后,所有算术都在浏览器里完成,从客户抓包里抠出来的数字不会被传到任何地方。
串行协议相关问题
9 600 波特的链路为什么每秒只走 960 字节,而不是 1 200 字节?
因为波特数的是线上的符号,不是载荷位。标准的二进制 UART 一个符号就是一个位,所以 9 600 波特等于每秒 9 600 个比特时间——但在 8N1 成帧下,每个数据字节要吃掉其中十个。除以 8 得到的 1 200 B/s,是假设线上只跑数据的理论值;除以 10 得到的 960 B/s,才是应用层真正收到的量。
起始位、停止位和校验位各占多少?
起始位是一个下降沿,用来通知接收端开始采样;停止位把线路拉回空闲态,保证下一个起始沿不会被误判。两者都不携带信息。校验位启用后会在数据位旁边再加一位,纯粹用于单比特错误检测。所以一帧 8E1 是 11 个比特时间——一个字节的载荷,占掉 1.375 个字节当量的线路时间。
先发高位还是先发低位,会影响换出来的字节数吗?
不会——两种顺序数出来完全一样,只是拼出来的数值不同。UART 是低位先出,SPI 和 I²C 习惯上高位先出。搞混之后得到的是位序颠倒的字节,占用的比特时间一个不多一个不少,所以症状看起来像数据损坏,而不像长度对不上。
CAN 的位填充会怎样改变比特与字节的关系?
CAN 在连续五个相同电平之后会插入一个相反的位,好让各接收节点保持时钟同步。一帧 11 位标识符、载荷占满 8 字节的标准报文,填充前是 108 比特,最坏情况下可以涨到大约 135 比特。多出来的都是纯线路时间:不管收发器插了多少填充位,你的载荷始终是 8 字节。
解码器导出的突发长度是比特数,怎么跟接收缓冲区对比?
用帧长去除,而不是用 8 去除,再拿得到的字节数跟缓冲区深度比。12 000 比特的突发在 8N1 下是 1 200 帧,因此需要 1 200 字节的空间;而 12 000 ÷ 8 = 1 500 这个原始数字描述的是线路占用。把错的那个喂进 FIFO 容量计算,是溢出标志莫名其妙被置位的常见原因。
还没有评论,快来发表第一条!