ab罗克韦尔plc吧 关注:19贴子:26

AB-PLC自学笔记

只看楼主收藏回复

先试试


1楼2018-08-25 09:08回复
    以前断断续续的学了一点,但大多是三天打鱼两天晒网;也参加了一 次培训,但是短短的课程、大量的产品介绍和难得的上机实验,很快 就忘记了学了点啥。翻开以前的学习记录,零散而杂乱,不少要点看 上去是那么陌生。也罢,再来一次打鱼又如何?
    第一步,安装软件。
    手上有去年培训的时候从老师那里搞来的 16 版本的 logix5000,以 前也安装过,里面有很好的英文语音教学,当时老师开玩笑说,可以 锻炼下听力。安装完 logix5000 V16,再安装一个模拟器软件: Emulate,安装过程中告诉我需要 rslinx,昏,看来安装次序错鸟。 其实在安装 logix5000 的过程中,最后一些小工具的安装也提示我需 要 rslinx 的,被我忽略了。于是安装 rslinx,再安装 emulate。最 后一步,把网上找来的授权导入。发现用老版授权的话,软件第一次 运行会提示你,现在 16 版本采用所谓的 factorytalk 管理授权了云 云,我不管,反正能用就行。
    接下来的问题就是,怎么用这个模拟器?以前用过,但是忘鸟。只记 得要选择一个特殊的硬件,还好有份模拟器的使用手册,简单看了下 几个插图就回忆起来了,试了下,ok。个人觉得 ab 的 emulate 有点 别扭,因为用惯了西门子的 plcsim,那个不需要选择什么特殊的硬


    2楼2018-08-25 09:09
    回复
      件,原工程就可以很仿真的 download 下去去模拟运行。而 ab 的东东, 却不能用真正的硬件配置,那么一个实际个工程文件必须修改下 controller 才能去仿真了???
      万事具备,就开始学习软件吧,从何入手呢?先找几个自己感兴趣的 问题研究研究吧。先看看变量的定义,ab 的独特之处就包括 tag 是 以名称作为关键“索引”,没有西门子那种地址的概念,这样当然简 化了开发。那么如何批量的导入/导出变量呢?我用 s7 的编程习惯是 在 excel 里面编辑好变量表,再导入到程序里面。在 logix5k 软件里 面找了下,果然可以,tools 菜单下有 import 和 export,试了下, 跟西门子的 symbol table 一样,都是以 csv 文件保存的,不过也发 现了中文注释偶尔会变“乱码”。记得看过讲关于如何解决 ab 导出 变量表的中文乱码问题,找了下这篇文章,原来乱码其实是 unicode 码,作者编了个 vb 小程序,当然也可以在 excel 里面编写个 vba 代 码,或者有人说用某网页的内码转换去解决也可以。(啥时候看看 vba 的书?)
      接下来再看看 16 版本新增的 add-on instructions,以前粗粗的研 究了下,记得是可以编写自己的模块在各个工程间重复使用。于是决 定用 st 编写一个 max3 函数,就是在三个 real 数据中找一个最大的。 先定义接口变量,ab 是在对话框里面定义,不象西门子的 scl 是完 全手工输入变量定义。模块写好以后 check 没有 error,然后在 main program 中调用,check 一下却总是报错。弄了半天,才回忆起来以


      3楼2018-08-25 09:09
      回复
        前碰到过这个事情,应该再定义一个类型为该模块的结构变量,调用 模块时填这个结构变量名就行了。然而这样的话,如果要把某个外部 io 变量或者某个内部变量单独给模块的一个输入端,岂不是要先赋 值给这个结构变量的其中一个?太麻烦了吧,也不合情理啊。再看看 接口变量的定义,发现有 req 属性,看看 help 里面的描述,再测试 了下,原来关键就在于 req 是否勾上了。勾上 req 以后,就可以用单 独的一个 tag 去填到这个参数去了。下一步就是模块如何在工程之间 复用呢?也很简单了,可以导入/导出成一个 xml 格式的文件,甚至 可以用 ie 打开,毕竟是标准的 xml 格式嘛。
        最后一个问题,是 program 的理解。以前做的笔记里面,写了默认每 个 task 下面的第一个 program 是循环执行的,其余 program 是被调 用的,测试下,果然如此。试着去修改 program 的属性,图标上面有 个“1”就表示了该 program 是被执行的。碰到了调用 program 的问 题,我找了 jsr 指令,ms 一共有三种指令:jsr、sbr 和 ret,下次 再研究吧。
        ok,今天到此为止。

        先解决上次遗留问题:JSR/SBR/RET 三个指令有何区别?
        看 help 里面描述:


        4楼2018-08-25 09:09
        回复
          该楼层疑似违规已被系统折叠 查看此楼


          5楼2018-08-25 09:10
          回复
            在 controller 属性里面可以选择串口采用 system protocol 还是
            userprotocol,后者可以支持 Ascii 协议。
            第 15章:故障处理程序,看来类似于西门子的故障 ob
            第 20章,加密程序。需要安装“rslogix5000 源保护软件”?
            16 版本的 Rslogix 不需要象手册里面说的那样再安装保护软件,而
            是直接从 tools 菜单-security-configure source protection,
            如果系统找不到密码文件(sk.dat)则要先指定一个,加密完成后退
            出 logix5000,然后把 sk.dat 文件移走就可以。需要解密的话,就
            需要指定该文件的位置。加密工程,还可以对整个 project 加密,似
            乎没有必要吧。
            学的有点乱糟糟的,总结一下前面的成果:
            1、软件安装,包括 rslogix5000、rslinx 和 rsemulate
            2、工程建立后,定义 tag,批量导入和导出,中文乱码解决,tag 的
            别名(alias)的用处,tag 的 scope 要注意;
            3、task 和 program 的概念,连续和周期 task,主 program 和
            subroutine,如何定义和调用 subroutine(jsr、sbr、ret)
            4、16 版本新增的 add-on instructions 如何定义、导出和导入
            5、编写了 st 和 fbd 的程序进行测试,有了初步映象
            6、缓存 io 的概念和用法
            7、cpu 串口的设置,可以用来 ascii 通讯――有待后面仔细研究
            8、程序的加密,某个子程序可以加密,整个 project 也可以加密
            下一步,有几个问题要研究一下:
            1、把以前在 step7 里面写的一些模块用 ab 来重写一次,熟悉一下基
            本指令的用法。
            2、故障处理程序怎么写?
            3、在线修改程序的问题

            把以前写的几个西门子 scl 模块用 ab 的 st 语言重写一遍,包括流量
            开方、小信号切除和累积。发现写起来很轻松,麻烦点的就是 ab 的
            add-on instructions 里面定义变量是填表格形式的,而西门子都
            是用文本形式自己输入的。代码就轻松多了,直接从 scl 里面 copy
            过来,check 一下有无错误,大部分语句都可以直接使用,但是在这
            里发现了几点 st 和 scl 的区别:
            1、ab 的 st 在某些方面比西门子的 scl 要严格一点,比如 bool 量的
            关键字,ab 只支持 0、1 的赋值,不支持 true、false(难道需要做
            什么设置么???),而西门子的 scl 是都支持的。又比如西门子的


            6楼2018-08-25 09:11
            回复
              return 语句,ab 不支持,查了下,return 语句是 iec61131 里面规 定的一个标准语句。而在 ab 里面,找了半天,终于找到一个替代的 指令:tnd。
              2、西门子的 in_out 和 out 区别很大,尤其是用 db 变量赋值参数的 时候,但是我没看出来 ab 的这两种参数有何区别?
              另外,ab 的 add-on instructions 调用时指定的结构变量,有点类 似于西门子的 fb 的背景 db。
              下一步,写几个包含定时器和较多复杂指令的模块,进一步看看 st 和 scl 的区别。

              关于定时器参数的用法,从工控网论坛上找到一篇帖子,写的很详细:
              ――――――――――――――――――――――――――――― ――
              RSLgix5000 中子程序的内部使用的输入、返回参数称之为“形参”, 子程序的调用者提供“实参”,以通过子程序完成某种控制要求。子 程序是由“形参”代替“实参”来执行的,对于一般的如 BOOL,DINT 等的数据类型,可以很容易地实现“实参”对“形参”的赋值。但是, 计时器等由于利用了 CPU 系统的资源,例如“时钟中断”等,因而不 能像上述类型数据那样可以用赋值的方式实现。要想使用计时器就必
              须得声明一个,以便系统能对此计时器进行操作。如果子程序的“形 参”可以是普通的计时器,那么对于 N 个子程序的调用,这个“形 参”计时器就必须实现 N 个计时器的功能,显然对于只能完成一次计 时的普通计时器是无法完成的,所以子程序中是不可能有普通计时器 作为“形参”的。这样就可以理解为什么 RSLgix5000 子程序中,不 能使用计时器作为“形参”。
              但是,众所周知,西门子 S7 系列 plc 的 Step 7 编程软件中的 FB, FC 功能块,也就是子程序,可以实现计时器作为子程序的“形参”, 这如何解释呢?其实,在 STEP 7 功能块,或者说是子程序中出现的 计时器,虽然外形和普通计时器一样,但是根据上面的论述,我们可 以确定其并非是普通计时器,而是一个“伪计时器”,真正的计时器 应该是声明的那一个,也就是作为“实参”的那一个。由此可见,每 当子程序被调用执行的时候,“伪计时器”将作为“实参”的那一个 真正的计时器的参数,诸如,计时当前时间,计时时间到等参数读入, 然后进行和普通计时器一样的操作。当然也包括将“伪计时器”的启 动条件赋值给“实参”计时器,以便使“实参”计时器启动工作。这 样就可以实现子程序中的计时器作为“形参”的功能。也是说,它的 “形参”计时器是经过特殊设计的,并非普通的计时器。
              因此,西门子 Step 7 中的子程序中的计时器,本质上依然使用了声 明过的,子程序外部的普通计时器。对于 RSLgix5000 来说,要实现 子程序中的计时器功能也是一样,使用子程序外部的计时器。


              7楼2018-08-25 09:12
              回复
                RSLgix5000 子程序使用计时器的方法
                由于在 RSLgix5000 梯形图子程序中,没有实现“形参”功能的“伪 计时器”,所以只能在全局变量中声明的计时器。为了便于在子程序 中使用这些计时器,我们将这些计时器放在数组里,这样子程序只需 一个数组下标变量,就可以使用这些计时器。但是,很遗憾,在 RSLgix5000 梯形图中是无法使用数组下标变量的,因此,我们就只 能使用 ST 即结构化文本,一种类似于 PASCAL 语言的编程工具,它提 供完整的数组支持。
                举一个例子,如果要实现 3 个计时器的时间设置工作,对于梯形图来 说,即使是使用数组,由于它不能使用数组下标变量,也只能是采用 一个一个的赋值方式,即,T[1].PRE = 1000,T[2].PRE = 1000,
                T[3].PRE = 1000 等等。如果子程序也采用一个一个赋值的方式,就 没有任何优势,还不如不使用子程序来实现,这样的子程序是毫无意 义的(不带“形参”的子程序除外)。如果采用 ST 结构化文本,由 于其数组下标可使用变量,就可以用子程序实现,子程序如下所示。 FOR I := 1 TO 3 BY 1 DO
                T[I] := 1000;
                END_FOR;
                这样就很适合子程序使用,不管是有 100 个还是 1000 个计时器,也 都只是使用这一个子程序,就可以完成所有计时器的计时时间设置工 作。由于梯形图无法完成这样的工作,因此子程序中的计时器数组的 使用,只能用 ST 结构化文本实现。
                例如有 2 个相同控制要求的设备,用子程序来实现,如果每个设备需 要使用 3 个计时器,那么需要声明含有 2×3=6 个计时器的计时器数 组。设备 1 使用前 3 个计时器,设备 2 使用后 3 个计时器。在子程序 中,设置一个 DINT 型的“形参”作为起始计时器号,例如设备 1 使 用 1,即从下标为 1 的计时器数组开始;设备 2 使用 4,即从下标为
                4 的计时器数组开始。
                需要说明的是,在 RSLgix5000 中,ST 结构化文本所用的计时器同梯 形图所用计时器不一样,在 ST 结构化文本中是 FBD_TIMER 类型,使 用时用 TONR 指令声明。
                一个实例
                我们以两个水泵的控制为例子进行说明。水泵 A 的启动输出信号为 START_A;出水阀门 A 的打开输出信号为 OPEN_A;水泵 A 启动反馈为 STARTED_A;出水阀门 A 开到位反馈为 OPENED_A;水泵 A 的启动运行 输入信号 PUMP_START_A;水泵 A 启动完成标志 PUMP_A_STARTED。水 泵 B 的启动信号为 START_B,出水阀门 B 的打开输出信号为 OPEN_B; 水泵 B 启动反馈为 STARTED_B;出水阀门 B 开到位反馈为 OPENED_B; 水泵 B 的启动运行输入信号 PUMP_START_B;水泵 B 启动完成标志 PUMP_B_STARTED。
                控制要求为水泵启动 5 秒后打开出水阀门,水泵使用 3 秒的输出脉冲 启动,出水阀门使用 6 秒的输出脉冲打开。这样每个水泵的控制,需 要 3 个计时器。
                为节省篇幅,这里省略了水泵停止部分的子程序,有兴趣的读者不妨


                8楼2018-08-25 09:12
                回复
                  例如有 2 个相同控制要求的设备,用子程序来实现,如果每个设备需 要使用 3 个计时器,那么需要声明含有 2×3=6 个计时器的计时器数 组。设备 1 使用前 3 个计时器,设备 2 使用后 3 个计时器。在子程序 中,设置一个 DINT 型的“形参”作为起始计时器号,例如设备 1 使 用 1,即从下标为 1 的计时器数组开始;设备 2 使用 4,即从下标为
                  4 的计时器数组开始。
                  需要说明的是,在 RSLgix5000 中,ST 结构化文本所用的计时器同梯 形图所用计时器不一样,在 ST 结构化文本中是 FBD_TIMER 类型,使 用时用 TONR 指令声明。
                  一个实例
                  我们以两个水泵的控制为例子进行说明。水泵 A 的启动输出信号为 START_A;出水阀门 A 的打开输出信号为 OPEN_A;水泵 A 启动反馈为 STARTED_A;出水阀门 A 开到位反馈为 OPENED_A;水泵 A 的启动运行 输入信号 PUMP_START_A;水泵 A 启动完成标志 PUMP_A_STARTED。水 泵 B 的启动信号为 START_B,出水阀门 B 的打开输出信号为 OPEN_B; 水泵 B 启动反馈为 STARTED_B;出水阀门 B 开到位反馈为 OPENED_B; 水泵 B 的启动运行输入信号 PUMP_START_B;水泵 B 启动完成标志 PUMP_B_STARTED。
                  控制要求为水泵启动 5 秒后打开出水阀门,水泵使用 3 秒的输出脉冲 启动,出水阀门使用 6 秒的输出脉冲打开。这样每个水泵的控制,需 要 3 个计时器。
                  为节省篇幅,这里省略了水泵停止部分的子程序,有兴趣的读者不妨
                  2 启动
                  TONR_TIMER[SBR_NUM + 2].TimerEnable := TONR_TIMER[SBR_NUM +
                  1].DN;//计时器 3 启动
                  SBR_OPEN := NOT TONR_TIMER[SBR_NUM + 2].DN AND
                  TONR_TIMER[SBR_NUM + 1].DN;//出水阀门打开输出信号 SBR_STARTED := SBR_OPENED; //启动完成信号
                  RET(SBR_STARTED);
                  其中,SBR 为子程序,括号内为输入“形参”,RET 为子程序返回指 令,返回输出“形参”。DN 是计时器计时时间到;TimerEnable 是计 时器的允许启动。水泵的启动采用了 3 秒的脉冲信号,出水阀门打开 使用了 6 秒脉冲信号。
                  当水泵 A 调用启动子程序时,使用的计时器从计时器数组 TONR_TIMER[1]开始;水泵 B 调用子程序时,则是从 TONR_TIMER[4] 开始使用。虽然启动子程序是同一个,但使用的计时器是不一样的, 这样就完成了在子程序中使用计时器。
                  结束语
                  由于在西门子 Step 7 子程序中已经内置了实现计时器的功能,所以 我们也有必要在 AB 的 RSLgix5000 子程序中实现计时器功能,更何况 需要有计时控制功能的子程序是大量存在的,不实现这一功能,意味 着子程序几乎没有什么用处。
                  虽然本文中的具体实现方法与 Step 7 肯定是不一样的,但本质是一 样的,都是利用了子程序外部的真实的计时器,通过真实的计时器实


                  9楼2018-08-25 09:12
                  回复
                    现计时功能。本文中,由于 RSLgix5000 无法使用“形参”,所以直 接使用了外部真实计时器,而 Step 7 则是通过“形参”间接地使用 了外部真实计时器。
                    从理论上来说,西门子的 Step 7 中的子程序,更好地体现了子程序 的优势,通过特殊设计的“伪计时器”读取真实计时器的参数值,成 功地把根本就不能将计时器作为子程序“形参”这一情况,在直观上 得到彻底改变,方便了人们的使用。
                    而在 RSLgix5000 子程序中,只能直接使用外部真实的计时器。由于 没有计时器作为“实参”和“形参”,所以无法全面体现出子程序的 优势(在计算机高级语言的程序设计中,例如“C 语言”,在子程序 中使用全局变量,被公认为是不好的。但 plc 程序有自己不同于计算 机程序的特点,不必拘泥于此)。但这也未必就是个问题,毕竟没有 “伪计时器”功能,也就节省了其可能有的内存及执行时间的开销。 如果说有不足的话,那就是使用了 ST 结构化文本,在只能使用梯形 图进行编程的情况下就不适合了。
                    ――――――――――――――――――――――――――――― ――
                    但是我是要在 add-on instructions 中使用定时器参数,上述文章 就不能完全照搬了。试了下,在 add-on instructions 的参数定义 里面可以直接定义一个定时器数组,当然类型不能是 input 或者
                    output,从这里我发现了 in-out 参数的作用,就是可以定义为结构
                    变量、数组变量等复杂型的数据。
                    然后在程序里面写代码了,我直接从 tonr 指令的 help 里面贴了代码
                    过来,居然出错,ft!!!
                    终于发现 help 中关于 tonr 指令的 st 写法是错的,原文如下:
                    ------------------
                    TONR_01.Preset := 500;
                    TONR_O1.Reset := reset;
                    TONR_01.TimerEnable := limit_switch1;
                    TONR(TONR_01)
                    timer_state := TONR_01.DN;
                    ------------------
                    第一句居然是错的!!!应该是 TONR_01.Pre := 500;我这个汗啊!!!
                    此外,想起来曾经看到资料里面说 controllogix 的定时器数量只受
                    cpu 运算能力的限制。看这种定时器的写法,就是定义一个定时器类
                    型的变量而已,感觉怪怪的,或许是习惯了西门子那种要指定定时器


                    10楼2018-08-25 09:12
                    回复
                      号的做法吧。Ab 的变量,不管是普通的数据类型还是特殊的定时器、
                      计数器都是起个名字就行了,方便啊。
                      接下来,我又想到了研究一下在 Add-on instructions 中调用另外一
                      个 Add-on instructions 方法,试了一下也不难:
                      1、假设在名为 Getmin 的 Add-on instructions 中需要调用一个名为
                      Min3 的 Add-on instructions,则首先在 Getmin 中定义一个类型为
                      Min3 的 In_out 参数(因为 input/output 类型的参数不接受结构型
                      变量),例如叫 in1;
                      2、在 Getmin 中用如下语句调用:Min3(in1);即可
                      跟以前调用子程序不同的就是,需要指定一个结构变量而已-又让我
                      想起了西门子的 fb。

                      试着写一个稍微复杂点的 add-on instructions,logic 检查无误,
                      run 起来却出错了,提示我这个错误:
                      (Type04) Program Fault (can be trapped by a fault routine)
                      (Code86) Access violation in user program.
                      Task:MainTask
                      Program: MainProgram
                      因为 mainprogram 只调用了这一个 add-on instructions,检查到 最后把所有 logix 语句都注释掉了还是错,看来是接口参数问题了, 最后发现是定义的一个数组类型的 in-out 参数引起的,只要定义了 数组参数就报错,昏!!!去查手册,里面明明说是可以的,而且还 给出了例子,why?折腾半天也没结果,我开始怀疑 rslogix5000 或 者是 emulate 的软件本身了,或许换个高点的版本???可惜一时找 不到啊。于是找来手册细细的看下去。
                      在查阅手册的过程中,发现 add-on instructions 有不少缺点,比 如有不少指令不能用,比如 for 指令,这让我大吃一惊。For 指令不 能用的话,循环怎么办?数组的操作呢?我不相信 for 指令不能用, 尝试了下,居然可以啊,咋回事?可惜身边没有一台实际的 plc 让我 测试下,否则前面的数组参数问题也可以得到印证!!!这两天折腾 add-on instructions,越来越发觉这个东西做的很不成熟,后面再 一一总结罗列出来吧(本来我对 ab 的东西感觉挺好,觉得是那种比 较“高贵”的东东,现在折腾几天下来,却感觉在给工程师进行模块 化、标准化的开发环境方面,相对 s7 来说,ab 做的实在是比较差
                      啊―――当然这也跟我刚刚开始学习 ab 有关系吧,总是带着西门子 的眼镜来要求 ab 的东东)。

                      一直没有解决前面的 add-on instructions 的数组参数问题,所以都 没心思继续研究雪鞋下去了,这个问题太打击人了。


                      11楼2018-08-25 09:13
                      回复
                        今天想想还是找点其它事情做吧,于是就翻翻下载的《华章 AB 实验
                        教程》,发现太简单了,跟去年培训的内容基本雷同。
                        ――――――――――――――――――――
                        实验 1:
                        主要议题:
                        -认识各模块
                        -RIUP
                        -通讯建立
                        其实就是 rslinx 的配置和使用。rslinx 的优点是配置简单,还能直
                        接扫描出硬件配置,不过版本要注意。
                        实验 2:
                        主要议题:
                        -强大的编程能力
                        -面向未来的投资
                        所谓“强大的编程能力”,实验教材中体现为:
                        --io 配置后自动生产丰富的信息,包括 IO 数据、故障信息、时标
                        等等,确实很好很强大
                        --可以查看在线的数据趋势
                        所谓“面向未来的投资”,恐怕指的就是 logix 的固件升级和统一的
                        软件平台吧。
                        实验 3:
                        主要议题:
                        -代码重用
                        -节省开发投资
                        -系统规模可大可小
                        其实就是修改 controller type,从 controllogix 改为
                        compactlogix,体现了“面向未来的投资”
                        实验 4:
                        创建一个项目,控制变频器的频率。这就涉及到了 rsnetworx 这个网
                        络组态软件。
                        去年培训做个这个实验,确实很简单、方便。
                        实验 5:


                        12楼2018-08-25 09:13
                        回复
                          --io 配置后自动生产丰富的信息,包括 IO 数据、故障信息、时标
                          等等,确实很好很强大
                          --可以查看在线的数据趋势
                          所谓“面向未来的投资”,恐怕指的就是 logix 的固件升级和统一的
                          软件平台吧。
                          实验 3:
                          主要议题:
                          -代码重用
                          -节省开发投资
                          -系统规模可大可小
                          其实就是修改 controller type,从 controllogix 改为
                          compactlogix,体现了“面向未来的投资”
                          实验 4:
                          创建一个项目,控制变频器的频率。这就涉及到了 rsnetworx 这个网
                          络组态软件。
                          去年培训做个这个实验,确实很简单、方便。
                          实验 5:
                          没看到相关资料的权威叫法),于是猜想就是该字符串的长度,于是
                          在程序里面直接把该“属性”赋值给输出参数,测试一下,果然就是
                          啊。接下来看看如何把字符串分解然后颠倒过来,本来想当然的要去
                          找字符串函数(vb 的思路),结果看了下 string 数据的结构,还有
                          一个 data 数组,看来就是存储字符的,大喜,这下更 easy 了。用
                          st 写吧,定义的参数如下:
                          输入――IN1(DINT)
                          输出――OUT1(DINT)
                          LOCAL――TEMP_STR1,TEMP_STR2(STRING)/I,STR_LEN(INT)
                          开始代码是如此写的:
                          DTOS(IN1,TEMP_STR1);
                          STR_LEN:=TEMP_STR1.LEN;
                          IF STR_LEN>1 THEN
                          FOR I:=1 TO STR_LEN BY 1 DO
                          TEMP_STR2.DATA[I-1]:=TEMP_STR1.DATA[STR_LEN-I];
                          END_FOR;
                          STOD(TEMP_STR2,OUT1);


                          13楼2018-08-25 09:14
                          回复
                            OUT1:=IN1;
                            END_IF;
                            发现输出一直为 0,很郁闷。开始怀疑 for 是否执行了,因为看手册
                            里面说 add-on 不支持 for 指令,虽然前面曾经模拟过程序,表明 for
                            是可以执行的。后来又怀疑开始相信的 len“属性”,发现都没问题。
                            最后,我突然想到 TEMP_STR2 的 len 属性,发现居然是 0!!!my god!
                            再加一句话给 TEMP_STR2 的 len 赋值就 ok 了,最后代码如下:
                            DTOS(IN1,TEMP_STR1);//输入数据转换为字符串
                            STR_LEN:=TEMP_STR1.LEN;//取得字符串长度
                            TEMP_STR2.LEN:=STR_LEN;//转换后的字符串长度
                            IF STR_LEN>1 THEN//转换字符串
                            FOR I:=0 TO STR_LEN-1 BY 1 DO
                            TEMP_STR2.DATA[I]:=TEMP_STR1.DATA[STR_LEN-I-1];
                            END_FOR;
                            STOD(TEMP_STR2,OUT1);
                            ELSE
                            OUT1:=IN1;
                            END_IF;


                            14楼2018-08-25 09:14
                            回复
                              大哥,求Logix500安装包,有吗?


                              IP属地:广东来自Android客户端16楼2019-01-01 23:04
                              回复