C keelega tutvume siin:

https://robolabor.ee/homelab/et/programming/c/crashcourse

ST keel, neile kes tunneb C

Konspekt venekeelsest dokumendist
http://codesys.ru/docs/st_c.pdf

Andmetüübid

täisarvud:

SINT (char)
USINT (märkimata märgid)
INT (lühike int)
UINT (märkimata int)
DINT (long)
UDINT (märkimata pikk)
LINT (64-bitine täisarv)
ULINT (64 bittine märgistatud täisarv) 

Reaalarvud:

REAL (float)
LREAL (double). 

Eritüübid BYTE, WORD, DWORD, LWORD on vastavalt 8, 16, 32 ja 64-bitised bitistringid. ST-s ei ole bittvälju. Bittide stringidele saab otse bitini juurde pääseda. Näiteks:

a.3 := 1; (* Muutuja a 3. biti seadistamine *)

Bittstringidega võib kasutada täisarvude operatsioone.

Loogiline tüüp on BOOL. Võib omada väärtust TRUE või FALSE. Füüsiliselt võib BOOL tüüpi muutuja vastata ühele bitile. Tavaliselt on see nii, kui tegemist on PLC binaarse sisendi või väljundiga või otseselt adresseeritava muutujaga. Selle põhjuseks on see, et enamik mikroprotsessoreid ei ole võimelised otse adresseerima üksikuid mälubitte.

'STRING' tüüpi stringid. On just stringid aga mitte massiivid. Seetõttu ei ole võimalik adresseerida üksikuid märke. Kuid stringide võrdlemine ja kopeerimine on võimalik, kasutades standardseid operaatoreid. Näiteks: strA := strB. IEC-l on stringide käsitlemiseks standardne funktsioonide kogum. Stringide sisemine vorming ei ole standardiseeritud.

IEC standardis on määratletud eritüübid kestuse (TIME), kellaaja (TOD), kalendripäeva (DATE) ja ajatempli (DT) jaoks. Töötamine aja ja intervallidega on PLC-programmides tavaline.

Struktuuride (STRUCT) kasutamine ei erine C-keelest. Struktuuri kirjeldus peab eelnema selle tüüpi muutuja deklareerimisele. Lubatud on sisseehitatud struktuurid ja massiivid.

Massiivid (ARRAY) võib moodustada mis tahes tüüpi elementidest, sealhulgas struktuuridest ja massiividest. Omapäradest tuleb märkida, et väärtusi võib initsialiseerimise ajal korrata.

Näiteks:

bX ARRAY[0..20] OF BOOL := TRUE, 10(FALSE), 9(TRUE); 

Väärtust FALSE korratakse siin 10 korda ja väärtust TRUE vastavalt 9 korda. Massiivid (ja struktuurid) saab kopeerida tavalise omistusoperatsiooni abil: bY := bX; Loendused on sarnased C loendustega. Näide:

TYP TEMPO: 
  (Adagio := 1, Andante := 2); 
END_TYPE

Terviktüüpide abil saab luua tüüpe, millel on piiratud väärtusvahemik. Näiteks:

