Texto estruturado

Texto estruturado (structured text, em inglês) é uma linguagem de programação para CLP’s definida pela PLCOpen na norma IEC61131-3. Por ser uma linguagem textual e de alto nível, possibilita a solução de problemas mais complexos, usando comandos básicos da programação como laços de repetição e condicionais.

Esta linguagem de programação é geralmente usada para blocos de função, que são usados em outros programas com outras linguagens como Ladder ou diagrama de blocos. A grande parte dos programas para CLP’s podem ser feitos em linguagens gráficas sem muitas dificuldades porém programas maiores e mais complexos exigem uma linguagem como Texto Estruturado. Uma aspecto positivo é a normatização das linguagens permitir o uso de diferentes linguagens em um único programa oferecendo maior chance de simplificação do problema. xia xia

Sintaxe[1]

De forma geral a linguagem de texto estruturado é muito parecida com o PASCAL e o BASIc.[2] Assim como PASCAL e o BASIc, ela também não é case sensitive, o que significa que letras maiúsculas não são diferenciadas de letras minúsculas. Os programas começam com comando PROGRAM e terminam com END_PROGRAM, a maioria dos comandos são finalizados com ponto e virgula( ;).

Comentários

Comentários são partes do programa que não são executadas, que são usadas para organizar e explicar o código. Para fazer comentários é usado as barras duplas ‘//’ , para uma linha, ou ‘/**/’ para parágrafos

 // Comentário

<comando>; /*Comentário*/

<comando>; (* Comentário *)

/*Comentário
      
  Fim do Comentário*/

Variáveis

Variáveis são espaços de memória, associados a identificadores ou nomes, cuja função é armazenar e representar valores. As variáveis devem ser declaradas entre os termos VAR e END_VAR. Caso sejam declaradas variáveis em um bloco de função, deve-se declarar as variáveis de entrada entre os termos VAR_INPUT e END_VAR, de modo análogo, as variáveis de saída entre os termos VAR_OUTPUT e END_VAR. A declaração deve seguir o padrão: “<nome da variável> : <tipo>;”. Pode-se fazer a inicialização juntamente com a declaração, utilizando a sintaxe: “<nome da variável> : <tipo> := <valor>;”

Exemplo de declaração de variáveis

VAR
BOTAO: BOOL := TRUE;
TEMPERATURA_MOTOR : REAL := 46.7;
SENTIDO:  STRING(7) := Horário;
SENSOR_VELOCIDADE : INT : = 10;
END_VAR

Tipo de Variáveis

Inteiros
IEC Data Type Format Range
SINT Short Integer -128 … 127
INT Integer -32768 … 32767
DINT Double Integer -2^31 … 2^31-1
LINT Long Integer -2^63 … 2^63-1
USINT Unsigned Short Integer 0 … 255
UINT Unsigned Integer 0 … 2^16-1
UDINT Long Double Integer 0 … 2^32-1
ULINT Unsigned Long Integer 0 … 2^64-1
Ponto flutuante
IEC Data Type Format Range
REAL Real Numbers ±10^±38
LREAL Long Real Numbers ±10^±308
Tempo

IEC Data Type

Format

Range

TIME

Duration of time after an event

T#10d4h38m57s12ms

TIME#10d4h38m

DATE

Calendar date

D#1989-05-22

DATE#1989-05-22

TIME_OF_DAY

Time of day

TOD#14:32:07

TIME_OF_DAY#14:32:07.77

DATE_AND_TIME

Date and time of day

DT#1989-06-15-13:56:14.77

DATE_AND_TIME#1989-06-15-13:56:14.77

Strings
IEC Data Type Format Range
STRING Character String ‘My string’
Bit strings
IEC Data Type Format Range
BOOL Boolean 1 bit
BYTE Byte 8 bits
WORD Word 16 bits
DWORD Double Word 32 bits
LWORD Long Word 64 bits
Vetores

São um tipo estrutura que armazena várias variáveis de mesmo tipo, são declaradas através da estrutura: “<nome do vetor> : ARRAY [<ll1>...<ul1>,<ll2>...<ul2> ] OF <tipo dos elementos>:=[<A1> , <A2> …. ,<An>];”. Por exemplo;

vetor : ARRAY[1..5] OF INT := [ 117, 2 ,5 ,40 ,7];
vetor_bool : ARRAY [1..3] OF BOOL := [TRUE, FALSE, FALSE];

