
简介面向西门子控制系统开发者的S7-1500流量累积数据处理案例基于博途STEP7环境编写覆盖流量信号采集、累积量计算、数据归档与数值显示等典型工业场景。资源包共9个文件包含XML工程配置、AP13博途项目文件、PLF与IDX索引数据以及PMA备份文件整体压缩包仅4.61MB目录结构清晰便于快速定位程序和辅助数据。项目中代码已经过运行验证功能稳定可直接下载参考既适合PLC初学者理解博途编程思路与累积算法实现也可为自动化、物联网、电子信息等专业学生的课程设计、毕业设计提供现成工程模板还可作为初期项目立项演示的基础版本。已有213人学习浏览下载后可按自身基础修改参数或扩展功能进一步用于实际项目二次开发。欢迎下载交流。1. 博途下的S7-1500流量累积先从“累积”两个字讲透流量累积是工业现场最常见的计算需求之一管道里流过的水、蒸汽、燃气瞬时流量只是“速度”真正用于贸易结算、物料衡算和效率统计的是“这班产线到底过了多少量”。S7-1500配合博途TIA Portal做这件事表面上就是把瞬时流量乘一个时间量再累加但真正落地时很多工程师栽在三个地方单位换算错一位、扫描周期不固定导致累积误差、掉电后累计值归零。这篇博文就从S7-1500的博途编程出发把流量累积的数据模型、程序结构、保持性设置和调试验证完整过一遍既给可直接抄的SCL代码也把精度和边界条件讲清楚。适合手里有S7-1500项目、被“累积不准”或“累积量回零”困扰的博途使用者也适合从经典STEP7转向TIA Portal的人。2. 流量累积程序的数据模型从瞬时流量到累计流量单位与精度先算清楚2.1 累积的本质是积分PLC里按“面积”累加流量累积在数学上是瞬时流量对时间的积分。PLC不能做连续积分只能按固定周期采样每个周期把“瞬时流量 × 周期时间”当成一片面积加到之前的累计值上。这个近似是否准确取决于采样周期是否恒定、瞬时流量波动是否剧烈。S7-1500的循环中断OBCyclic Interrupt OB可以配置1ms到若干秒的固定周期比在OB1里靠扫描周期累加可靠得多。理由很直接OB1的扫描时间会随程序大小和通信负载浮动哪怕只差几毫秒一天下来累积误差也可能被放大到不可接受。我一般会把累积计算放在循环中断OB里周期设为100ms到1s不要在OB1里用系统时钟去“蹭”时间。如果项目中已经有PID、阀门控制等实时任务建议把流量累积单独放到一个中断OB避免被其他程序段延长扫描周期。下面的公式是程序的核心逻辑当前周期累积量 瞬时流量(单位时间) × 循环中断周期时间 累计值 当前周期累积量这里有个容易忽略的点循环中断OB的周期是固定配置值但实际执行时仍有微小抖动S7-1500的时钟分辨率足够高如果要求很高可以用系统运行时间RT_INFO中的运行时间来计算实际周期差而不是直接用配置周期。后面第6章会给出具体做法。2.2 单位换算m3/h 与 L/min以及累积脉冲当量流量计输出的瞬时流量常见单位有m3/h、m3/s、L/min、t/h。累积前必须先归一化到“每秒流量”否则程序里的“乘以周期秒数”就会完全错误。不少人直接把仪表显示的瞬时值拿来乘周期结果1000方的管道一天累积出几百万方就是因为没做单位换算。下面这张表是常用的换算关系建议在程序里用一个独立的FC或全局变量集中管理不要散落在多个FB里。原始流量单位转换为“每秒”的乘数举例瞬时值为100m3/h1 / 3600100 m3/h 0.0277778 m3/sm3/min1 / 60100 m3/min 1.66667 m3/sL/h1 / 3600000100 L/h 0.0000278 m3/sL/min1 / 60000100 L/min 0.0016667 m3/st/h需要介质密度换算100 t/h 需先除以密度得到m3/h2.2.1 把量程转换放在累积之前现场模拟量流量计一般输出4-20mA或0-10VPLC侧先通过NORM_X和SCALE_X把原始值变成功值。这一步也要确认量程上限对应的是哪个单位。我见过一个案例变送器量程是0-2000 m3/h但DCS组态时填成了0-20000 m3/hSCALE_X输出直接大了10倍累积量自然离谱。所以量程转换结束后立刻在程序中加一个上下限限幅超出量程就保持上一周期值或者直接报警这比事后查数据要省力得多。2.3 浮点数的精度边界REAL够不够用什么时候换LREALS7-1500的REAL是32位浮点数有效数字约7位。如果累积量从0开始显示到小数点后2位那么累计到100万方时浮点表示的分辨率大约只有0.125方左右继续累加时较小的增量可能被舍入掉。对于大型罐区或长周期累计这会造成“数值不再变化”的现象。S7-1500也支持LREAL即64位浮点数精度约15位有效数字。对于多数流量累积场景REAL已经够用但遇到下面情况我宁愿直接用LREAL累计量可能超过100万方且需要保留小数点后多位瞬时流量变化范围很大比如从0.1到10000 m3/h跨越5个数量级长时间无人清零、跨月累计且用于结算类统计。代价是LREAL运算比REAL慢一点占用DB空间多一倍但S7-1500的CPU性能完全承担得起。如果程序里同时用REAL和LREAL做计算注意隐式转换规则博途的SCL通常不允许隐式转换需要显式REAL_TO_LREAL否则编译报错。#accValue : #accValue REAL_TO_LREAL(#instFlow) * #cycleTimeSec;这里的#accValue声明为LREAL#instFlow是REAL#cycleTimeSec是REAL显式转换避免类型冲突。参数#cycleTimeSec应传入循环中断OB的实际周期秒数例如100ms对应0.1。3. 在博途TIA Portal中建FC块还是FB块流量累积的SCL实现3.1 为什么用FB而不是FC背景数据块与保持性经典STEP7里做流量累积很多人习惯用FC加全局DB因为FC不占背景数据块。但在博途S7-1500项目里我强烈建议用FB函数块。理由有三第一FB的接口变量和多实例、单实例背景DB天然内聚调用多次也不会互相干扰第二FB的静态变量可以单独设置保持性流量累积值作为静态变量掉电保持配置非常简单而FC必须在全局DB里做符号定义和保持范围管理第三博途的FB支持SCL语言写累积逻辑比梯形图直观得多。FB调用时需要分配背景DB常见的做法是在OB30循环中断里调用FB背景DB选择“单实例”即可。如果项目中有多路流量可以用多实例把每个流量的FB实例嵌入到一个调用FB的静态变量里不过这只是工程组织问题不影响核心算法。3.2 一个可直接抄的FB_FlowTotalizer接口与参数表下面是我常用的流量累积FB接口。参数尽量做成外部可写方便HMI直接修改量程、单位或复位命令。FUNCTION_BLOCK FB_FlowTotalizer { S7_Optimized_Access : TRUE } VERSION : 0.1 VAR_INPUT rawValue : REAL; // 瞬时流量已经做过量程转换 unitFactor : REAL : 1.0; // 单位换算系数转换为“每秒流量”的乘数 cycleTimeSec : REAL : 0.1; // 循环中断周期单位秒 resetFlag : BOOL : FALSE; // 复位/清零命令 flowLowLimit : REAL : 0.0; // 小流量切除下限 END_VAR VAR_OUTPUT totalValue : LREAL; // 累计流量 cycleIncrement : LREAL; // 本周期增加的流量 overflowFlag : BOOL; // 溢出或者上限标志 END_VAR VAR_STATIC lastResetMode : BOOL; // 上一次复位命令状态用于上升沿检测 END_VAR VAR_TEMP normFlow : REAL; END_VAR参数说明rawValue严格讲是“已转换为工程量单位的瞬时流量值”比如0-2000 m3/h对应的浮点数unitFactor把该单位变成每秒流量比如m3/h对应1/3600cycleTimeSec必须与调用FB的循环中断周期一致这是累积精度的基准resetFlag为TRUE的上升沿将totalValue清零flowLowLimit用于小流量切除低于该值时不计入累积避免管道漏流和传感器漂移被累加。3.2.1 背景DB的保持性与优化访问S7-1500默认启用“优化块访问”背景DB在创建时默认“仅非保持”。要改成保持需要取消勾选“仅非保持”然后对需要保持的变量勾选“保持”。注意博途的保持性设置在“属性 保持性”里不是像S7-300那样在DB中定义保持范围。这个差异是经典STEP7用户从V5.x转向博途时最容易卡住的地方后面第4章会详细展开。3.3 SCL代码扫描周期、量程转换、累积、复位一个都不能少下面是可以直接使用的SCL完整代码。代码里做了小流量切除、复位上升沿、单位换算和限幅判断。// STEP 1: 小流量切除低于下限的瞬时流量按0处理 IF #rawValue #flowLowLimit THEN #normFlow : 0.0; ELSE #normFlow : #rawValue; END_IF; // STEP 2: 复位命令上升沿检测 IF #resetFlag AND NOT #lastResetMode THEN #totalValue : 0.0; END_IF; #lastResetMode : #resetFlag; // STEP 3: 单位换算并累加 #cycleIncrement : LREAL_TO_REAL(#cycleTimeSec) * #normFlow * #unitFactor; #totalValue : #totalValue LREAL_TO_REAL(#cycleIncrement); // STEP 4: 溢出标志累计量超过某个业务上限时置位 IF #totalValue 1.0e12 THEN #overflowFlag : TRUE; ELSE #overflowFlag : FALSE; END_IF;这段代码的执行顺序是有讲究的先切除小流量再检测复位然后累加。如果把复位放在累加后面那么在复位命令触发的那一个周期旧累计值仍然会被加一次虽然差值很小但结算场景下这就是“未清零干净”的投诉点。LREAL_TO_REAL转换是因为#cycleIncrement被定义为LREAL如果外部监控表需要实时观察REAL也够用。语句LREAL_TO_REAL(#cycleIncrement)在这里取的是LREAL累加量的低32位浮点近似仅作为显示用途真正的累计值始终是LREAL。3.4 在OB30循环中断里调用别把累积写在OB1里3.4.1 调用与背景DB分配在博途项目树中双击“添加新块”选择“组织块”类型选“循环中断”编号建议使用OB30时间间隔设100ms。然后在OB30里拖入FB_FlowTotalizer系统会弹出“调用选项”选择单实例并创建背景DB例如DB_FlowTotalizer。调用时把瞬时流量地址、周期时间常量、复位位等连接好。DB_FlowTotalizer( rawValue : HMI_Tag_DB.InstantFlow, unitFactor : 0.000277778, cycleTimeSec : 0.1, resetFlag : HMI_Tag_DB.ResetTotal, flowLowLimit : 0.05 );这里HMI_Tag_DB.InstantFlow来自HMI数据块通常由模拟量输入处理OB写入。unitFactor填0.000277778就是m3/h转换为m3/s的系数1/3600。如果一个项目里有多路流量就在OB30里多次调用同一个FB每次分配不同的背景DB互不干扰。3.4.2 循环中断时间设置的注意点循环中断的最小周期取决于CPU型号和程序负载。S7-1500标准CPU可以做到1ms但流量累积不需要这么快我一般选100ms到1s。周期太短会频繁执行浮点运算浪费CPU周期太长则会在瞬时流量快速变化时丢失细节。在实际项目中如果瞬时流量来自电磁流量计4-20mA信号本身有阻尼100ms采样足够如果是质量流量计输出脉冲则可以用更高频的计数方式不推荐用浮点累积代替硬件计数器。提示 循环中断的时间间隔必须在“组织块属性”中设置不能像OB1那样在程序里改写。修改后应重新下载硬件配置或块不要只下载软件否则实际周期不生效。4. S7-1500累积值掉电保持博途的保持性变量与断电处理4.1 保持性Retain vs 非保持S7-1500的NV区分配流量累积值最怕断电丢失。S7-1500系列CPU不依赖电池保存保持性数据而是使用内置的NVRAM非易失性存储器保存。博途中的保持性变量在掉电时会自动写入NVRAM而不是像S7-300那样依赖外部后备电池或MMC卡。这个区别让很多从S7-300转过来的工程师困惑明明没有电池为什么数据还在正因为S7-1500的硬件存储机制不同所以保持性变量完全是软件属性设置错了就会丢。保持性设置在单个变量的“属性”里勾选或取消。一个DB里可以部分变量保持、部分变量非保持。需要明确的是保持性变量会占用额外的存储空间和保存时间不要全DB无脑勾选保持尤其不要为临时变量或输入输出变量设置保持。4.2 在DB里设置保持性的步骤以FB的背景DB为例操作路径打开背景DB在左侧“保持性”列对需要断电保持的变量“totalValue”和“lastResetMode”勾选保持。如果找不到“保持性”列检查DB属性是否勾选了“优化块访问”优化访问的DB在属性对话框的“保持性”选项卡里逐项勾选非优化访问的DB则在变量列表上直接点击“保持性”列。注意S7-1500推荐使用优化访问所以多数情况是打开DB后在上方菜单栏点击“监视”然后选择要设保持的变量再在下方“属性 保持性”中勾选。DB_FlowTotalizer totalValue - 属性 保持性: 保持 lastResetMode - 属性 保持性: 保持 cycleIncrement - 属性 保持性: 非保持cycleIncrement只是显示用不需要保持。lastResetMode必须保持否则掉电重启后resetFlag的上升沿状态可能被重置导致重启后第一个周期误触发复位把累积量清零。这是一个很隐蔽的坑如果复位信号一直为TRUEPLC断电重启FB首次运行时lastResetMode默认FALSE而HMI上的复位按钮还是TRUE程序就会把累积量清零。4.3 掉电重启后如何判断累积值是否可信启动OB里做标记仅设置保持还不够。现场设备可能会在断电期间被拆走、流量计被校准、管道被吹扫这些情况下保持的累积值已经失去业务意义。更稳妥的做法是在启动组织块OB100中写一段初始化逻辑把“上次停机时间”和“本次启动时间”记录下来HMI/上位机对比停机时长来决定是否沿用累积值。// OB100 启动OB DB_FlowTotalizer.lastResetMode : FALSE; DB_SystemInfo.powerOnTime : RD_SYS_T(T#0MS);这里RD_SYS_T读出的系统时间首次上电会显示为一个很大的内部时间值。建议在HMI里显示“停机时长”如果超过工艺允许的离线时间就要求操作员手动确认累计值是否继续使用。4.4 注意没有电池的S7-1500如何保证数据不丢S7-1500的保持性数据存储在CPU的NVRAM中写入次数有限但正常寿命足够长。频繁写入保持性变量会缩短NVRAM寿命尤其是每次扫描周期都变化的变量不要设置为保持。流量累积值每秒或每个中断周期都在变化如果每个周期都写NVRAM开销很大且不必要。博途的处理方式是保持性变量在变化后由系统在掉电时或后台自动保存而不是每个扫描周期同步写。为了减小NVRAM写入压力可以让累积值在内存中运行每隔一段时间例如每分钟将中间值复制到另一个保持性变量中。不过S7-1500的硬件设计中保持性变量本身就是断电保存所以多数场景直接勾选保持即可不必为此专门做双重缓冲。5. STEP7习惯转博途的坑经典S7-300代码不能直接搬到S7-15005.1 经典Step7的FC在博途里需要改什么标题里出现“STEP7案例”很多搜索者其实是把经典STEP7 V5.x与博途里的STEP 7搞混了。S7-1500只能使用TIA Portal博途中的STEP 7 Professional经典STEP7 V5.6根本无法为S7-1500组态程序。如果你只有STEP7 V5.6的旧程序不能直接打开更不可能下载到S7-1500。通常做法是手动将FC/FB的逻辑翻译成SCL或LADDER再重新分配硬件配置。翻译时最容易出错的点是定时器经典STEP7的S5T格式和定时器编号T1、T2在博途中改成了IEC定时器例如TON、TOF需要重新插入定时器实例。系统功能SFC/FC编号很多SFC在S7-1500中不存在或换名比如SFC100等。地址区S7-300的M区、DB块在S7-1500中仍可用但S7-1500的I/O访问需要指定从站的访问路径。模拟量模块的地址S7-1500默认使用优化硬件配置模拟量输入起始地址可能和旧程序不同必须重新映射。5.2 定时器、OB编号和符号访问的差异经典S7-300的OB35是循环中断而S7-1500默认也支持OB30、OB31等多路循环中断。旧程序如果写成OB35调用博途里也能用但不建议延续这个习惯。S7-1500的符号访问极其方便建议在程序中使用绝对地址时保留注释便于从STEP7转来的程序员阅读。下面的表格列出几个关键差异多数新手会踩到项目经典STEP7 V5.x博途TIA Portal S7-1500程序块格式源文件为AWL/STLSCL/STL/LAD/FBD块类型一致背景DB保持DB中定义保持区域变量属性中单独勾选循环中断OBOB35固定OB30-OB38可配置访问方式绝对地址为主符号访问优先绝对地址兼容下载方式PLC Download在线 下载到设备需选择“硬件和软件”5.3 博途PG/PC接口无网卡选项怎么办与下载调试的3个必查项热词里“博途PGPC接口无网卡选项”是搜索量很高的坑。S7-1500使用PN接口下载程序如果博途的“PG/PC接口”下拉列表里找不到网卡通常不是网卡驱动坏了而是权限问题或用错了访问模式。检查三个地方第一安装博途时是否选择了“工业以太网”相关组件第二当前Windows用户是否为管理员UAC是否开启访问保护第三网卡的TCP/IP属性里需要启用“SIEMENS 工业以太网”相关协议但注意不要手动设置优先级。如果是纯S7-1500项目博途默认使用“PN/IE”接口选择当前使用的物理网卡比如Realtek PCIe GbE Family Controller不要选“Any”开头的选项。“无网卡选项”多见于虚拟机环境解决办法是把VMware网卡设置改为桥接模式并关闭VMware的防火墙过滤。如果还是看不到在博途项目树里右键“在线访问”把设备分配一遍再打开PG/PC接口就正常了。6. 验证与进阶用监控表和PLC仿真把累积误差控制在0.1%以内6.1 仿真器里的“假流量”怎么验证累积结果一致博途内置的PLCSIM仿真器支持S7-1500项目。在仿真器中验证流量累积核心做法是给FB一个恒定的瞬时流量然后观察固定时间内的总累计值。比如瞬时流量设置为3600 m3/h循环中断周期100ms单位换算系数1/3600那么10秒钟后累计值应该接近10 m3。如果偏差超过0.1%优先怀疑周期时间不匹配。打开仿真器后通过变量监控表强制rawValue : 3600.0cycleTimeSec : 0.1然后记录电脑系统时间等10秒后读取totalValue。理想值计算如下每秒钟累积量 3600 / 3600 1 m3/s 10秒后累计值 1 × 10 10 m3如果结果偏大或偏小检查unitFactor是否写错或者循环中断实际周期与设置的100ms不一致。S7-1500 CPU自带实时时钟但PLCSIM运行在PC上周期精度受电脑负载影响我一般允许±2%以内的偏差如果是真实PLC这个偏差应该在±0.05%之内。6.2 三个必调参数扫描时间、最小流量切除、复位延迟这三项是在现场调试中最常调整的参数直接决定最终统计数据的可信度。参数位置调整依据循环中断周期OB30属性瞬时流量波动大时取100ms平稳流量取1s最小流量切除FB接口flowLowLimit取仪表量程的1%-2%低于它不算累积复位延迟HMI里做成确认按钮防止误触要求操作员按住1秒以上再触发flowLowLimit的设置要小心。设置太大正常小流量时段被切除累计值偏小设置太小流量计零漂被累计管道停用期间数字还慢慢涨。常见做法是取流量计量程的1%。例如量程2000 m3/h下限设20 m3/h低于20时视为零流量。对于贸易计量这个值应在仪表文档中明确不能只靠现场拍脑袋。复位延迟最好在HMI侧实现PLC侧只接收一个瞬时BOOL信号。在HMI画面中组态一个“累计清零”按钮按下后启动定时器比如1秒后置位resetFlag松开时取消。这一步能有效防止误触。6.3 用S7-1500的实际硬件时钟算累计时间差有的项目对周期抖动非常敏感比如瞬时流量变化率极高或者需要做认证级计量。那么不要用循环中断配置的标称周期而是用实际周期计算。S7-1500自带的RT_INFO功能块可以读取CPU运行时间也可以在循环中断OB的START接口中拿当前系统时间。但常见的做法是配合一个1ms或1s的IEC定时器做时间戳在FB内部计算两次调用之间的实际时间差。// 在FB内部新增两个静态变量 // lastTime : LTIME // actualDeltaTimeSec : REAL #actualDeltaTimeSec : LTIME_TO_REAL(T_DIFF : RT_CLOCK(TRUE));这里简化的思路是每次调用时读取当前时间与上一次调用时间做差得到实际经过的秒数用这个秒数替代cycleTimeSec。由于S7-1500的RT_CLOCK或RD_SYS_T调用本身也有开销这种方法在几毫秒级别意义不大但用在100ms周期的循环中断上可以消除配置周期与实际周期之间的系统偏差。需要提醒的是这样做会增加程序复杂度和运行时间不是所有项目都值得。对于常规生产统计固定周期的100ms已经足够对于贸易结算建议不要依赖PLC浮点累积应使用流量计算机或流量计的硬件累积功能。现场验证时最好的方式是用一块秒表同时作为流量计的累积计数器和PLC累计值对拍。在10分钟内连续比较如果偏差稳定在一个方向上优先检查单位系数如果偏差无规律则检查循环中断是否被高优先级中断卡顿或者瞬时流量是否在小流量切除线附近震荡。前者的典型现象是累计值偏小且误差随时间增大后者的典型现象是累计值在小流量时段几乎不变但偶尔跳增。把上述参数表打印出来逐项排查流量累积这个看似简单的功能就能稳定跑完一个检修周期。本文还有配套的精品资源点击获取