Beremiz运动控制,IEC61131编程语言SFC关联动作限制符: N、R、S、L、D、P、P0、P1、SD、DS、SL含义与区别

Refer:

1. SFC语言编辑器 · NetPAC操作使用手册 · 看云 (kancloud.cn) https://www.kancloud.cn/gastonfeng/kvpac_beremiz/1841545

2. 开源PLC编程软件Beremiz (kaikong.cn) https://www.kaikong.cn/Beremiz/

IEC61131-3 规定 Program Organization Units(POU)程序组织单元,包含Program,Fuction Block,Fuction,POU是个封装的单元,可以独立编译,并作为其他程序的部件,经编译的POU可以连接在一起组成完整的程序.

Beramiz 提供符合IEC61131-3标准的编程开发环境。IEC 61131-3是PLC编程开发的国际标准,这个标准将程序的基本单位称为程序组织单元( Program Organisation Unit,POU),并定义了三种程序组织单元:函数(FC)、函数块(FB)和程序(PROG)。今天这篇文章,我们就来详细介绍下程序组织单元。

IEC 61131-3定义了三种 程序组织单元POU,分别是:

函数(FC):Function可以有输入/输出参数,但是没有静态变量。使用相同的参数调用函数时,总会产生相同的输出结果。另外,定义函数时,必须指定返回值类型;函数块(FB):Function Block也被称为“功能块”,可以有输入/输出参数,并且可以有静态变量。使用相同的参数调用函数块时,由于静态变量的保持性,可能产生不同的输出结果;程序(Prog):Program类似于C语言的Main函数。程序内部调用函数或函数块,外部被任务(Task)调用而执行;

SFC语言的主要元素是:初始步骤、步骤、转换、动作块、分支、“跳跃”。 SFC程序由通过转换连接的一组步骤组成。

一旦具有SFC图表编辑功能的标签被激活,下一个面板就会出现在工具栏中(请参见图49 )。

图49 -SFC图表编辑面板

按钮外观按钮名称按钮功能:

调用开始按钮创建一个新的初始步骤;根据IEC61131-3,SFC图表上必须有一个初始化步骤,该步骤可表征SFC图表的初始状态。

调用步骤编辑对话框 创建新步骤;根据需求编辑对话框,勾选三种连接器:输入、输出、动作,前面的勾号。

调用条件转移编辑对话框 创建一个新的转换/跃迁;根据需求编辑转换对话框,选择转换类型{参照/引用:预定义转换;在线:ST语言代码;连接:BOOL输入型左触点连接器}及其优先级。ST语言实例:(IncStep=9)&(NOT OddPeriod)

调用动作块编辑对话框 创建一个新的动作块;根据需求编辑动作块对话框,动作块、动作、动作属性{”限定符”、“持续时间”、“类型{动作、变量、在线}”、“值”、“指示器”}接下来,本篇文章侧重说明其中的 “动作/行动块”

调用发散和收敛按钮 创建一个新“选一或同步”分支/收敛;根据需求编辑分支对话框,选择分支类型{“选一发散”、“选一收敛”、“并行发散”、“并行收敛”} 和 分支数量。选一分支发散线输出端,必须与“转换”直链;并行分支收敛线输入端,必须与“转换”直链;。

调用无条件跳转按钮 创建一个新的无条件“跳转”调用;根据IEC61131-3,必须在步和跳之间定义“转换”。

一、行动块、动作、动作属性概述

1、动作/块的执行:当一个步被活动(激活),动作块中的所有动作根据动作限定符的条件设定执行。当一个步在活动状态,动作块中的每个动作每周期执行一次。动作块包括:一组动作。 您可以通过单击“添加” 按钮并设置必要的参数,来添加新动作:

“限定符”; 即合格验证,动作限定符;这个非常重要。

“持续时间”;

“类型”:“动作”,“变量”,“在线”;

“值”;

“指示器”

二、动作(顺序)限定

IEC编程,SFC关联 动作限制符: N、R、S、L、D、P、P0、P1、SD、DS、SL含义与区别

AQ /动作限定符为每个动作定义运行时序;它能决定当步活动时动作如何执行;每个动作只可指定一个 AQ。动作类型决定了当步变为非活动状态时输出是保持还是复位。需要时,改变初始设置或向程序中添加复位过程。

