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

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

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

阿硬:

在我们和硬件通讯的协议当中,可能要一个字节一个字节的解析。但是我们有时候需要传输的数据有时候用一个字节是不够的。 比如一个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,这样就可以和阿硬愉快的沟通啦

相关推荐
JMchen12343 分钟前
第 3 篇|Android 项目结构解析与第一个界面 —— Hello, CSDN!
android·android studio·android 零基础·android 项目结构·android 界面开发
众少成多积小致巨4 小时前
Soong构建入门
android·go·编译器
笔夏4 小时前
【安卓学习之混淆】记录一些混淆导致闪退
android·学习
阿巴斯甜4 小时前
Kotlin高阶函数和Java 8 lambda的区别:
android
IpdataCloud4 小时前
IP查询高精度怎么选?8个指标判断是否适合你
网络·网络协议·tcp/ip
张小潇4 小时前
AOSP15 WMS/AMS系统开发 - WindowManagerService relayout调用流程详解
android
聊点儿技术4 小时前
IP风险等级评估是什么?跨境电商业务场景全解析
网络·网络协议·tcp/ip
阿巴斯甜4 小时前
Kotlin 高阶函数:
android
之歆5 小时前
Day03_HTML 列表、表格、表单完整指南(下)
android·javascript·html
QING6185 小时前
Kotlin之【init】—— 新手须知
android·kotlin·android jetpack