硬件工程师口中的取低八位,中八位,高八位是什么意思?

阿硬:协议定好了,你按协议上的解析就可以了。

小卡拉米:高八位,中八位低八位什么意思。

阿硬:

在我们和硬件通讯的协议当中,可能要一个字节一个字节的解析。但是我们有时候需要传输的数据有时候用一个字节是不够的。 比如一个CAN协议,要接收一个数据

我们接收到数据段有三个字节,第一个字节代表数据的高八位,第二个字节代表数据的中八位,第三个字节代表数据的低八位。我们怎么解析这个数据呢?

1、复习byte ,short,int 和 long

在Kotlin中

类型 位数 字节数 取值范围
Byte 8 1 -128 到 127
Short 16 2 -32768 到 32767
Int 32 4 -2³¹ 到 2³¹-1
Long 64 8 -2⁶³ 到 2⁶³-1

2、传输数据时,byte个数的选择

当传输状态信息(例如设备启动状态、水温、空调温度设定值)时,一个 Byte(8位)通常足以表示,因为其取值范围(-128 至 127)能够涵盖这类离散或有限范围的状态值。

若传输的数据值超出 Byte 的表示范围,则需要使用两个 Byte 组合表示一个数值 :其中一个 Byte 表示高八位 ,另一个 Byte 表示低八位

对于小数类型的数据传输 ,需在通信协议中明确规定小数精度 (例如保留三位小数)。实际传输时,一般做法是将原始数值乘以缩放因子(如 1000)转换为整数 ,然后发送该整数值。接收方解析后,再除以相同的缩放因子(如 1000) ,即可还原原始数值。

3、两个byte 转成一个数

核心原理:二进制位拼接与数值重构

当使用两个字节表示一个数值时(Byte1 为高八位,Byte2 为低八位),本质是通过二进制位的拼接重构原始数值。其数学原理是:

最终数值 = (高八位值 × 256) + 低八位值

具体的操作步骤:

3.1、字节到整数的无符号转换

Kotlin/Java中,Byte 是有符号类型,需要转为无符号整数

kotlin 复制代码
val highBits = byte1.toInt() and 0xFF  // 高八位无符号值 (0~255)
val lowBits = byte2.toInt() and 0xFF   // 低八位无符号值 (0~255)

and 0xFF 确保只保留后八位

3.2、高八位左移

通过位左移(<<) 将高八位移动到正确位置:

kotlin 复制代码
val shiftedHigh = highBits shl 8  // 等价于 highBits × 2⁸

00001011(十进制11)左移8位 → 00001011_00000000(十进制2816)

3.3、位或(OR)运算合并

将移位后的高八位与低八位进行按位或运算

kotlin 复制代码
val finalValue = shiftedHigh or lowBits  // 位拼接

00001011_00000000(高八位)
OR 00101100(低八位)

= 00001011_00101100

原理解析图

kotlin 复制代码
高八位字节 (byte1)     低八位字节 (byte2)
┌───────┐             ┌───────┐
│ 00001011 │           │ 00101100 │
└───────┘             └───────┘
      │                     │
      ▼ 左移8位             ▼
┌───────────────┐       ┌───────┐
│ 0000101100000000 │ OR  │ 00101100 │
└───────────────┘       └───────┘
             │         │
             └─────┬─────┘
                   ▼
         ┌───────────────────┐
         │ 0000101100101100 │ → 十进制2860
         └───────────────────┘

高中低 同理,三个的时候,高八位要左移十六, 中八位左移八位

4、一个数转成两个byte

graph LR A[原始整数 value] --> B[取低八位] A --> C[取高八位] B --> D[byte2 = value & 0xFF] C --> E[byte1 = value >> 8]

4.1. 提取低八位(byte2) :

kotlin 复制代码
    val byte2 = (value and 0xFF).toByte()  // 直接取最后8位    
  • and 0xFF操作:屏蔽高24位,保留最低8位
  • 示例:2860(0x0B2C)→ 0x2C → 44

4.2. 提取高八位(byte1)

kotlin 复制代码
 val byte1 = (value shr 8).toByte()  // 右移8位后取低8位
  • shr 8操作:将原始值右移8位(相当于除以256)
  • 示例:2860(0x0B2C)→ 右移8位 → 0x0B → 11

4.3 如果需要提取中八位,需要注意一下

graph LR A[原始32位整数] --> B[屏蔽低八位] A --> C[屏蔽高八位] B --> D[右移8位] C --> E[位掩码操作] D --> F[获取中八位] E --> F

详细步骤(以 0x12345678 为例)

  1. 屏蔽低八位(清除0-7位)

    kotlin 复制代码
    val withoutLow = value and 0xFFFFFF00 // 清除低8位
    • 位掩码 0xFFFFFF00 = 11111111_11111111_11111111_00000000
    • 示例:0x12345678 and 0xFFFFFF00 = 0x12345600
    • 效果:保留24-8位,清除0-7位
  2. 屏蔽高八位(清除24-31位)

    kotlin 复制代码
    val middle8 = (value shr 8) and 0xFF // 右移后取低8位
    • 步骤分解:

      a. value shr 8:将值右移8位

      • 0x12345678 shr 8 = 0x00123456
        b. and 0xFF:取结果的最低8位
      • 0x00123456 and 0xFF = 0x56

完整代码实现

kotlin 复制代码
fun extractMiddle8Bits(value: Int): Int {
   :直接右移+掩码(推荐)
    return (value shr 8) and 0xFF

// 方法2:分步屏蔽
    // val withoutLow = value and 0xFFFFFF00
    // return (withoutLow ushr 8) and 0xFF

}

OK,这样就可以和阿硬愉快的沟通啦

相关推荐
kymjs张涛3 分钟前
前沿技术周刊 2025-06-09
android·前端·ios
用户2018792831671 小时前
View的filterTouchesWhenObscured属性
android
宋智孝的小迷弟2 小时前
抽丝剥茧带你掌握 Kotlin Flow(一):协程时代的异步数据流处理“神器”
android·面试·app
小鱼人爱编程3 小时前
现代大前端是如何编码的?
android·前端·flutter
移动开发者1号3 小时前
Android中Activity、Task与Process的关系
android·kotlin
琪阿不会编程3 小时前
Mysql8 忘记密码重置,以及问题解决
android·数据库·sql·mysql
CYRUS_STUDIO3 小时前
一文搞懂 SO 脱壳全流程:识别加壳、Frida Dump、原理深入解析
android·安全·逆向
移动开发者1号4 小时前
Activity onCreate解析
android·kotlin
帅得不敢出门7 小时前
Android Framework预装traceroute执行文件到system/bin下
android
xzkyd outpaper7 小时前
从面试角度回答Android中ContentProvider启动原理
android·面试·计算机八股