『7x24小时有问必答』

一、核心原理

先通过  bytes[offset]  获取字节数组中指定偏移量(offset)的单个字节(对应 PLC 中的 1 个字节地址);
再通过  按位与(&  运算 +  位左移(<<  运算,提取该字节中指定位(bitIndex,范围 0~7,0 表示最低位 / 最右边,7 表示最高位 / 最左边)的值;
判定规则:运算结果非 0 表示该位为 1(对应 C#  true),运算结果为 0 表示该位为 0(对应 C#  false)。

二、关键表达式(提取单个位的值)

这是提取指定位的核心代码,直接可复用:
// 核心表达式:提取  bytes  数组中 offset 偏移量字节的 bitIndex 位的值bool  bitValue = (bytes[offset] & (1  << bitIndex)) !=  0;

表达式逐部分拆解

部分
含义说明
bitIndex
要提取的位索引,范围 0~7(必须满足  0 ≤ bitIndex ≤ 7,否则会出错)
1 << bitIndex
把数字 1 左移  bitIndex  位,生成一个 “仅目标位为 1,其余位为 0” 的掩码(例如  bitIndex=2  时,1<<2=4,对应二进制  00000100
bytes[offset] & (1 << bitIndex)
按位与运算:只有 “目标位同时为 1” 时,结果才非 0,其余情况结果为 0(精准筛选目标位的值)
!= 0
将位运算结果转换为 C# 布尔值:非 0 →  true(位值为 1),0 →  false(位值为 0)

三、完整代码示例

下面提供可直接运行的 C# 代码,包含字节数组定义、位提取方法、场景演示:
using  System;class  PlcBitExtraction{       static  void  Main(string[]  args)      {             // 示例:从 PLC 读取的字节数组(假设 bytes[0] = 0x05,对应二进制 00000101)             byte[] plcBytes =  new  byte[] {  0x05,  0x12,  0x34  };             // 需求1:提取 offset=0(第1个字节)、bitIndex=0(最低位)的值             int  offset1 =  0;             int  bitIndex1 =  0;             bool  bit1 = ExtractBitFromBytes(plcBytes, offset1, bitIndex1);            Console.WriteLine($"字节{offset1}的位{bitIndex1}值:{bit1}(对应二进制位1)");             // 需求2:提取 offset=0、bitIndex=1 的值             int  bitIndex2 =  1;             bool  bit2 = ExtractBitFromBytes(plcBytes, offset1, bitIndex2);            Console.WriteLine($"字节{offset1}的位{bitIndex2}值:{bit2}(对应二进制位0)");             // 需求3:提取 offset=0、bitIndex=2 的值             int  bitIndex3 =  2;             bool  bit3 = ExtractBitFromBytes(plcBytes, offset1, bitIndex3);            Console.WriteLine($"字节{offset1}的位{bitIndex3}值:{bit3}(对应二进制位1)");             // 需求4:提取 offset=1、bitIndex=3 的值(bytes[1]=0x12 → 二进制 00010010)             int  offset4 =  1;             int  bitIndex4 =  3;             bool  bit4 = ExtractBitFromBytes(plcBytes, offset4, bitIndex4);            Console.WriteLine($"字节{offset4}的位{bitIndex4}值:{bit4}(对应二进制位1)");      }       ///  <summary>       ///  从字节数组中提取指定偏移量、指定位索引的位值       ///  </summary>       ///  <param name="bytes">原始字节数组(从 PLC 读取的字节流)       ///  <param name="offset">字节偏移量(数组索引,从0开始)       ///  <param name="bitIndex">位索引(0~7,0=最低位,7=最高位)       ///  <returns>位值(true=1,false=0)</returns>       static  bool  ExtractBitFromBytes(byte[] bytes,  int  offset,  int  bitIndex)      {             // 合法性校验:防止数组越界和位索引超出范围             if  (bytes ==  null)                   throw  new  ArgumentNullException(nameof(bytes),  "字节数组不能为null");             if  (offset <  0  || offset >= bytes.Length)                   throw  new  ArgumentOutOfRangeException(nameof(offset),  "字节偏移量超出数组范围");             if  (bitIndex <  0  || bitIndex >  7)                   throw  new  ArgumentOutOfRangeException(nameof(bitIndex),  "位索引必须在0~7之间");             // 核心:位运算提取指定位             byte  targetByte = bytes[offset];  // 获取指定偏移量的字节             int  mask =  1  << bitIndex;            // 生成位掩码             return  (targetByte & mask) !=  0;  // 按位与运算,判定位值      }}

四、运行结果说明

上述代码中,plcBytes[0] = 0x05(十六进制)→ 对应二进制  00000101,运行后输出:
字节0的位0值:True(对应二进制位1字节0的位1值:False(对应二进制位0字节0的位2值:True(对应二进制位1字节1的位3值:True(对应二进制位1
完全匹配二进制位的实际值,验证了提取逻辑的正确性。

五、补充说明

位索引顺序
:PLC 中常用的位编号(如 I0.0、I0.1)通常对应  bitIndex=0bitIndex=1,与上述代码的位索引一致;
批量提取
:若需提取 1 个字节对应的 8 个位,可通过循环  bitIndex  从 0 到 7 依次调用提取方法;
PLC 场景适配
:该方法完全适配 Sharp7、S7NetPlus 等主流 PLC 通信库,可直接集成到 PLC 数据读取业务中。

总结

核心表达式:(bytes[offset] & (1 << bitIndex)) != 0(快速提取指定位的值);
关键运算:按位与(&)用于筛选目标位,位左移(<<)用于生成位掩码;
位索引范围:0~7(0 最低位,7 最高位),偏移量  offset  为字节数组的索引;
实际使用时需增加合法性校验,避免数组越界和无效位索引。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码