最常见的bcd码,你真的会用BCD码指令么
最常见的bcd码,你真的会用BCD码指令么那么为何输入整数16处理的时候就没有出错呢?BCD_I指令的输入端这里,在指令处理的时候BCD端的参数,是以怎样的真实格式化去处理的?根据BCD码的基础定义“用4位二进制数表示十进制数中0-9这10个数字”,从这句话可知十六进制的ABCDEF就是十进制的10-15,这明显超出了基础定义的0-9,因此16进制下的ABCDEF用作输入参数时指令出错的原因就找到了。BCD指令错误监控图1BCD指令错误监控图2从上边这2张图上,我们可以看到BCD_I指令的输入端输入整数10-15和输入十六进制的ABCDEF时候,该指令都出错了(此时SM1.6会被置1,可以去看前一篇文章),因此后边的ENO都无法输出了,后边的监控线头是灰色,因为没有能流。同时,还可以看到输入整数值16的时候,程序没有出错,为什么呢?
在我前天发表的文章《图说西门子特殊寄存器之SM1.0-SM1.7》中讲到SM1.6处,我留了一个问题给朋友们,就是:“使用BCD码转整数指令时候,为何输入参数是1113指令运行无错误,而当输入参数是1114时指令运行出错了?”,以这个为引子,开始我今天的文章。
说到BCD码可能会立马想到8421码,读书的时候应该接触的就是这个。其实BCD码还可以分为有权码、无权码,还有什么5421码,但这些都不是我要讲的,本人要说的是西门子200PLC中关于BCD码的指令,特别是BCD码转换指令出错的原因分析。
BCD码 (Binary-Coded Decimal)也叫二-十进制码,是用4位二进制数表示十进制数中0-9这10个数字的一种码。这个是BCD码的基础定义,不管是什么PLC都要遵守的,所以特意再提出来。
首先来看2张监控截图:
BCD指令错误监控图1
BCD指令错误监控图2
从上边这2张图上,我们可以看到BCD_I指令的输入端输入整数10-15和输入十六进制的ABCDEF时候,该指令都出错了(此时SM1.6会被置1,可以去看前一篇文章),因此后边的ENO都无法输出了,后边的监控线头是灰色,因为没有能流。同时,还可以看到输入整数值16的时候,程序没有出错,为什么呢?
根据BCD码的基础定义“用4位二进制数表示十进制数中0-9这10个数字”,从这句话可知十六进制的ABCDEF就是十进制的10-15,这明显超出了基础定义的0-9,因此16进制下的ABCDEF用作输入参数时指令出错的原因就找到了。
那么为何输入整数16处理的时候就没有出错呢?BCD_I指令的输入端这里,在指令处理的时候BCD端的参数,是以怎样的真实格式化去处理的?
Micro/WIN软件中对指令的解释
根据帮助文件的解释和实际的程序,我猜测可能有2种可能:
①是以直接以2进制BCD码的格式来处理的(也就是说16已经被看作一个BCD码数,那他的二进制应该是BCD 2#0001 0110 == 16#16)?
②是以16进制下的值看作BCD的格式来处理的(也就是说将整数16自动转换为16#10,BCD 16#10)?
--为了探明这问题,继续看下一个图片。
BCD指令监控图3
BCD指令监控之状态表图
从监控图3可以看到,BCD端输入整数16,被转换为整数10。而将VW0也就是整数10再次作为BCD_I指令的输入端时,指令又出错了。按照上边猜测①的思路16是当做一个BCD码看待的,即BCD 2#0001 0110,那么转化后的结果应该是16才对,而监控中VW0的结果是10,由此可见,思路①的猜测是错误的。
那么只有按照思路②来看,输入端的整数16先是被转换为16进制下的16#10后看作一个BCD码再去转换的,也就是将16#10即2#0001 000看作了BCD码,因此转化为十进制数就是10。以这样的解释来看结果,那么结果就对了,再来多试验看看:
BCD指令监控图4
从这个图片可以看到整数17被转换为了11,整数18被转换为了12。
17的16进制表示就是16#11,即BCD 16#11==2#0001 0001,因此转化BCD转化为整数就是11。
18的16进制表示就是16#12,即BCD 16#12==2#0001 0010,因此转化BCD转化为整数就是12。(请忽略本文中的==用法的不准确性,仅为说明问题,谢谢)
所以,到这里BCD_I指令,BCD输入端其实是16进制下的BCD值,BCD_I指令更加准确的描述应该是将16进制BCD码转化为为整数,不知道帮助文件或者西门子200的手册为何没有强调这个16进制。下图是手册上的解释:
BCD码指令在系统手册上的解释
但是我在西门子找答案网页上发现了西门子的专家置评,见下图:
BCD_I指令的官方评价
所以,文章写到此,可以得出一个结论:BCD_I指令就是将16进制的BCD码转化为整数的一个指令,其在BCD参数输入端的值为16进制数时最好,不为16进制数时系统将自动将其转化成16进制数,而后才对其进行运算。
再进一步来说一下BCD端是要求16进制的问题,下边看一个西门子300的程序切图:
M20.0不为1时切图
这个图片是值运行程序第2行,整数16通过BCD_I指令后结果也是10,证明是和西门子200中的算法一样的。
M20.0为1时切图
这个图片是将M20.0置1,程序第1行也接通,从这个图片上看到PLC还是在运行,ENO还是输出了,这是和西门子200系统不一样的地方,但是MW2的值此时为0,显然是不对的,所以PLC还是给出了提示:
300系统指示灯报错了
诊断报告说BCD转换错误
这两个图详细说明了,因为程序第一行的BCD_I指令出现错误,所以系统报错了。报错的真是原因是什么呢?就是整数10被转为了16#0a,而BCD码的基本概念是用4位二进制数表示0-9这10个十进制数,因此BCD #160a是非法的,它不能被看作是一个BCD码。
写到这里,再回头看我在之前的文章中留下的问题:“使用BCD码转整数指令时候,为何输入参数是1113指令运行无错误,而当输入参数是1114时指令运行出错了?”,我想有的朋友已经有答案了。
答案就是:BCD_I指令是要求16进制的BCD码格式,整数1113转化为16进制是16#459,整数1114转化为16进制是16#45A,而出现A就是非法的BCD码。这就是最终的答案。
整数1114转化为16进制是16#45A
本篇文章结束,可能有点费理解,但是提高就是不断的越过障碍,希望通过本文能让朋友们对BCD相关指令编程时候的错误情况有一个更深入的了解,不至于出错了还要想很久才知道哪里错了。
最后,感谢大家的支持,有不明白的地方,敬请关注留言,我会及时回复,谢谢。