Os vetores só podem ser atribuídos com a estrutura “:= [<A1> , <A2> …. ,<An>];”(como no exemplo acima) somente na primeira vez , nas outras ele deve ser atribuído elemento a elemento com a estrutura: “ <nome do vetor>[<posição>]:=<variável ou valor>;” acessado com a estrutura

  <variável>:=<nome do vetor>[<posição>];
Structs

São uma estrutura que armazena variáveis de diferentes tipos. São declaradas usando o modelo

TYPE <Nome>
STRUCT
<variavel 1>
<variavel 2>

<variável N>
END_STRUCT
END_TYPE

Operadores

Os operadores servem para manipular os diferentes tipos de dados. A existência de operadores faz com que o texto estruturado seja mais fácil de programar comandos mais complexos, se forem comparadas com as outras linguagens de CLP’s.

Operação

Símbolo

Precedência

Expressão parentizada

(expressão)

Alta

Executa a função

Função(...)

Negação

Complemento booleano

-

NOT

Exponenciação

**

Multiplicação

Divisão

Módulo

*

/

MOD

Soma

Subtração

+

-

Comparação

<,>, <=, >=

Igualdade

Desigualdade

=

<>

E booleano

AND, &

OU exclusivo booleano

XOR

OU booleano

OR

Baixa

Atribuição

Para fazer atribuições às variáveis é necessário o uso da sintaxe ‘:=’ , onde a variável a esquerda recebe o valor a direita do símbolo <Variavel que recebe> := <variavel, valor ou operação>;

Condicionais

Estas estruturas são úteis para realização de testes ou decisões. Caso alguma expressão booleana seja verdadeira ele executa uma ação, caso contrário o programa continua. As expressões mais comuns são o IF...THEN; ELSE e ELSIF. Existem algumas variações do IF...THEN que podem ser observadas abaixo.

IF … THEN
IF <expressão booleana> THEN
        <comandos>;/*Executa caso a expressão booleana for verdadeira*/
    END_IF;
IF...THEN...ELSE
    IF <expressão booleana> THEN
        <comandos>;/*Executa caso a expressão booleana for verdadeira*/
    ELSE
        <comandos>;/* Executa caso a expressão booleana for falsa*/
    END_IF;
IF...THEN...ELSIF...ELSE
    IF <expressão booleana(1)> THEN
        <comandos>;/*Executa caso a expressão booleana(1) for verdadeira*/
    ELSIF <expressão booleana(2)>
        <comandos>;/* Executa caso a expressão booleana(2) for falsa*/
    ELSE
        <comandos>;/* Executa caso ambas expressões booleanas forem falsas*/
    END_IF;
CASE...OF

A estrutura CASE...OF é uma estrutura condicional que utiliza uma expressão numérica ao invés de uma expressão booleana, ela pode ser utilizada com um seletor.

    CASE <expressão numérica> OF /*A expressão numérica pode ser do tipo: SINT, INT, DINT ou REAL*/
        <seletor1> : <comandos>;/* Executa caso (expressão numérica = seletor1)*/
        <seletor2> : <comandos>;/* Executa caso (expressão numérica = seletor2)*/
<seletor3> : <comandos>;/* Executa caso (expressão numérica = seletor3)*/
ELSE
    <comandos>;/* Executa caso a expressão numérica não coincida com os seletores*/
END_CASE;

Laços de Repetição

Um dos aspectos mais importantes do Texto Estruturado é a possibilidade do uso de laços para repetir linhas de código. Laços de repetição permitem executar uma série de linhas de código várias vezes até se atingir uma condição de parada. Laços de repetição são ferramentas úteis na programação de vários processos e podem ser complicados de se implementar usando a linguagem Ladder ou diagrama de blocos, por exemplo. Caso se deseje abortar a execução do laço de repetição, basta adicionar o comando “EXIT”, que fará com que o laço de repetição seja interrompido imediatamente e a execução do programa continue. Os laços de repetição são comumente usados em conjunto com estruturas condicionais.

FOR...DO

O laço FOR é utilizado para se executar o código um certo número de vezes. O aspecto que destaca este laço de repetição dos outros é que sempre há a presença de um contador o qual é usado para se pré determinar o número de vezes que o código será repetido. O valor deste contador pode ser utilizado nas instruções dentro do laço FOR.

FOR <contador>:=<valor inicial> TO <valor final>BY <incremento> DO
    <comandos>;/*Executa enquanto o contador não alcançar o valor final*/
