前言:
十六进制(H)转二进制
方法1:对每一位16进制数字进行除二取余,倒序排列,每位16进制数都要得出4位2进制数,不够前面补0,从左到右组合在一起。
例如:2E4(H)转2进制。补充:16进制数:0-9,10用A表示,往后排
方法2:采用2进制转16进制时的8421法,16进制数每位拆开,看当前数字是8421的哪些数字之和,这些数字下面为1,没有参与和运算的是0。
程序:
//Counting the bits containing "1" in a memory Word
//计算存储器字中包含“1”的位
#xSource := #In_Source;
#Total := 0;
FOR #i := 1 TO 16 DO
#Total := #Total + WORD_TO_INT(IN := #xSource AND 16#0001);
#xSource := SHR(IN := #xSource, N := 1);
END_FOR;
效果:
代码整体功能说明:
这段代码的核心功能是统计输入变量#In_Source(类型为 Word,即 16 位无符号整数类型)中各位为 1 的个数,并将统计结果存储在输出变量#Total(整数类型)中。通过循环逐位判断并累加实现此功能。
具体代码解读
变量初始化部分
- #xSource := #In_Source; 这意思就是,先把输入变量#In_Source 的值给到中间变量#xSource 。接下来所有的操作都会以这个中间变量为基础,这么做能在不改动原始输入变量的前提下,更方便地去做按位处理之类的操作。而且#xSource 也是 Word 类型,跟#In_Source 一样,继承了初始值。
- #Total := 0; 就是把输出变量#Total 一开始就设成 0 。它是用来累计统计#In_Source(通过#xSource 间接操作)里各位是 1 的情况所对应的数值的,已经准备好接收后面逐位判断累加的结果啦。
循环操作部分(FOR 循环)
- #xSource AND 16#0001 这是在做按位与操作,#xSource 是 Word 类型的数据,要和十六进制数 0001(对应的二进制数是 0000 0000 0000 0001)进行按位与的运算。按位与运算的规则是,只有对应位都是 1 的时候,这一位的结果才是 1,不然就是 0 。所以这么操作完,就只留下了 #xSource 的最低位,其他位都变成 0 了。要是 #xSource 的最低位是 1 ,那运算结果就是十六进制的 0001 ;要是最低位是 0 ,运算结果就是十六进制的 0000 。
- WORD_TO_INT 这是一个类型转换的函数,能把前面按位与操作得到的结果(本来是 Word 类型)转成整数类型。转换完以后,如果按位与的结果是十六进制的 0001 ,那就变成整数 1 ;要是是十六进制的 0000 ,那就变成整数 0 。
- 最后把转换得到的整数加到 #Total 变量上,这样就实现了每次循环对 #xSource 当前最低位(对应的整数是 1 或者 0 )情况的统计累加。
- FOR #i := 1 TO 16 DO 这是定义了一个计数循环,循环控制的变量是#i,它的取值从 1 开始,每次增加 1 ,一直到 16 结束。因为 Word 类型的数据长度是 16 位,所以这里循环 16 次,正好能把 #xSource 代表的 16 位数据挨个处理一遍。
- #Total := #Total + WORD_TO_INT(IN := #xSource AND 16#0001);
- #xSource := SHR(IN := #xSource, N := 1); 这里用了右移(SHR)函数,对 #xSource 变量进行右移操作,右移的位数由参数 N 规定是 1 。右移操作的效果就是把 #xSource 的各位依次往右移动一位,最高位补 0 ,原来的最低位不要了,这样原来的次低位就变成新的最低位了,为下一次循环判断新的最低位情况做好了准备。
- END_FOR; 这就表示 FOR 循环结束了,经过这 16 次循环,#Total 变量就完成了对 #xSource (也就是最开始的 #In_Source )里所有 16 位数据中各位是 1 的个数的统计累加。
总的来说,等这段代码都执行完了,#Total 变量里存着的数就是输入变量 #In_Source 里各位是 1 的个数。这就实现了从 Word 类型的输入数据,到统计结果是整数类型输出的功能逻辑。
西门子SCL编程,统计一个16 位字中值为1的位的数量
http://bbs.plcjs.com/forum.php?mod=viewthread&tid=505611&fromuid=1
(出处: PLC论坛-全力打造可编程控制器专业技术论坛)