• 对于位,如果保持动作限定符(S)未被指定,输出将复位;如果保持动作限定符(S)已指定,输出将保持。• 对于梯形图程序,输出默认复位,默认设置可变为保持输出状态。• 对于 ST 程序,默认输出状态保持,必要时,在程序中写入复位过程并使用动作标志(当 ST 程序中对应步变为非活动时,该标志变为 ON)来控制复位过程。

SFC语言编辑器动作限定符

动作限定符

动作限定词名称(合格验证)

定时器设置

功能

动作块行为

注释

N

普通(默认)

非存储的

/

动作执行跟步活动时间一样长

该步骤处于活动状态时执行该动作

R

重写复位

/

当步变为活动,且他的动作是由“S、SL、SD或DS”限定符,指定动作停止并复位。如果动作正在执行,但不是由“S、SL、SD或DS”限定符执行,动作只是复位(不停止)。复位操作设置如下: OUT/OUT NOT指令: “OFF”,TIM/TIMH 指令:“复位”;其它定时器/计数器/转换寄存器:“保持”

禁用图表后将执行该动作

S

置位(存储)

/

步活动时动作执行,即使步变成非活动也持续执行,要取消执行,使用R限定符

P

脉冲Pulse

/

是若最终扫描功能使能,当步活动时动作执行2个扫描周期。若最终 扫描功能非使能,当步活动时,动作执行1个周期。

P0

下降沿脉冲

/

每当步变为非活动时动作执行一次

P1

上升沿脉冲

/

每当步变为活动时动作执行一次。

如下:时间限定,它们都是需要一个以Time恒定格式的时间值。 e.g. T#10ms

D

延时执行Delay

从步活动开始, 过去用户指定时间后动作执行。如果在用户指定时间到期之前步变为非活动,动作将不执行。

动作经过一定的时间后成为活动的(如果步依旧活动的话),然后只要是步是活动的,动作也保持活动

该动作将在特定的指定时间后开始执行(如果该步骤仍处于活动状态), 并且只要此步骤处于活动状态就将执行

L

限时执行Limit

当步活动后, 动作执行直到用户指定时间到达。如果步变为非活动,动作执行将终止。

动作在一定时间内是活动的,最长持续时间赞同于步的活动的时间

在某个预定时间间隔内执行该动作,此后该动作停止

SD

置位和延时Set&Delay

步活动后直到用户指定时间到达,动作开始执行,即使步变成非活动也持续执行,要取消执行,使用R限定符

动作一定时间后是活动的,并一直保持活动直到收到一个'复位命令'。

即使该步骤不再处于活动状态,该动作也会在一段时间后开始执行。

DS

延时和置位Delay&Set

执行时类似"SD"。同SD不同,如果步在用户指定延迟时间到期之前变为非活动,动作将不操作。要取消执行,使用R限定符。

动作在一定时间后是活动的,此后只要步是活动的,动作也保持活动的,直到收到一个'复位'命令。

仅在该步骤仍处于活动状态时,该动作才会在特定的指定时间后开始执行。

SL

置位和限时Set&Limit

步活动时动作执行,直到用户指定时间到期。与“L”不同的是,即使步变成非活动也持续执行,要取消执行,使用R限定符。

存储和时间限制 动作在一定时间内是活动的

该动作在指定的时间间隔内处于活动状态

D,DS,L控制动作执行的时序,使用步定时器,时间单位与动作块被分配的步的定时器一致。SD和SL用与步定时器不同的定时器控制时间,因为他们操作独立于步状态。如果动作限定符设置为“N”,梯形图程序将不能正确检测步的上升沿激活状态。因此,如果一个过程根据步的激活状态只执行一次,需要使用“P1”动作限定符。

图1 各限定动作执行时序图

三、动作持续时间

只有“动作限定”为 D、L、DS、SD、SL这个属性才有意义。

通常使用格式: T#3s 、 T#100ms

四、动作类型”:“动作”,“变量”,“在线”

“类型”定义将在动作激活期间执行的代码或特定动作。

4.1 动作/行动

