开头就不废话了,直接进入正题。现在拿1200PLC练中断的,多数还在OB10、OB20时间中断和OB40硬件中断里打转。这个练习我之前也卡过一阵子,特别是模拟量模块的中断,手册翻了好几遍才发现门道在模块组态里。这篇笔记把我在SM1231模拟量输入模块上做中断练习的完整过程、参数设置和踩坑经历都整理出来,适合刚把1200PLC基础指令玩熟、准备往中断这块深入的朋友。
1. 整体方案设计与核心思路拆解
1.1 为什么要单独练模拟量模块中断
模拟量中断和数字量中断有个本质区别:数字量输入变化是瞬时的电平跳变,而模拟量数值是连续变化的,不存在明显的“边沿”。想让PLC在模拟量越限时立刻反应,常规做法是在OB1里写比较指令,每个扫描周期轮询一遍通道值。但这样做有两个问题:一是扫描周期可能在几毫秒到几十毫秒之间波动,碰到要求快速切断或快速报警的场合,响应不及时;二是如果程序特别长,OB1周期被拉长,轮询的实时性就更没法保证。
模块中断的思路是把“监视”这件事从CPU里挪出来,交给模拟量模块的硬件电路去处理。SM1231这类模块内部有比较器,通道值超过设定上下限时,模块直接往CPU发硬件中断请求,CPU响应后立刻执行对应的OB块。这种模式下,CPU不用每个周期跑一遍比较逻辑,响应速度也远快于扫描周期。
我最早做这个练习时走的是OB1轮询路线,后来真正接触中断才明白,模拟量模块中断适合用在需要“越限立即动作”的场景,比如温度过高切断加热、压力过低停泵、流量超限报警这些。物料搬运、包装产线这类对响应时间不敏感的场景,轮询就够用,没必要把中断的复杂度引入系统。
1.2 这个练习要解决的核心问题
做这个练习时,我把它拆成了三个问题来验证:
第一,模拟量模块在什么条件下触发中断。这决定了模块参数的设置方式。SM1231模块的每个输入通道都支持设置上限和下限,信号超出设定范围时触发模块中断。但需要注意,这个上限和下限的单位不是工程量而是原始值,也就是模块AD转换后的数值,4到20毫安信号对应0到27648,具体对应关系后面详细讲。
第二,中断触发后CPU该执行什么程序。S7-1200的硬件中断OB是OB40,模拟量模块触发的中断也归它管。需要在OB40里写处理逻辑,同时要能在程序里区分是哪个通道触发的中断,以及是上限还是下限触发的。这个信息存储在OB40的临时变量里,格式是HW_IO和POINT_ADDR,后面会详细说明。
第三,中断响应时间到底能到多少。理论上硬件中断的响应时间远快于扫描周期,但实际项目里很少有人测这个数据。我这次用CPU的日期时间指令记录中断发生时刻,做了几组对比测试,实测结果后面贴出来。
1.3 选型与方式取舍
我手里的CPU是S7-1200 1214C DC/DC/DC,固件版本V4.4,模拟量模块用的是SM1231 AI 4x13 bit,也就是4通道13位精度的模拟量输入模块,支持0到10伏电压和0到20毫安、4到20毫安电流信号。这款模块支持上下限中断功能,也是这次练习要用到的核心功能。
其实做模拟量越限报警还有一种方式——在OB1里用NORM_X和SCALE_X指令把原始值转成工程量后做比较。这种方式的优点在于直观、好调试,CPU资源占用也不高;缺点就是受扫描周期限制,最坏情况下的响应时间等于一个完整扫描周期,有些现场设备对响应时间有硬性要求,轮询就扛不住了。
模块中断的方式虽然响应快,但也有一些限制。比如每个模拟量通道只能设一组上下限,而且组态时必须把测量范围定好,通道的中断使能要在模块参数里打开。另外,中断OB里的程序要尽量短小,因为中断OB执行时会打断OB1的正常扫描,占用的是CPU的中断处理时间。中断服务程序写得太长,反而会影响系统整体的扫描效率。这些取舍在做方案时要提前想清楚。
2. 模拟量模块组态与中断参数配置
2.1 SM1231模块的硬件连接与地址分配
先用一张简洁的表格把这次使用的硬件配置列出来,方便后面一步一步对照操作。
| 项目 | 参数 |
|---|---|
| CPU模块 | CPU 1214C DC/DC/DC,固件V4.4 |
| 模拟量模块 | SM1231 AI 4x13 bit,订货号6ES7231-4HD32-0XB0 |
| 信号类型 | 4到20毫安电流信号(两线制变送器) |
| 通道分配 | 通道0接温度变送器,通道1接压力变送器 |
| 模块起始地址 | IW64(取决于在组态中的安装位置) |
这里要提醒一下,SM1231的地址分配是按槽位自动生成的,在博途的设备组态界面选中模块后,能看到“I地址”和“Q地址”一栏,默认情况下第一个模拟量输入通道占用IW64,第二个是IW66,依次类推。地址可能因组态环境不同会有差异,实际操作时以博途里显示的为准,不要把地址写死。
接线方面,SM1231的每个输入通道有正负两个端子,两线制变送器的正极接模块的通道正端,负极接模块的通道负端。这里有个容易踩的坑:两线制变送器需要外部供电,使用模块自带的24V传感器电源时,变送器的电源正极要接在供电端子上,而不是直接接到模拟量输入正端,否则变送器没有工作电压,信号自然出不来。
2.2 模块参数设置中的测量类型与中断配置
这是模拟量中断练习最关键的一步。在博途的“设备组态”中选中SM1231模块,下方会出现模块属性窗口。需要设置的核心参数有三个:
第一个是“测量类型”。SM1231每个通道都可以独立设置测量类型,支持电压和电流两大类。电流类型里又分为0到20毫安和4到20毫安两种。我用的变送器是4到20毫安输出,所以测量类型选“电流”,测量范围选“4到20 mA”。这一步如果选错,通道值要么一直是满量程,要么一直在零位附近,排查起来很费时间。
第二个是“上下限值”。在模块属性的“输入”选项卡里,每个通道都有“上限值”和“下限值”这两个参数。注意这里的单位不是毫安或摄氏度,而是原始值。在4到20毫安量程下,模块AD转换后的原始值范围是0到27648,其中4毫安对应0,20毫安对应27648。比如温度变送器量程是0到100摄氏度,4到20毫安对应线性关系,那么要设置80摄氏度为上限,对应的原始值就是27648乘以0.8,约等于22118。下限同理。
第三个是“中断”使能。在模块属性里勾选“硬件中断”选项,让模块在通道值越限时向CPU发出中断请求。如果这个选项没勾选,前面设置的上下限值就只作为诊断信息使用,不会触发中断。
2.3 原始值与工程量的换算逻辑
模拟量模块的原始值到工程量是线性映射关系,公式如下:
工程量 = 上限工程量 + (原始值 - 下限原始值) × (上限工程量 - 下限工程量) / (上限原始值 - 下限原始值)
拿4到20毫安、0到100摄氏度的变送器举例:4毫安对应原始值0、工程量0摄氏度,20毫安对应原始值27648、工程量100摄氏度。PLC读到的原始值为13824时,对应工程量是50摄氏度。
在1200PLC里,推荐用NORM_X和SCALE_X指令做这个换算:
- NORM_X把原始值标准化到0到1之间的实数
- SCALE_X把0到1之间的实数映射到指定的工程量范围
比如说,通道0读到IW64,先用NORM_X,参数MIN填0,MAX填27648,得到0到1之间的标准化数值,再用SCALE_X把标准化数值映射到0.0到100.0的浮点温度值。这个换算方式在中断程序和普通轮询程序里写法一致,方便复用。
在实际项目里,很多工程师图省事直接用手算公式的方式写浮点运算指令,效果也一样。但用NORM_X和SCALE_X的好处在于程序可读性好,后来接手的人一看就知道量程范围在哪里,少走弯路。
3. 中断组织块OB40的编程实现与运行机制
3.1 OB40的组织块属性与触发行为
S7-1200中硬件中断统一由OB40处理,不管是数字量模块还是模拟量模块触发的硬件中断,最终都进入OB40。这一点和S7-300/400有些差异,S7-300中模拟量模块触发的硬件中断OB号是OB40到OB47可选,1200里则固定在OB40,组态时不需要指定OB号,直接把OB40建出来就能用。
OB40有几个值得留意的属性。一个是优先级,默认优先级是16,在标准OB块里算比较高的,不能被OB1打断,但可以被更高优先级的OB块(比如时间中断OB10、OB11的默认优先级是17以上)打断。另一个是触发方式,OB40由硬件信号触发,模块检测到通道值超限时往背板总线发送中断请求,CPU收到请求后在下一条指令边界响应。
关于响应时间,S7-1200官方资料给的硬件中断响应时间在几百微秒量级。我在实际测试中通过记录中断OB里的系统时钟做过对比,从模块通道值越限到OB40第一条指令执行,实测在0.2到0.5毫秒之间。这个速度相比OB1扫描周期确实快了很多,能满足绝大多数快速响应的需求。
3.2 OB40的临时变量怎么用
创建OB40后,在快接口中可以看到一系列临时变量。对模拟量模块中断来说,最有用的两个是:
- HW_IO:触发中断的模块硬件标识符,格式是HW_IOS类型
- POINT_ADDR:触发中断的通道信息,格式是POINT类型
HW_IO用于确认是哪个模块触发的中断。系统里有多个模拟量模块时,可以在同一个OB40里通过HW_IO做判断,分别处理不同模块的触发。POINT_ADDR则记录了触发中断的具体通道地址。在SM1231模块上,POINT_ADDR的低字节保存的就是通道号,数值0表示通道0,1表示通道1。
不过我在实际调试中感到,仅凭POINT_ADDR来判断上限还是下限触发,不够直观。更稳妥的做法是在OB40里同时读取对应通道的当前值,结合模块组态中设定的上下限值,反推到底是哪个方向越限。因为OB40执行时,越限状态不一定已经恢复,读到的通道值大概率还停留在超限区域,通过比较读回值和限值大小就能确认触发方向。这种方法虽然绕一点,但逻辑清晰,不容易出错。
3.3 OB40里写什么程序合适
中断OB的第一原则是执行时间要短,只做最紧急的事。模拟量越限中断的处理逻辑通常是:
第一步,记录触发标志。用M区或数据块里的位变量记录哪个通道、哪个方向触发了中断,方便主程序轮询时读取。
第二步,读取触发时的通道值。把通道当前原始值存到全局数据块里,用于后续分析和记录。
第三步,输出动作。如果这个中断需要直接驱动设备动作,比如切断加热输出、停泵,可以在OB40里直接写输出指令。但要注意指令执行时间,不要放循环、字符串处理、DB块初始化这类耗时操作。
第四步,如果需要复位中断状态,可以在OB40末尾或OB1中清除模块的触发条件。模块中断在通道值恢复到设定范围内后会自动复位,不需要用户程序额外清零。
关于“断线检测”需要注意:SM1231支持断线诊断功能,启用后若4到20毫安通道电流低于1毫安,模块会报诊断事件并可能触发中断。这个诊断和上下限中断是两套机制,诊断事件走的是错误处理OB(如OB82),不走OB40。现场调试时不要混在一起查,否则方向容易跑偏。
4. 完整实操过程与核心环节实现
4.1 第一步:在博途中组态硬件并开启中断功能
打开博途V16或V17,新建项目后先做设备组态。添加CPU 1214C DC/DC/DC,再把SM1231 AI 4x13bit模块拖到CPU左侧或右侧的扩展槽位上。组态完成后,系统会自动分配模拟量通道的I地址。
选中SM1231模块,在属性窗口的“输入”选项卡中逐项配置通道参数:
- 选中通道0,测量类型选择“电流”,测量范围选择“4到20 mA”
- 上限值填22118(对应80摄氏度),下限值填5530(对应20摄氏度)
- 勾选“启用硬件中断”
- 通道1按同样方式配置,测量类型和测量范围相同,上下限值根据压力变送器量程另行计算
注意,模块属性里的“上限值”和“下限值”并不是量程的上下限,而是触发中断的阈值。量程上下限由测量范围决定,中断阈值由这里的参数决定。如果只想要上限报警,下限值可以填0,但这样下限方向不会触发中断,需要确认是否符合现场工艺要求。
4.2 第二步:创建OB40并编写中断处理程序
在“添加新块”中选择“组织块”,类型选择“硬件中断”,编号保持OB40。创建好后,在OB40里写入如下程序:
// OB40 硬件中断处理 // 通道0上限触发标志 "InterruptFlags".Ch0_Upper := FALSE; "InterruptFlags".Ch0_Lower := FALSE; // 通道1上限触发标志 "InterruptFlags".Ch1_Upper := FALSE; "InterruptFlags".Ch1_Lower := FALSE; // 判断触发通道 IF #OB40_POINT_ADDR = 0 THEN // 通道0触发 "InterruptFlags".Ch0_Triggered := TRUE; // 读取当前通道值 "ProcessValues".Ch0_RawValue := "IO_DB".AI0; // 判断触发方向 IF "ProcessValues".Ch0_RawValue >= 22118 THEN "InterruptFlags".Ch0_Upper := TRUE; ELSIF "ProcessValues".Ch0_RawValue <= 5530 THEN "InterruptFlags".Ch0_Lower := TRUE; END_IF; ELSIF #OB40_POINT_ADDR = 1 THEN // 通道1触发 "InterruptFlags".Ch1_Triggered := TRUE; "ProcessValues".Ch1_RawValue := "IO_DB".AI1; IF "ProcessValues".Ch1_RawValue >= [对应上限原始值] THEN "InterruptFlags".Ch1_Upper := TRUE; ELSIF "ProcessValues".Ch1_RawValue <= [对应下限原始值] THEN "InterruptFlags".Ch1_Lower := TRUE; END_IF; END_IF;上面代码里的IO_DB是数据块,AI0和AI1定义为Int类型,分别指向IW64和IW66。也可以直接使用IW64和IW66访问硬件输入,但放进数据块再访问的写法,方便在仿真或离线调试时手动赋值测试OB40逻辑。
这里要特别说明,OB40的临时变量名称在不同的博途版本中有差异。V16中OB40的POINT_ADDR变量名通常是#OB40_POINT_ADDR,V13 SP1之前的版本可能叫#POINT_ADDR。不同版本之间如果提示变量未定义,先检查一下OB40快接口里的实际变量名。这个细节虽然小,但卡住过不少人。
4.3 第三步:编写主程序,验证中断与轮询并行工作
在OB1里同时保留常规的模拟量换算逻辑,用于对比中断触发和轮询监测的差异。主程序中:
// 通道0工程量转换 "NORM_X" // 将IW64原始值标准化 (MIN := 0, MAX := 27648, VALUE := "IO_DB".AI0, OUT => "TempNorm".Ch0_Norm); "SCALE_X" // 将标准化值映射到0~100摄氏度 (MIN := 0.0, MAX := 100.0, VALUE := "TempNorm".Ch0_Norm, OUT => "ProcessValues".Ch0_Eng); // 循环轮询方式的上限判断,用于与中断对比 IF "ProcessValues".Ch0_Eng >= 80.0 THEN "CompareResult".Ch0_Upper_ByScan := TRUE; ELSE "CompareResult".Ch0_Upper_ByScan := FALSE; END_IF;OB1里的轮询结果和OB40里的中断触发标志做对比,就能直观看到两种方式的触发时刻差异。
为了验证中断触发时的CPU行为,我在OB40里还加了一段记录时间的逻辑:
"InterruptTime".Ch0_TriggerTime := RD_SYS_T(); // 读取系统时间,此处用毫秒值方便后续对比这个时间戳和OB1轮询发现越限时打出的时间戳一比较,就能算出两种方式的响应时间差。
4.4 第四步:仿真与硬件实测
如果没有实体模块,可以先在博途的PLCSIM里验证OB40的调用逻辑。仿真时没法真正模拟模块的硬件中断,但可以通过手动修改IW64的数值来测试程序分支。在仿真器中把IW64的值改成大于22118,OB40不会自动触发,因为仿真环境不模拟模块的硬件中断检测功能。需要手动触发OB40或使用“通过仿真器触发硬件中断”的方式测试。这一步在PLCSIM中测试时经常会卡住,建议有条件还是上真机验证。
硬件实测我这边是这样做的:用一个信号发生器输出4到20毫安信号接到SM1231通道0,把输出电流缓慢上调到超过80摄氏度对应的模拟值,观察OB40是否被调用,以及中断标志和时间戳是否被置位。实测结果和预期一致,信号过阈值后OB40在0.3毫秒左右被调用,而OB1轮询方式是在下一个扫描周期才检测到越限,两个时间差在3到8毫秒之间。
5. 常见问题与排查技巧实录
5.1 中断一直不触发怎么办
这是做模拟量模块中断时遇到最多的问题。排查路径我总结为三步:
第一步检查模块属性里是否勾选了“硬件中断”。这个选项藏在模块属性“输入”选项卡里,层级比较深,容易漏掉。我初学时就在这里栽过跟头,组态了半天,设备视图里看着配置都对,但OB40就是不执行,最后才发现中断使能位没勾选。
第二步检查上下限值设定的单位。上面反复强调过,模块参数里的上下限值不是工程量,而是原始值。如果直接把80填到上限值里,意味着通道原始值超过80就触发中断,而正常运行时原始值动辄几千几万,下限阈值基本恒成立,表现就是中断乱触发或常触发,干扰判断。
第三步检查OB40是否真的下载到CPU里。博途里新增的OB块要经过编译下载才会生效。如果只下载了设备组态而没有下载程序块,模块参数生效了但OB40没有下载,中断请求到了CPU却找不到处理块,系统不会报警也不会执行,看起来很像是中断功能失效。
5.2 中断触发了但不知道是哪个通道
系统里有多个模拟量模块或多通道触发时,靠看程序很难第一时间定位。我建议在OB40里给每个模块、每个通道都分配独立的标志位,同时在全局数据块里记录触发时间戳和通道原始值。排查时打开监控表或数据块监控界面,一眼就能看到哪个通道的哪个方向触发了中断。
另外,SM1231模块上有诊断LED,通道超限或断线时对应的通道指示灯会闪烁或变色,硬件现场也可以作为辅助判断手段。不过LED只是通道诊断状态,并不直接对应中断触发,两者不要混淆。
5.3 中断响应偶尔延迟或丢失
这种情况多半不是模块或CPU的问题,而是OB40被更高优先级的OB块打断,或者中断发生时刻恰好CPU正在处理其他高优先级中断,导致OB40排队执行。
S7-1200的中断优先级机制是:数值越小优先级越高。OB40的默认优先级是16,如果系统里还有OB10时间中断(优先级17)或OB20延时中断(优先级18),在极端时序下可能排队。如果要求模拟量中断绝对优先,可以把OB40的优先级调整为15甚至更低(数值更小),但要注意,高优先级OB块会打断低优先级OB块,调整后会带来更复杂的中断嵌套关系。一般应用场合保持默认优先级就够了,不用额外调整。
还有一种情况是滤波时间造成的影响。SM1231模块每个通道都有模拟量滤波设置,默认为无滤波。如果开启了滤波功能,模块会做多次采样取平均值,信号虽然更稳定,但会引入滞后。信号实际越过阈值后,模块内部可能经过几个滤波周期才判定为超限,反映到中断触发上就是延迟。需要快速响应的通道建议关闭滤波或选择较小的滤波时间。
5.4 模块诊断状态报错
SM1231模块报诊断时,常见原因包括:通道断线(4到20毫安模式下电流低于1毫安)、测量类型设置与实际信号不匹配、模块供电异常。
断线诊断和中断配置是两个独立的功能。断线时模块会发诊断事件,CPU诊断缓冲区会记录条目,但不一定会触发OB40。如果希望断线也进入中断处理,需要启用模块的“诊断中断”功能,并在OB82(诊断中断组织块)里编写处理程序。很多初学者把这两类中断混在一起查,结果OB40里始终没反应,但在诊断缓冲区能看到断线记录,原因就在这里。
5.5 一个实用技巧:中断程序里不要做模拟量工程量换算
前面提到OB40要短小精悍,映射到实际代码上,最典型的反面例子就是在OB40里直接做NORM_X和SCALE_X的工程量转换。模拟量转换涉及浮点运算,虽然单次执行时间不长,但叠加在中断处理里会延长中断OB的执行时间。如果这个OB40被多个通道的模拟量中断频繁调用,浮点运算累积起来对CPU时间占用很可观。
我建议的做法是OB40里只记录:哪个通道触发了、触发时的原始值是多少、触发方向是上限还是下限,然后立即返回。工程量转换、报警联动、数据归档这些工作放到OB1里轮询完成,或者用OB40置位标志、OB1检测到标志后再处理。这样分工清晰,也符合中断服务程序“快进快出”的编程惯例。
6. 中断与轮询的联合调试心得
6.1 用对比实验验证两种方式的差异
为了直观展示中断的优越性,我在一次调试中同时用两种方式监测同一路温度信号。温度变送器输出信号用信号发生器模拟,以1毫安每秒的速率缓慢上升,让信号缓慢跨越设置的上限。
OB1轮询方式在信号越过阈值后,最迟一个扫描周期内检测到越限并置位标志。OB40中断方式在信号越过阈值后约0.3毫秒内就记录了时间戳和通道值。两者的时间差主要取决于OB1周期长度,我测试时OB1周期大约是6到8毫秒,所以时间差也在这一范围内。如果OB1程序更复杂、扫描周期更长,中断的优势会更明显。
这个对比实验也让我重新理解了手册里关于中断“快”的真正含义。中断并不是让CPU跑得更快,而是让紧急任务从周期轮询中解放出来,以事件驱动的方式即时响应。对工业现场大量“越限就动作”的场景来说,这种机制比纯粹提高CPU扫描频率要高效得多。
6.2 中断标志的复位时机
使用中断标志位时,复位时机也是容易出问题的地方。我在练习时曾把复位放在OB1开头,结果中断OB里刚置位的标志,在下一个OB1周期一开始就被清零,主程序还没读到就丢了。
正确的做法是:主程序读取并处理完中断标志后再复位。比如OB1里先判断“InterruptFlags”.Ch0_Upper是否为真,执行相应的报警或动作逻辑后,再将该位复位。这样确保标志信息被完整消费,不会丢失。
如果担心程序扫描到OB1末尾时又触发新的中断,导致标志复位与新置位打架,可以在复位前再读一次中断触发状态做互锁。不过对一般应用来说,主程序读取后立即复位的常规写法就够用了。
6.3 中断与模拟量输入滤波的配合
如果现场信号干扰较大,直接使用模块原始值作为中断阈值,可能会因为信号瞬时毛刺造成频繁触发中断。这种场景下,可以在模块属性里启用输入滤波,或者把线性滤波放到外部信号调理环节。
但要注意,滤波时间设置得越大,信号越平滑,但响应越迟钝。比如滤波时间设置为100毫秒时,信号真实越过阈值后,模块内部可能要在100毫秒后才判定为超限并触发中断。这样即使中断机制本身很快,实际效果却被滤波拖慢了,反而失去意义。
我个人的经验是:做快速越限保护时,通道不滤波或采用较小的滤波时间;做平稳监测时,滤波时间可以适当加大,但中断阈值要留出足够余量,避免正常波动频繁触发。具体参数要根据现场信号质量和工艺要求综合权衡。
7. 模拟量中断功能的扩展应用思路
7.1 多通道独立限值监控
SM1231有4个或8个输入通道,每个通道都可以独立设置测量类型和上下限值,也就意味着可以用单个模块同时监视多路模拟量信号,每个通道都有各自独立的越限中断触发条件。
这种应用很适合多参数监控的场景。比如一台设备同时监视温度、压力、流量、液位四个参数,每路单独设置工艺上下限,任一参数越限都在OB40里标记出来,并记录触发时间戳和当时的通道值。相比在OB1里轮询四个通道做比较,模块中断方式逻辑更简洁,响应也更及时。
多通道共用一个OB40时,在OB40里用POINT_ADDR做分支判断是必须的。每路的判断代码独立,标志位独立,避免某个通道触发时把所有通道的处理逻辑都跑一遍,增加无谓的执行时间。
7.2 用中断配合数据块记录事件顺序
在现场事故分析中,事件发生的时间先后顺序往往比事件本身更重要。用模拟量中断配合全局数据块,可以在每次中断触发时记录一组数据:触发通道、触发方向、通道原始值、时间戳。
当多个通道依次越限时,数据块里会留下完整的触发序列。通过这些记录,可以还原“先有温度升高、后有压力上升、最终触发联锁停机”这类因果链条,对分析设备故障原因很有帮助。
记录数据块的程序建议放在OB40里,但记录动作要尽量简单——只写一条记录到数组元素,不做排序、不做历史归档。更复杂的数据分析放到上位机或触摸屏的脚本里完成。
7.3 与PID调节配合形成闭环保护
模拟量模块中断不仅能做报警和联锁,还能与PID调节器配合,形成带保护的闭环控制。常规PID控制是周期性的,通过OB30循环中断周期调用PID程序。当被调参数越限时,模拟量中断立即触发OB40,在OB40里将PID输出强制为安全值或切换到手动模式,实现比纯PID调节更快的保护动作。
这种方案的亮点在于,PID回路仍然在OB30里正常执行,但保护的监视线完全独立,不受PID调节周期影响。中断保护是即时动作,PID调节是平滑控制,两者各司其职。不过要注意OB40和OB30之间的数据交互,PID输出值的数据类型、是否允许强制、手动自动切换条件都要预先约定好,避免两个OB块互相抢写输出通道。
8. 几个值得牢记的注意事项
做模拟量模块中断练习时,有一些零散但很重要的经验,集中整理在下面。
第一,模块组态参数修改后必须做“编译”并完整下载。博途有时只提示下载设备组态,如果下载时漏选程序块,OB40的变动可能不会生效。养成“编译完成后,设备和软件全部下载”的习惯,能避免很多诡异的现象。
第二,OB40里的访问变量用符号名还是绝对地址,根据个人习惯。但如果是符号名,要确保该符号对应的数据块在OB40被触发时已经存在并完成初始化。中断可能在CPU启动早期就触发,如果数据块还没初始化好,OB40里访问到的内容可能不确定。稳妥的做法是在OB100启动组织块里完成数据块初始化,再开启相关中断功能。
第三,从没接触过中断OB的新手,建议先用最简单的数字量输入模块测试OB40的触发逻辑,再切换到模拟量模块。数字量中断触发条件简单,一个按钮按下去就触发一次,逻辑验证方便。摸清楚OB40的调用机制和变量含义后,再处理模拟量模块的上下限中断,难度会降低很多。
第四,硬件接线时,模拟量信号的屏蔽层要单端接地,避免形成地环路。现场电磁干扰较强的环境下,通道值容易波动,干扰严重时甚至会造成中断频繁触发。屏蔽层接地是模拟量应用中最基础也最容易被忽视的一环。
第五,如果需要读取中断触发时的通道值,OB40里直接访问IW64或通过数据块变量访问都可以,但要注意,模块通道值在中断处理期间可能还在变化,读到的只是一个时间点上的瞬时值。如果要精确记录越限时刻的信号幅值,可以在OB40里连续读两次取平均值,减少采样抖动的影响。不过这会增加OB40的执行时间,是否采用要根据实际需求权衡。