对网友求助问题的几个回帖展示之六十二 点击:1652 | 回复:7



wyb2866255---王者之师

    
  • 精华:57帖
  • 求助:0帖
  • 帖子:148帖 | 2872回
  • 年度积分:1
  • 历史总积分:31450
  • 注册:2010年7月01日
发表于:2014-07-08 13:13:37
楼主

                   对网友求助问题的几个回帖展示之六十二

 

         网上有这样一个求助帖:求解有符号数如何转换无符号

有一个双字的十六进制数DW#16#D4DB71FB,我用计算器转成十进制是 3571151355

但貌似PLC里只能转成有符号的数 L#-723815941

怎么在plc里转换成无符号的数~

有什么办法吗~

各位大神~本人新手求教~~跪谢~~~

感激!!~!~!

      该求助帖提出的问题:如何在PLC里将双字的十六进制数DW#16#D4DB71FB换成无符号的数3571151355,正是目前PLC自身不能解决的问题,以西门子S7-200为例,该PLC内的存储器存储整数的最小单元为字节,2个字节组成一个字,2个字构成一个双字,双字即为PLC存储整数的最大的存储单元。PLC对字节定义为无符号数,即字节可传递显示16进制数0~FF(即10进制数0~255),而对于字与双子存储器定义为有符号数,即:其最高位定义为存储数的符号位,当最高位=0时表示为此数为正数,当最高位=1时表示此数为负数。如将16进制正数“16#9673”送入MW0,MW0的各位值为:1001_0110_0111_0011,由于其最高位M0.7=1 ,故在监视状态下,MW0显示的不是正数38755,而是负数-26781。见下图:

 

        这就是求助者提出的问题:本来是正数存入存储器里,可是存储器显示的数却变成负数,如对次数进行加减乘除运算,也是按负数进行,这给数据监视及对数据计算整理带来极大的不便。

      如何解决字与双字在存储的数其最高位=1时,在监视状态下能显示其正数值而不出现负数值呢?请见以下解析:

       1、对于最高位=1的字存储器,要使它不显示负数,可将它传递给双字存储器。用双字存储器显示其存数值即可解决显示正数值而不会显示负值。即:令该字的上一个字存储器=0,如:MW2 = 16#9763,可令MW0=0,监视MD0双字存储器,其MD0的显示值即为正数值,见下图中的MOV_DW的显示值。

         2、  对于最高位=1的双字存储器,由于PLC无四字存储器,故不能采用上述1的方法来实现正数显示,但可以采用下面的思路编程来实现:

        用二个存储器(一个双字与一个单字)分别显示该数的前后二部分数字:用双字存储器显示该数百位以上的部分数值,用单字存储器显示该书的十位与个位2为数值。将这二个存储器数字串联相接的数字,即为该数转换为10进制数的正数值。举例:一个16进制数转换为10进制数,将转换后的数的百位以上的数字部分送入双子存储器内,其值为:35711513;而转换为10进制数的百位以下的数字部分送入单子存储器内,其值为:55。则该16进制数转换为10进制的数为:35711513 55。

        编程思路:1、将16进制的双字正数送入MD1,其MD0值=MD1数÷256(即16#100)。再将MD0÷100×256——>VD0, 则VD0值即为MD1÷100的整数部分,将它转换为10进制数送入VD0,则VD0就不会显示负值,而且此VD0值的最小单位值1为10进制数的百位数(即=100)。 MD0÷100的余数部分加上MD1的最低字节(MB4)值—>MW4,再进行这样整理:MW4-100 > 0 则VD0 + 1,直到MW4 < 100为止。此时的VD0值为原MD1数转换为10进制的百位以上的数字部分,而MW4值为原MD1数转换为10进制的百位以下的十位与个位的数字部分。

         将双字单元的16进制数转换为无符号的10进制数的程序

 

 

 

       下面是将双字的十六进制数 DW#16#D4DB71FB送入MD1, 按上面程序运行,在监视状态下,转换成无符号的正数(见网络6中的VD0与VW4),

 

 

 

         即:MD1 = 16#D4DB71FB = 3571151355

   VD0*100+VW4=3571513×100+ 55 = 3571151355

    对于最高位=0的双字数,带入上程序,运行结果也是正确的,见下图:

 

 

 

        即:MD1 = 16#74DB71FB = 1960538619

      VD0*100+VW4=19605386×100+19 = 1960538619

 

     对于最高位=0的数可不用运行上述编程,直接用MD1->VD1, 其VD1即可在监控下显示10进制数值,故可将原网络6改为下面2条编程语句(见下图):在最高位=0时,其M1.7=0,故网络6运行,其VD1值即为10进制的转换值。在最高位=1时,其M1.7=1,故网络7运行,其VD0与VW4值串联相接值 即为10进制的转换值。

 

 

        本文到此结束,有不妥之处,请给予指正,谢谢!

 




银光人生—华

  • 精华:0帖
  • 求助:0帖
  • 帖子:5帖 | 13597回
  • 年度积分:0
  • 历史总积分:52877
  • 注册:2007年11月23日
发表于:2014-07-09 08:16:07
1楼

很不错的总结,精华。                  

LCL———王者之师

  • 精华:0帖
  • 求助:9帖
  • 帖子:62帖 | 478回
  • 年度积分:197
  • 历史总积分:34719
  • 注册:2011年9月24日
发表于:2014-07-13 17:09:33
2楼

王工你太牛了,佩服。。。。

小诚

  • 精华:16帖
  • 求助:64帖
  • 帖子:679帖 | 7271回
  • 年度积分:3
  • 历史总积分:32156
  • 注册:2012年9月27日
发表于:2014-07-17 15:14:13
3楼

引用 LCL———王者之师 的回复内容: 王工你太牛了,佩服。。。。



Smile-lyc

  • [管理员]
  • 精华:114帖
  • 求助:50帖
  • 帖子:2793帖 | 22283回
  • 年度积分:284
  • 历史总积分:144015
  • 注册:2006年8月04日
发表于:2014-07-17 15:27:29
4楼

如将16进制正数“16#9673”送入MW0,MW0的各位值为:1001_0110_0111_0011,由于其最高位M0.7=1 ,故在监视状态下,MW0显示的不是正数38755

其中正数是不是该是:38515

wyb2866255---王者之师

  • 精华:57帖
  • 求助:0帖
  • 帖子:148帖 | 2872回
  • 年度积分:1
  • 历史总积分:31450
  • 注册:2010年7月01日
发表于:2014-07-17 17:57:00
5楼

        回4楼:你说的对:对16#39673 的 10进制数应为38515。这是由于我笔误造成的错误,即将16进制数写错了,16#数应为 39763  它转换为0进制数才为38755,请见本帖的第二插图中的转换数据。

abm7185

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 7回
  • 年度积分:0
  • 历史总积分:7
  • 注册:2014年9月28日
发表于:2014-09-28 21:20:07
6楼

有条不紊,头头是道嘛

burningup

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 54回
  • 年度积分:0
  • 历史总积分:24
  • 注册:2014年9月14日
发表于:2015-08-03 14:12:49
7楼

很不错的总结, 谢谢               


热门招聘
相关主题

官方公众号

智造工程师