END_FOR;

Caso não seja declarado o valor do incremento, será considerado igual a um.

WHILE...DO

O laço WHILE realiza algumas instruções enquanto certa condição, que corresponde a uma expressão booleana, é verdadeira. O laço começa com a checagem da condição, caso ela seja verdadeira o laço é iniciado. Caso seja falsa o programa nem chega a executar as instruções contidas no laço e da continuação ao resto do código. Uma vez dentro do laço, cada vez que a execução dos comandos for concluída a condição de parada é checada novamente. Caso ainda seja verdadeira os comandos serão repetidos. Caso seja falsa o laço é encerrado e se prossegue com a execução do código.

WHILE <expressão booleana> DO
    <comandos>; /*Executa caso a expressão booleana for verdadeira*/
END_WHILE;
REPEAT… UNTIL

Este laço funciona de maneira oposta ao WHILE, as linhas de código a serem repetidas são executadas e então se realiza a checagem da expressão booleana de condição de parada. Caso a expressão seja falsa o código será repetido. Caso a expressão seja verdadeira o laço é encerrado e segue com a execução normal do programa. Sendo assim é garantido que as instruções contidas no laço serão executadas pelo menos uma vez mesmo que a expressão booleana que corresponde a condição de parada seja verdadeira.

           REPEAT
<comandos>; /*Executa caso seja a primeira iteração, ou caso a expressão booleana for verdadeira*/
    UNTIL <expressão booleana>
END_REPEAT;

Exemplos

Exemplo Inversor: Neste programa deseja-se inverter o texto que está dentro da variável “TEXTO”

PROGRAM EXEMPLO_INVERSOR
VAR
    TEXTO: STRING(17) := 'ODARUTURTSE_OTXET'; (* Texto que será invertido *)
    TEXTO_INVERTIDO: STRING(17) := ''; (* Variável que receberá o texto invertido*)
    CONTADOR: INT; (* Variável que contará as iteraçãoes realizadas*)
END_VAR;

FOR CONTADOR := 16 TO 0 BY -1 DO (*  A variável CONTADOR inicia com o valor 16 e vai até 0, com um incremento de -1 *)
    TEXTO_INVERTIDO[16 - CONTADOR] := TEXTO[CONTADOR]; (* A string TEXTO_INVERTIDO recebe os valores da string TEXTO *)
    (*Na primeira iteração teremos que TEXTO_INVERTIDO[16-16] := TEXTO[16], ou seja a vairável TEXTO_INVERTIDO recebe o último caractere da variável TEXTO *)
END_FOR;
END_PROGRAM;

No próximo exemplo temos um bloco de função para um programa qualquer. Neste bloco temos um condicional que verifica o estado de um sensor e determina a ligação de um alarme, caso o alarme seja acionado ele não permite que o resultado seja verdadeiro, mesmo que a variável ligar seja verdadeira. Se o alarme estiver desligado, ou seja, falso, ele permite que o resultado seja verdadeiro.

Diagrama em Ladder do exemplo ao lado
FUNCTION_BLOCK EXEMPLO_BLOCO
VAR_INPUT
    LIGAR : BOOL;
    SENSOR_PRESSAO : INT;
END_VAR;
VAR_OUTPUT
    RESULTADO : BOOL;
    ALARME : BOOL;
END_VAR;
IF SENSOR_PRESSAO < 50 THEN
    ALARME := FALSE; (*Executa caso o valor da variável SENSOR_PRESSAO for menor que 50*)
ELSE
    ALARME := TRUE;    (*Executa caso a afirmação acima for falsa*)
END_IF;
IF LIGAR AND NOT ALARME THEN
    RESULTADO := TRUE; (*Executa caso o valor da variável LIGAR for verdadeiro e o valor da variável ALARME for falso*)
ELSE
    RESULTADO := FALSE;(*Executa caso a afirmação acima for falsa*)
END_IF;
END_FUNCTION_BLOCK;

Aqui temos o mesmo programa em linguagem Ladder, perceba que uma simples comparação feita em texto estruturado com um IF..THEN, em Ladder precisamos usar um bloco de função.

Referências

  1. «Structured Text Tutorial For PLC Programmers». PLC Academy (em inglês). Consultado em 19 de novembro de 2015 
  2. Rockwell Automation (novembro 2012). «Logicx5000 Controllers Structured Text» (PDF). Allen-Bradley. Consultado em 19 de novembro de 2015