行动/动作,是Function Block“功能块”右键菜单中创建。 动作/行动块,添加动作,类型选择为"行动",就可以引用。

SFC选择“动作”的情况下,与转换的情况相同,可以使用SFC语言编写的该POU在项目树中使用预定的动作。

4.2 变量

变量,是在编辑区上方的,变量添加区创建。动作/行动块,添加动作,类型选择为"变量",就可以引用。

(步骤激活后,根据变量的类型, 此变量将采用值0、0.0,FALSE和其他类型的空值。动作开始执行后,变量将采用值1、1.0,TRUE和其他类型的单位值。

如果动作停止执行,则变量将再次采用值0、0.0,FALSE和另一个零值,具体看其类型。

4.3 在线

在线指ST代码。

动作/行动块,添加动作,类型选择为"在线",则可以在“值”上转换为以ST语言编写为将在动作导向的状态下执行的代码: var := var + 1;

注意,与用于"转换"的内置代码相反,在使用动作的内置代码末尾, 您需要添加分号“;”。

五、Beremiz生成C代码解析

5.1 PLC_APP 逻辑程序块

结构层次

1.程序入口

(操作系统适配)

2.plc默认变量 init

3.项目配置(用户定义)变量 init

4.资源(触发器/POU实例)初始化与运行

程序POU

功能块POU

动作

Beremiz界面

数据对象

资源选项卡:1、任务,指两种触发器 ”循环定时器/中断 “2、实例,指"程序POU"对象

项目选项卡:

1.配置变量,指所有程序的外部变量

源文件

plc_app_dyplc.c

plc_main.c

config.c

Resource1.c

...

Resource.c

POUS.C

A-数据初始化

startPLC

plc_app_abi_t plc_dyplc_app

{ .start = startPLC,

}

__init

config_init__

RESOURCE1_init__

...

RESOURCEx_init__

AI_init__

函数实现

int startPLC(int argc,char **argv){ if(__init(argc,argv) == 0){ PLC_SetTimer(0, common_ticktime__); return 0; }else{ return 1; }}

int __init(int argc,char **argv)

{int res = 0;init_level = 0;/* Effective tick time with 1ms default value */if(!common_ticktime__)common_ticktime__ = 1000000;

config_init__();__init_debug();init_level=1; if((res = __init_py_ext(argc,argv))){return res;}return res;}

void config_init__(void) { BOOL retain; retain = 0; __INIT_GLOBAL_LOCATED(CONFIG,DI0,__IX1_0,retain) __INIT_GLOBAL(BOOL,DI0,__INITIAL_VALUE(__BOOL_LITERAL(FALSE)),retain) __INIT_GLOBAL_LOCATED(CONFIG,DI1,__IX1_1,retain)

... RESOURCE1_init__();}

void RESOURCE1_init__(void) {BOOL retain;retain = 0;TIMER0 = __BOOL_LITERAL(FALSE);TIMER1 = __BOOL_LITERAL(FALSE);MODBUS_init__(&PER4,retain);AI_init__(&PER6,retain);AO_init__(&PER5,retain);POINT_init__(&PER0,retain);}

B-线程运行

runPLC

plc_app_abi_t plc_dyplc_app

{.run = runPLC,

}

__run

config_run__

RESOURCE1_run__...RESOURCEx_run__

AI_body__

函数实现

void runPLC(void){ PLC_GetTime( &__CURRENT_TIME ); __run();}

void __run(void){ __tick++; if (greatest_tick_count__) __tick %= greatest_tick_count__;

__retrieve_py_ext();

/*__retrieve_debug();*/

config_run__(__tick);

__publish_debug();

__publish_py_ext();

}

void config_run__(unsigned long tick) { RESOURCE1_run__(tick);}

void RESOURCE1_run__(unsigned long tick) { TIMER0 = !(tick % 200); TIMER1 = !(tick % 1); if (TIMER0) { MODBUS_body__(&PER4); } if (TIMER0) { AI_body__(&PER6); } if (TIMER0) { AO_body__(&PER5); } if (TIMER1) { POINT_body__(&PER0); }}

C-工具函数

void PLC_GetTime(...);

void PLC_SetTimer(...);

int startPLC(int argc,char **argv)

int stopPLC();

//void runPLC(void)

5.2 PLC_RTE 线程运行时

// plc_main_rte.c :: plc_rts_task

while (1)

{

//printf("[%s:%d] tick:%d\n",__FUNCTION__, __LINE__, HAL_GetTick());

dbg_handler();

if(plc_state == PLC_STATE_STARTED)

{

plc_curr_rte->get_input(); // plc_get_input()::plc_main_rte.c

plc_iom_get(); // plc_iom.c::plc_iom_get() -> plc_hw.c::plc_dio_get()

if((g_u64timer - before_iec) >= g_u64tick_period)

{

plc_curr_app->run(); // plc_app_dyplc.c :: runPLC()

before_iec = g_u64timer;

}

plc_iom_set(); //plc_iom.c::plc_iom_set() -> plc_hw.c::plc_dio_set()

plc_curr_rte->set_output(); //plc_set_output()::plc_main_rte.c

}

}

线程入口初始化:

线程函数入口

plc_rts_task ()

plc_main_rte.c

dbg_init();

plc_timer_init(); plc_iom_init(); plc_hw.c plc_iom_test_hw();

plc_load_rte();plc_curr_rte->init_dio();

plc_load_app();

plc_app_start();

线程主循环体:

读IO输入

plc_curr_rte->get_input();

// plc_main_rte.c::plc_get_input()

通过PLC位置定义“%IX0.0”,实现读入区I-RAM 与 PLC变量名关联

(粉红色数字,为内存偏移量)

plc_iom_get();

// plc_iom.c::plc_iom_get() -> plc_hw.c::plc_dio_get()

if((g_u64timer - before_iec) >= g_u64tick_period)

{

plc_curr_app->run();

before_iec = g_u64timer;}

// plc_app_dyplc.c :: runPLC()

通过PLC位置定义“%QX0.0”,实现输出区Q-RAM 与 PLC变量名关联

(粉红色数字,为内存偏移量)

plc_iom_set();

// plc_iom.c::plc_iom_set() -> plc_hw.c::plc_dio_set()

写IO输出

plc_curr_rte->set_output();

// plc_main_rte.c ::plc_set_output()

5.1 项目·配置选项卡

1. 配置变量(Config variables) : 硬件 I/O 引脚分配、全局变量预定义。例如:%IX1.1,%MB2. I/Q/M :输入/输出/内存,X/B:位:字节。详见:IEC61131-3可编程语言标准中文版.pdf, 变量位置定义。

2.项目属性

3.配置

5.2 资源·config.resource1配置选项卡

资源主要是,把硬件定时器和程序绑定生成任务实例。定时器分类:循环Cyclic、中断Interrupt两种。

5.3 程序·Program程序POU

5.4 功能块·FuctionBlock功能块POU

5.5 添加变量打印,方便调试

第一步、新建结构化语言POU:功能块 : ST:FB_Printf

内部添加如下C语言代码:

{{ //__SET_VAR(data__->TRANSPORTCMD1.,BCR_RACKNO,,__GET_EXTERNAL(data__->BCR_RACKNO,)); // __SET_EXTERNAL(data__->,J2_ADDR,,__GET_VAR(data__->TRANSPORTCMD1.J2_ADDR,)); //获取局部变量:__GET_VAR(data__->ASPPOS,)

uint8_t done = __GET_EXTERNAL(data__->A1_D1,); //GetFbVar(DONE); printf("[%s:%d] (A1Init) tick:%d\n",__FUNCTION__, __LINE__, done); // HAL_GetTick());

SetFbVar(DONE,done);

}}

第二步、在功能块:SFC:xxxx下,添加“行动”

uint16_t j1_addr = __GET_EXTERNAL(data__->J1_ADDR,);

if(0!=j1_addr)

printf("####[%s:%d] J1_ADDR:%d####\n",__FUNCTION__, __LINE__, j1_addr);

第三步、SFC顺序功能流程图中,行动块中调用此“打印行动”

2025-12-26 00:23:36
熹妃传新随从获得攻略及全面解析 | 熹妃传新随从获取方法与技巧
世嘉土星游戏列表