TYPE DAC10: 
  INT (0..16#3FF); 
END_TYPE

Iga tüübi jaoks võib luua aliase (typedef C). Näiteks:

TYPE DEGR : UINT 
END_TYPE. 

 ~

Konstandid.

IEC kasutab tüpiseeritud konstante. Näiteks:

2#10001000 (bait binaarses formaadis)
INT#40 (täisarv) 
t#10h14m5s (kellaaeg)
D#2006-01-31 (kuupäev)

Märgikonstandid saab deklareerida lokaalselt või globaalselt spetsiaalses deklareerimislõikes: VAR_CONSTANT.

Identifikaatorid.

 ~

Muutujate initsialiseerimine.

Vaikimisi on kõik muutujad initsialiseeritud nulliga. Muutuja deklareerimisel võib selgesõnaliselt määrata muutuja teistsuguse väärtuse. Näiteks:

str1: STRING := 'Hello world'. 

Muutujaid võib deklareerida RETAIN või PERSISTENT. See tähendab, et neid tuleb paigutada mittepüsivasse kontrollerimällu (kui see on saadaval). Need initsialiseeritakse ainult programmi esmakordsel käivitamisel või spetsiaalse käsuga.

 ~

**Kaudne adresseerimine.

Lisaks üldisele andmemälule on kontrolleril 3 erimäluala. Need on sisendpiirkond, väljundpiirkond ja otseaadresseeritav piirkond. Neid alasid kasutatakse kontrolleri käivitussüsteemi ja kasutaja programmi vaheliseks suhtlemiseks. Kõige lihtsamatel PLC-del on mälu eraldamine I/O-piirkonnas tootja poolt fikseeritud. Me võime vajaliku aadressi otse programmist adresseerida (nt %QB5 annab väljundpiirkonna 5. baidi) või deklareerida vastavas kohas asuva muutuja.

 ~

Tüübi teisendamine.

Implicit tüübikonversioon on keelatud. Igasugune teisendamine tuleb teha selgesõnaliselt, kasutades spetsiaalseid operaatoreid. Neid on lihtne meeles pidada. Kirjutame lähtetüübi, seejärel _TO_ ja soovitud tüübi. Näiteks:

iX := REAL_TO_INT(rX);

 ~

Operaatorid ja funktsioonid.

Kõige sagedamini kasutatavad ST-operaatorid ja funktsioonid on loetletud tabelis 1. IEC määratleb mitmeid üldisi ja spetsialiseeritud (PLC-programmide jaoks) funktsioone ja funktsionaalseid plokke. Nende hulka kuuluvad taimerid, trigerid, loendurid, regulaatorid ja muud.

Operatsioon ST
Määramine :=
Algebraoperatsioonid +, -, *, /
Märkide asendamine -
Jaotuse jäägid MOD
Absoluutväärtus ABS
Võrdlused < , > , <= , >=
Võrdsus, ebavõrdsus = , <>
JA, VÕI, MITTE JA, VÕI, MITTE
Eksklusiivne VÕI XOR
bitiivi nihutamine vasakule SHL(in,n)
paremale SHR(in,n)
Tsükliline nihe vasakule ROL(in,n)
paremale ROR(in,n)
Kahe väärtuse valik MAX(in0, in1)
suurim, väikseim `` MIN(in0, in1)`
Binaarne valik SEL(g, in0, in1)
Multiplekser MUX(k, in0,...,inN).

Tabel 1: ST põhilised operaatorid ja funktsioonid.

Kirjutamine ++x; või x += 1; on ST-s loomulikult võimatu. Ainus võimalus on x := x + 1;.

sizeof.

Operaator SIZEOF(in). Selle tähendus peaks olema C programmeerijatele ilmselge.

sprintf.

ST-s sellist operaatorit ei ole. Mis tahes tüüpi muutuja saab teisendada stringiks, kasutades `.._TO_STRING'.

Viited.

pt : POINTER TO INT; 
var_int1:INT; 
var_int2:INT; 
pt := ADR(var_int1); 
var_int2 := pt^; 

Ühendused. Vajaduse korral saab sellest mööda minna, paigutades mitu eri tüüpi muutujat samale aadressile otse adresseeritavasse mällu või näitajate abil. Samamoodi saab stringi elementidele ligi pääseda, "sobitades" seda massiiviga.

Semikoolon

Hoolimata ST selgest sugulusest Pascali keelega, kasutatakse selles semikoolonit nagu C keeles. *See ei ole mitte eraldaja, vaid operaatori lõpu märk. *Looduslikult võib üks rida sisaldada suvalist arvu operaatoreid. Lisaks toimib semikoolon tühja operaatorina. Iga programmi komponendi (POU) tekst ST-s peab sisaldama vähemalt ühte operaatorit.

Programmsed sulud.

ST-s ei ole tavalisi programmi sulgusid ( {} C-s või begin ja end Pascalis). Selle asemel on igal programmikonstruktsioonil oma sulgev programmi sulgur. Näiteks: END_FUNCTION või END_IF. Igaüks, kellel on olnud "õnn" näha C keeles mitmetasandilisi sulgemissulgureid, peaks seda lahendust mõistma.

IF ELSE.

IF-lause on peaaegu samaväärne C-s vastava avaldusega. Tingimus võib olla ainult loogilist tüüpi muutuja või avaldis. Vastasel juhul tuleb teha selgesõnaline teisendus loogiliseks tüübiks.

IF <tingimus1> THEN
  <Statement1>
ELSIF <tingimus2> THEN
  <Statement2>
ELSE
  <Statement3>
END_IF;

CASE.

Sarnane switchiga C-s. Alternatiivsetel harudel ei ole programmi sulgevat sulgurit ja neid ei saa üksteise järel käivitada. Vastavalt on operaator break mõttetu ja puudub. Alternatiivsete konstandide väärtuste määramisel võib neid loetleda komadega eraldatult või määrata vahemiku. Näiteks:

CASE (x + 2)/3 OF
  0:
      y := 1;
  1,2:
      y := 4;
      z := 5;
  3..50:
      y := 7
ELSE
      y := 0;
END_CASE

WHILE ja REPEAT.

WHILE tsükkel on täpselt sama, mis on while tsükkel C-s. REPEAT UNTIL' vastab do while'-le. Peen erinevus seisneb selles, et REPEAT täidetakse seni, kuni tingimus on TRUE.

FOR.

FOR-tsüklit kasutatakse väljendite rühma teadaoleva arvu kordade täitmiseks. tsükkel sisaldab algväärtuse, lõppväärtuse, valikuliselt sammu (vaikimisi 1) ja tsükli keha määramist. Näide:

FOR I := 1 TO 100 BY 10 DO x := x*y; END_FOR 

C-keeles vastab see järgmisele:

for (I = 1; I <= 100; I += 10) x = x*y; 

Lõpmatu tsükkel ST-s kirjutatakse tavaliselt kui WHILE TRUE DO.

Operaatorile break ST-tsükklides vastab operaator EXIT. Operaatorit continue ei ole.

main ja PLC_PRG.

Täitmise peatamine ja kontrolli tagastamine operatsioonisüsteemile tähendaks kontrollerprogrammi täielikku kokkuvarisemist. Seetõttu on igal kontrollerprogrammil tsükkel:

while(1)
{
  ReadInputs();
  PLC_PRG();
  WriteOutputs();
}

Multitasking-projektides loob operatsioonsüsteem iga ülesande jaoks sõltumatu põhitsükli. Iga teie programm käivitub tsüklis, kui te ei võta erimeetmeid.

Võtke seda kui tõsiasja. Sellega ei ole raskusi; selle õppimiseks kulub paar tundi.

Multitasking.

Multitasking on saadaval isegi 8-bitise mikroprotsessoriga PLC-dele, millel puudub operatsioonisüsteem. Kõige lihtsamal juhul asendab süsteem ühe PLC_PRG kutsumise asemel vaheldumisi kutsed erinevatele kasutajaprogrammidele. Loomulikult võttes arvesse nende prioriteete ja täitmistsükli aega. Niimoodi ongi mittetõrjuv multitegumtöötlus rakendatud.

Minimaalne ülesande tsükliaeg ja käivitavate sündmuste loetelu tuleb täpsustada kontrolleri dokumentatsioonis.

Funktsioonid.

C kasutab funktsiooni väärtuse tagastamiseks return(). IEC-s on igal funktsioonil kaudselt deklareeritud muutuja, mille väärtus tagastatakse. Selle nimi on sama, mis funktsiooni nimi. See tähendab

int GetX(int x) { ... return(x); } 

ST-s näeks välja nii:

GetX := x; 
RETURN; 

Nagu C-s, saab funktsiooni kutsumisel anda parameetrid üle, loetledes need sulgudes, eraldatuna komadega: GetXY(1,2).

Funktsiooni muutujate jaoks eraldatakse mälu virna.

Sisemuutujate väärtusi ei salvestata kutsete vahel (kuid mitte funktsioonaalplokkide puhul). Lokaalseid staatilisi muutujaid funktsioonides ei deklareerita. Funktsioonide ja funktsioonaalplokkide puhul on lubatud parameetrite üleandmine viitega (VAR_IN_OUT).

IEC-funktsioonidel võib olla muutuv arv parameetreid. Tüüpiline näide on tabelis 1 esitatud funktsioon MUX. See võib käsitleda muutuvat arvu parameetreid ja mis tahes tüüpi parameetreid.

Tühja tüüpi ei ole. Igal funktsioonil peab olema vähemalt üks parameeter ja see peab tagastama väärtuse. Kasutage BOOL tüüpi, see pakub minimaalset koormust. Nagu C-s, võib funktsioonikõnesid lisada väljenditesse.

Funktsioonaalplokid.

Funktsioonaalplokis antakse parameetrid üle väärtuste määramisega: GetX(x := 2).

Andmete deklareerimisel eraldatakse sisend, väljund ja siseseid muutujaid. Funktsioonaalploki deklareerimise põhjal võib deklareerida ühe või mitu eksemplari. Eksemplari deklareerimine põhjustab andmemälu eraldamise, nagu ka struktuuri tüüpi muutujate loomine.

Loomulikult ei suurenda see koodi. Erinevalt funktsioonist säilivad funktsioonaalploki eksemplari muutujad selle väljakutsete vahel. See tähendab, et eksemplari muutujatele on võimalik igal ajal ligi pääseda, sõltumata selle kutsest.

Eksemplari deklaratsioonis võib teha muutujate täiendavat initsialiseerimist.

ST-st C-le tõlkimisel tuleb iga funktsioonaalploki jaoks kirjutada initsialiseerimisfunktsioon.