Structured text
- 7 min read
- 1 chapter
Related on Lably
Through Block (programming)
Complex statements and nested instructions are supported:
- Iteration loops (REPEAT-UNTIL; WHILE-DO)
- Conditional execution (IF-THEN-ELSE; CASE)
- Functions (SQRT(), SIN())
Sample program
<span id="mwIA"></span><span class="cm" id="mwIQ">(* simple state machine *)</span> <span class="n" id="mwIg">TxtState</span><span class="w" id="mwIw"> </span><span class="o" id="mwJA">:=</span><span class="w" id="mwJQ"> </span><span class="n" id="mwJg">STATES</span><span class="p" id="mwJw">[</span><span class="n" id="mwKA">StateMachine</span><span class="p" id="mwKQ">]</span><span class="o" id="mwKg">;</span> <span class="k" id="mwKw">CASE</span><span class="w" id="mwLA"> </span><span class="n" id="mwLQ">StateMachine</span><span class="w" id="mwLg"> </span><span class="k" id="mwLw">OF</span> <span class="w" id="mwMA"> </span><span class="mi" id="mwMQ">1</span><span class="o" id="mwMg">:</span><span class="w" id="mwMw"> </span><span class="n" id="mwNA">ClosingValve</span><span class="p" id="mwNQ">()</span><span class="o" id="mwNg">;</span> <span class="w" id="mwNw"> </span><span class="n" id="mwOA">StateMachine</span><span class="w" id="mwOQ"> </span><span class="o" id="mwOg">:=</span><span class="w" id="mwOw"> </span><span class="mi" id="mwPA">2</span><span class="o" id="mwPQ">;</span> <span class="w" id="mwPg"> </span><span class="mi" id="mwPw">2</span><span class="o" id="mwQA">:</span><span class="w" id="mwQQ"> </span><span class="n" id="mwQg">OpeningValve</span><span class="p" id="mwQw">()</span><span class="o" id="mwRA">;</span> <span class="k" id="mwRQ">ELSE</span> <span class="w" id="mwRg"> </span><span class="n" id="mwRw">BadCase</span><span class="p" id="mwSA">()</span><span class="o" id="mwSQ">;</span> <span class="n" id="mwSg">END_CASE</span><span class="o" id="mwSw">;</span>
Unlike in some other programming languages, there is no fallthrough for the CASE statement: the first matching condition is entered, and after running its statements, the CASE block is left without checking other conditions.
Additional ST programming examples
<span id="mwUQ"></span><span class="c1" id="mwUg">// PLC configuration</span> <span class="n" id="mwUw">CONFIGURATION</span><span class="w" id="mwVA"> </span><span class="n" id="mwVQ">DefaultCfg</span> <span class="w" id="mwVg"> </span><span class="n" id="mwVw">VAR_GLOBAL</span> <span class="w" id="mwWA"> </span><span class="n" id="mwWQ">b_Start_Stop</span><span class="w" id="mwWg"> </span><span class="o" id="mwWw">:</span><span class="w" id="mwXA"> </span><span class="kt" id="mwXQ">BOOL</span><span class="o" id="mwXg">;</span><span class="w" id="mwXw"> </span><span class="c1" id="mwYA">// Global variable to represent a boolean.</span> <span class="w" id="mwYQ"> </span><span class="n" id="mwYg">b_ON_OFF</span><span class="w" id="mwYw"> </span><span class="o" id="mwZA">:</span><span class="w" id="mwZQ"> </span><span class="kt" id="mwZg">BOOL</span><span class="o" id="mwZw">;</span><span class="w" id="mwaA"> </span><span class="c1" id="mwaQ">// Global variable to represent a boolean.</span> <span class="w" id="mwag"> </span><span class="n" id="mwaw">Start_Stop</span><span class="w" id="mwbA"> </span><span class="n" id="mwbQ">AT</span><span class="w" id="mwbg"> </span><span class="err" id="mwbw">%</span><span class="n" id="mwcA">IX0</span><span class="o" id="mwcQ">.</span><span class="mi" id="mwcg">0</span><span class="o" id="mwcw">:</span><span class="kt" id="mwdA">BOOL</span><span class="o" id="mwdQ">;</span><span class="w" id="mwdg"> </span><span class="c1" id="mwdw">// Digital input of the PLC (Address 0.0)</span> <span class="w" id="mweA"> </span><span class="n" id="mweQ">ON_OFF</span><span class="w" id="mweg"> </span><span class="n" id="mwew">AT</span><span class="w" id="mwfA"> </span><span class="err" id="mwfQ">%</span><span class="n" id="mwfg">QX0</span><span class="o" id="mwfw">.</span><span class="mi" id="mwgA">0</span><span class="o" id="mwgQ">:</span><span class="kt" id="mwgg">BOOL</span><span class="o" id="mwgw">;</span><span class="w" id="mwhA"> </span><span class="c1" id="mwhQ">// Digital output of the PLC (Address 0.0). (Coil)</span> <span class="w" id="mwhg"> </span><span class="n" id="mwhw">END_VAR</span> <span class="w" id="mwiA"> </span><span class="c1" id="mwiQ">// Schedule the main program to be executed every 20 ms</span> <span class="w" id="mwig"> </span><span class="n" id="mwiw">TASK</span><span class="w" id="mwjA"> </span><span class="n" id="mwjQ">Tick</span><span class="p" id="mwjg">(</span><span class="n" id="mwjw">INTERVAL</span><span class="w" id="mwkA"> </span><span class="o" id="mwkQ">:=</span><span class="w" id="mwkg"> </span><span class="n" id="mwkw">t</span><span class="sc" id="mwlA">#20</span><span class="n" id="mwlQ">ms</span><span class="p" id="mwlg">)</span><span class="o" id="mwlw">;</span> <span class="w" id="mwmA"> </span><span class="k" id="mwmQ">PROGRAM</span><span class="w" id="mwmg"> </span><span class="n" id="mwmw">Main</span><span class="w" id="mwnA"> </span><span class="k" id="mwnQ">WITH</span><span class="w" id="mwng"> </span><span class="n" id="mwnw">Tick</span><span class="w" id="mwoA"> </span><span class="o" id="mwoQ">:</span><span class="w" id="mwog"> </span><span class="n" id="mwow">Monitor_Start_Stop</span><span class="o" id="mwpA">;</span> <span class="n" id="mwpQ">END_CONFIGURATION</span> <span class="k" id="mwpg">PROGRAM</span><span class="w" id="mwpw"> </span><span class="n" id="mwqA">Monitor_Start_Stop</span><span class="w" id="mwqQ"> </span><span class="c1" id="mwqg">// Actual Program</span> <span class="w" id="mwqw"> </span><span class="n" id="mwrA">VAR_EXTERNAL</span> <span class="w" id="mwrQ"> </span><span class="n" id="mwrg">Start_Stop</span><span class="w" id="mwrw"> </span><span class="o" id="mwsA">:</span><span class="w" id="mwsQ"> </span><span class="kt" id="mwsg">BOOL</span><span class="o" id="mwsw">;</span> <span class="w" id="mwtA"> </span><span class="n" id="mwtQ">ON_OFF</span><span class="w" id="mwtg"> </span><span class="o" id="mwtw">:</span><span class="w" id="mwuA"> </span><span class="kt" id="mwuQ">BOOL</span><span class="o" id="mwug">;</span> <span class="w" id="mwuw"> </span><span class="n" id="mwvA">END_VAR</span> <span class="w" id="mwvQ"> </span><span class="k" id="mwvg">VAR</span><span class="w" id="mwvw"> </span><span class="c1" id="mwwA">// Temporary variables for logic handling</span> <span class="w" id="mwwQ"> </span><span class="n" id="mwwg">ONS_Trig</span><span class="w" id="mwww"> </span><span class="o" id="mwxA">:</span><span class="w" id="mwxQ"> </span><span class="kt" id="mwxg">BOOL</span><span class="o" id="mwxw">;</span> <span class="w" id="mwyA"> </span><span class="n" id="mwyQ">Rising_ONS</span><span class="w" id="mwyg"> </span><span class="o" id="mwyw">:</span><span class="w" id="mwzA"> </span><span class="kt" id="mwzQ">BOOL</span><span class="o" id="mwzg">;</span> <span class="w" id="mwzw"> </span><span class="n" id="mw0A">END_VAR</span> <span class="w" id="mw0Q"> </span><span class="c1" id="mw0g">// Start of Logic</span> <span class="w" id="mw0w"> </span><span class="c1" id="mw1A">// Catch the Rising Edge One Shot of the Start_Stop input</span> <span class="w" id="mw1Q"> </span><span class="n" id="mw1g">ONS_Trig</span><span class="w" id="mw1w"> </span><span class="o" id="mw2A">:=</span><span class="w" id="mw2Q"> </span><span class="n" id="mw2g">Start_Stop</span><span class="w" id="mw2w"> </span><span class="k" id="mw3A">AND</span><span class="w" id="mw3Q"> </span><span class="k" id="mw3g">NOT</span><span class="w" id="mw3w"> </span><span class="n" id="mw4A">Rising_ONS</span><span class="o" id="mw4Q">;</span> <span class="w" id="mw4g"> </span> <span class="w" id="mw4w"> </span><span class="c1" id="mw5A">// Main Logic for Run_Contact -- Toggle ON / Toggle OFF ---</span> <span class="w" id="mw5Q"> </span><span class="n" id="mw5g">ON_OFF</span><span class="w" id="mw5w"> </span><span class="o" id="mw6A">:=</span><span class="w" id="mw6Q"> </span><span class="p" id="mw6g">(</span><span class="n" id="mw6w">ONS_Trig</span><span class="w" id="mw7A"> </span><span class="k" id="mw7Q">AND</span><span class="w" id="mw7g"> </span><span class="k" id="mw7w">NOT</span><span class="w" id="mw8A"> </span><span class="n" id="mw8Q">ON_OFF</span><span class="p" id="mw8g">)</span><span class="w" id="mw8w"> </span><span class="k" id="mw9A">OR</span><span class="w" id="mw9Q"> </span><span class="p" id="mw9g">(</span><span class="n" id="mw9w">ON_OFF</span><span class="w" id="mw-A"> </span><span class="k" id="mw-Q">AND</span><span class="w" id="mw-g"> </span><span class="k" id="mw-w">NOT</span><span class="w" id="mw_A"> </span><span class="n" id="mw_Q">ONS_Trig</span><span class="p" id="mw_g">)</span><span class="o" id="mw_w">;</span> <span class="w" id="mwAQA"> </span><span class="c1" id="mwAQE">// Rising One Shot logic </span> <span class="w" id="mwAQI"> </span><span class="n" id="mwAQM">Rising_ONS</span><span class="w" id="mwAQQ"> </span><span class="o" id="mwAQU">:=</span><span class="w" id="mwAQY"> </span><span class="n" id="mwAQc">Start_Stop</span><span class="o" id="mwAQg">;</span> <span class="n" id="mwAQk">END_PROGRAM</span>
Function block example
<span id="mwAQ0"></span><span class="linenos" data-line="1" id="mwAQ4"></span><span class="c1" id="mwAQ8">//=======================================================================</span> <span class="linenos" data-line="2" id="mwARA"></span><span class="c1" id="mwARE">// Function Block Timed Counter : Incremental count of the timed interval</span> <span class="linenos" data-line="3" id="mwARI"></span><span class="c1" id="mwARM">//=======================================================================</span> <span class="linenos" data-line="4" id="mwARQ"></span><span class="nx" id="mwARU">FUNCTION_BLOCK</span><span class="w" id="mwARY"> </span><span class="nx" id="mwARc">FB_Timed_Counter</span> <span class="linenos" data-line="5" id="mwARg"></span><span class="w" id="mwARk"> </span><span class="nx" id="mwARo">VAR_INPUT</span> <span class="linenos" data-line="6" id="mwARs"></span><span class="w" id="mwARw"> </span><span class="nx" id="mwAR0">Execute</span><span class="w" id="mwAR4"> </span><span class="o" id="mwAR8">:</span><span class="w" id="mwASA"> </span><span class="nx" id="mwASE">BOOL</span><span class="w" id="mwASI"> </span><span class="o" id="mwASM">:=</span><span class="w" id="mwASQ"> </span><span class="nx" id="mwASU">FALSE</span><span class="o" id="mwASY">;</span><span class="w" id="mwASc"> </span><span class="c1" id="mwASg">// Trigger signal to begin Timed Counting</span> <span class="linenos" data-line="7" id="mwASk"></span><span class="w" id="mwASo"> </span><span class="nx" id="mwASs">Time_Increment</span><span class="w" id="mwASw"> </span><span class="o" id="mwAS0">:</span><span class="w" id="mwAS4"> </span><span class="nx" id="mwAS8">REAL</span><span class="w" id="mwATA"> </span><span class="o" id="mwATE">:=</span><span class="w" id="mwATI"> </span><span class="mf" id="mwATM">1.25</span><span class="o" id="mwATQ">;</span><span class="w" id="mwATU"> </span><span class="c1" id="mwATY">// Enter Cycle Time (Seconds) between counts</span> <span class="linenos" data-line="8" id="mwATc"></span><span class="w" id="mwATg"> </span><span class="nx" id="mwATk">Count_Cycles</span><span class="w" id="mwATo"> </span><span class="o" id="mwATs">:</span><span class="w" id="mwATw"> </span><span class="nx" id="mwAT0">INT</span><span class="w" id="mwAT4"> </span><span class="o" id="mwAT8">:=</span><span class="w" id="mwAUA"> </span><span class="mi" id="mwAUE">20</span><span class="o" id="mwAUI">;</span><span class="w" id="mwAUM"> </span><span class="c1" id="mwAUQ">// Number of Desired Count Cycles</span> <span class="linenos" data-line="9" id="mwAUU"></span><span class="w" id="mwAUY"> </span><span class="nx" id="mwAUc">END_VAR</span> <span class="linenos" data-line="10" id="mwAUg"></span><span class="w" id="mwAUk"> </span> <span class="linenos" data-line="11" id="mwAUo"></span><span class="w" id="mwAUs"> </span><span class="nx" id="mwAUw">VAR_OUTPUT</span> <span class="linenos" data-line="12" id="mwAU0"></span><span class="w" id="mwAU4"> </span><span class="nx" id="mwAU8">Timer_Done_Bit</span><span class="w" id="mwAVA"> </span><span class="o" id="mwAVE">:</span><span class="w" id="mwAVI"> </span><span class="nx" id="mwAVM">BOOL</span><span class="w" id="mwAVQ"> </span><span class="o" id="mwAVU">:=</span><span class="w" id="mwAVY"> </span><span class="nx" id="mwAVc">FALSE</span><span class="o" id="mwAVg">;</span><span class="w" id="mwAVk"> </span><span class="c1" id="mwAVo">// One Shot Bit indicating Timer Cycle Done</span> <span class="linenos" data-line="13" id="mwAVs"></span><span class="w" id="mwAVw"> </span><span class="nx" id="mwAV0">Count_Complete</span><span class="w" id="mwAV4"> </span><span class="o" id="mwAV8">:</span><span class="w" id="mwAWA"> </span><span class="nx" id="mwAWE">BOOL</span><span class="w" id="mwAWI"> </span><span class="o" id="mwAWM">:=</span><span class="w" id="mwAWQ"> </span><span class="nx" id="mwAWU">FALSE</span><span class="o" id="mwAWY">;</span><span class="w" id="mwAWc"> </span><span class="c1" id="mwAWg">// Output Bit indicating the Count is complete </span> <span class="linenos" data-line="14" id="mwAWk"></span><span class="w" id="mwAWo"> </span><span class="nx" id="mwAWs">Current_Count</span><span class="w" id="mwAWw"> </span><span class="o" id="mwAW0">:</span><span class="w" id="mwAW4"> </span><span class="nx" id="mwAW8">INT</span><span class="w" id="mwAXA"> </span><span class="o" id="mwAXE">:=</span><span class="w" id="mwAXI"> </span><span class="mi" id="mwAXM">0</span><span class="o" id="mwAXQ">;</span><span class="w" id="mwAXU"> </span><span class="c1" id="mwAXY">// Accumulating Value of Counter</span> <span class="linenos" data-line="15" id="mwAXc"></span><span class="w" id="mwAXg"> </span><span class="nx" id="mwAXk">END_VAR</span> <span class="linenos" data-line="16" id="mwAXo"></span><span class="w" id="mwAXs"> </span> <span class="linenos" data-line="17" id="mwAXw"></span><span class="w" id="mwAX0"> </span><span class="nx" id="mwAX4">VAR</span> <span class="linenos" data-line="18" id="mwAX8"></span><span class="w" id="mwAYA"> </span><span class="nx" id="mwAYE">CycleTimer</span><span class="w" id="mwAYI"> </span><span class="o" id="mwAYM">:</span><span class="w" id="mwAYQ"> </span><span class="nx" id="mwAYU">TON</span><span class="o" id="mwAYY">;</span><span class="w" id="mwAYc"> </span><span class="c1" id="mwAYg">// Timer FB from Command Library</span> <span class="linenos" data-line="19" id="mwAYk"></span><span class="w" id="mwAYo"> </span><span class="nx" id="mwAYs">CycleCounter</span><span class="w" id="mwAYw"> </span><span class="o" id="mwAY0">:</span><span class="w" id="mwAY4"> </span><span class="nx" id="mwAY8">CTU</span><span class="o" id="mwAZA">;</span><span class="w" id="mwAZE"> </span><span class="c1" id="mwAZI">// Counter FB from Command Library</span> <span class="linenos" data-line="20" id="mwAZM"></span><span class="w" id="mwAZQ"> </span><span class="nx" id="mwAZU">TimerPreset</span><span class="w" id="mwAZY"> </span><span class="o" id="mwAZc">:</span><span class="w" id="mwAZg"> </span><span class="nx" id="mwAZk">TIME</span><span class="o" id="mwAZo">;</span><span class="w" id="mwAZs"> </span><span class="c1" id="mwAZw">// Converted Time_Increment in Seconds to MS</span> <span class="linenos" data-line="21" id="mwAZ0"></span><span class="w" id="mwAZ4"> </span><span class="nx" id="mwAZ8">END_VAR</span> <span class="linenos" data-line="22" id="mwAaA"></span><span class="w" id="mwAaE"> </span> <span class="linenos" data-line="23" id="mwAaI"></span><span class="w" id="mwAaM"> </span><span class="c1" id="mwAaQ">// Start of Function Block programming</span> <span class="linenos" data-line="24" id="mwAaU"></span><span class="w" id="mwAaY"> </span><span class="nx" id="mwAac">TimerPreset</span><span class="w" id="mwAag"> </span><span class="o" id="mwAak">:=</span><span class="w" id="mwAao"> </span><span class="nx" id="mwAas">REAL_TO_TIME</span><span class="p" id="mwAaw">(</span><span class="k" id="mwAa0">in</span><span class="w" id="mwAa4"> </span><span class="o" id="mwAa8">:=</span><span class="w" id="mwAbA"> </span><span class="nx" id="mwAbE">Time_Increment</span><span class="p" id="mwAbI">)</span><span class="w" id="mwAbM"> </span><span class="o" id="mwAbQ">*</span><span class="w" id="mwAbU"> </span><span class="mi" id="mwAbY">1000</span><span class="o" id="mwAbc">;</span> <span class="linenos" data-line="25" id="mwAbg"></span> <span class="linenos" data-line="26" id="mwAbk"></span><span class="w" id="mwAbo"> </span><span class="nx" id="mwAbs">CycleTimer</span><span class="p" id="mwAbw">(</span> <span class="linenos" data-line="27" id="mwAb0"></span><span class="w" id="mwAb4"> </span><span class="k" id="mwAb8">in</span><span class="w" id="mwAcA"> </span><span class="o" id="mwAcE">:=</span><span class="w" id="mwAcI"> </span><span class="nx" id="mwAcM">Execute</span><span class="w" id="mwAcQ"> </span><span class="nx" id="mwAcU">AND</span><span class="w" id="mwAcY"> </span><span class="nx" id="mwAcc">NOT</span><span class="w" id="mwAcg"> </span><span class="nx" id="mwAck">CycleTimer</span><span class="p" id="mwAco">.</span><span class="nx" id="mwAcs">Q</span><span class="o" id="mwAcw">,</span> <span class="linenos" data-line="28" id="mwAc0"></span><span class="w" id="mwAc4"> </span><span class="nx" id="mwAc8">pt</span><span class="w" id="mwAdA"> </span><span class="o" id="mwAdE">:=</span><span class="w" id="mwAdI"> </span><span class="nx" id="mwAdM">TimerPreset</span><span class="p" id="mwAdQ">);</span> <span class="linenos" data-line="29" id="mwAdU"></span> <span class="linenos" data-line="30" id="mwAdY"></span><span class="w" id="mwAdc"> </span><span class="nx" id="mwAdg">Timer_Done_Bit</span><span class="w" id="mwAdk"> </span><span class="o" id="mwAdo">:=</span><span class="w" id="mwAds"> </span><span class="nx" id="mwAdw">CycleTimer</span><span class="p" id="mwAd0">.</span><span class="nx" id="mwAd4">Q</span><span class="o" id="mwAd8">;</span> <span class="linenos" data-line="31" id="mwAeA"></span><span class="w" id="mwAeE"> </span> <span class="linenos" data-line="32" id="mwAeI"></span><span class="w" id="mwAeM"> </span><span class="nx" id="mwAeQ">CycleCounter</span><span class="p" id="mwAeU">(</span> <span class="linenos" data-line="33" id="mwAeY"></span><span class="w" id="mwAec"> </span><span class="nx" id="mwAeg">cu</span><span class="w" id="mwAek"> </span><span class="o" id="mwAeo">:=</span><span class="w" id="mwAes"> </span><span class="nx" id="mwAew">CycleTimer</span><span class="p" id="mwAe0">.</span><span class="nx" id="mwAe4">Q</span><span class="o" id="mwAe8">,</span> <span class="linenos" data-line="34" id="mwAfA"></span><span class="w" id="mwAfE"> </span><span class="nx" id="mwAfI">r</span><span class="w" id="mwAfM"> </span><span class="o" id="mwAfQ">:=</span><span class="w" id="mwAfU"> </span><span class="nx" id="mwAfY">NOT</span><span class="w" id="mwAfc"> </span><span class="nx" id="mwAfg">Execute</span><span class="o" id="mwAfk">,</span> <span class="linenos" data-line="35" id="mwAfo"></span><span class="w" id="mwAfs"> </span><span class="nx" id="mwAfw">pv</span><span class="w" id="mwAf0"> </span><span class="o" id="mwAf4">:=</span><span class="w" id="mwAf8"> </span><span class="nx" id="mwAgA">Count_Cycles</span><span class="p" id="mwAgE">);</span> <span class="linenos" data-line="36" id="mwAgI"></span> <span class="linenos" data-line="37" id="mwAgM"></span><span class="w" id="mwAgQ"> </span><span class="nx" id="mwAgU">Current_Count</span><span class="w" id="mwAgY"> </span><span class="o" id="mwAgc">:=</span><span class="w" id="mwAgg"> </span><span class="nx" id="mwAgk">CycleCounter</span><span class="p" id="mwAgo">.</span><span class="nx" id="mwAgs">cv</span><span class="o" id="mwAgw">;</span> <span class="linenos" data-line="38" id="mwAg0"></span><span class="w" id="mwAg4"> </span><span class="nx" id="mwAg8">Count_Complete</span><span class="w" id="mwAhA"> </span><span class="o" id="mwAhE">:=</span><span class="w" id="mwAhI"> </span><span class="nx" id="mwAhM">CycleCounter</span><span class="p" id="mwAhQ">.</span><span class="nx" id="mwAhU">q</span><span class="o" id="mwAhY">;</span> <span class="linenos" data-line="39" id="mwAhc"></span><span class="w" id="mwAhg"> </span> <span class="linenos" data-line="40" id="mwAhk"></span><span class="nx" id="mwAho">END_FUNCTION_BLOCK</span>

