A 12. fejezet („Strukturált szöveg (ST)") gyakorlatainak részletes megoldásai és a tudáspróba megoldókulcsa. Előbb dolgozd ki magad, csak utána ellenőrizz!
Gyakorlatok — megoldások
12.1. feladat — Értékeld ki fejben, majd géppel
Megoldás (iA := 4, iB := 10, bC := TRUE)
| # | Kifejezés | Kiértékelés sorrendje | Eredmény |
|---|---|---|---|
| a | iA + iB * 2 |
előbb a szorzás: 10×2 = 20, majd 4+20 | 24 |
| b | (iA + iB) * 2 |
előbb a zárójel: 14, majd ×2 | 28 |
| c | iA > 3 AND iB < 5 OR bC |
előbb az összehasonlítások (TRUE, FALSE), majd AND (FALSE), végül OR TRUE |
TRUE |
| d | iB MOD iA |
10 osztva 4-gyel: maradék | 2 |
| e | NOT bC AND iA = 4 |
előbb NOT bC (FALSE), majd az egyenlőség (TRUE), végül AND |
FALSE |
A c) pont a lényeg: az AND erősebben köt, mint az OR, ezért a kifejezés valójában
(iA > 3 AND iB < 5) OR bC. Ha nem ezt akartuk, zárójelezni kell.
⚠ Gyakori hiba: az operátorok kötési erősségét „balról jobbra” olvasással pótolni. Kétes esetben tegyél zárójelet — az olvashatóság többet ér, mint a rövidség.
12.2. feladat — Javítsd ki a tartományos IF-et
Megoldás
rNyomas = 9.0 esetén a legelső feltétel (> 2.0) teljesül, ezért iSzint := 1 lesz, és
az ELSIF ágak soha nem futnak le. A program 9 bar-nál is 1-es szintet jelez — a hiba
csendes, mert nincs hibaüzenet.
(a) Sorrend megfordítása — a legszigorúbb feltétel elöl:
IF rNyomas > 8.0 THEN iSzint := 3; ELSIF rNyomas > 5.0 THEN iSzint := 2; ELSIF rNyomas > 2.0 THEN iSzint := 1; ELSE iSzint := 0; END_IF
(b) Alsó és felső határ megadása:
IF rNyomas > 8.0 THEN iSzint := 3; ELSIF rNyomas > 5.0 AND rNyomas <= 8.0 THEN iSzint := 2; ELSIF rNyomas > 2.0 AND rNyomas <= 5.0 THEN iSzint := 1; ELSE iSzint := 0; END_IF
Melyik a jobb? Működésre nézve egyenértékűek, de az (a) rövidebb és kevésbé hibázható:
az ELSIF szerkezet természetéből adódik, hogy csak akkor vizsgálódik, ha az előzők nem
teljesültek — a felső határ tehát fölösleges. A (b) viszont olvasásra egyértelműbb,
mert kimondja a tartományt. Csapatmunkában és vizsgadolgozatban a (b) is védhető, ha
következetes. Amit mindkettőben meg kell tartani: az ELSE ág — enélkül 2 bar alatt az
iSzint az előző értékén ragadna.
12.3. feladat — Írd át CASE-re
Megoldás
VAR iNyomasBar : INT; END_VAR iNyomasBar := REAL_TO_INT(rNyomas); CASE iNyomasBar OF 0..2: iSzint := 0; 3..5: iSzint := 1; 6..8: iSzint := 2; ELSE iSzint := 3; END_CASE
Milyen pontosságot veszítesz? A REAL_TO_INT kerekít, tehát a tizedes információ
elvész: 5,4 bar és 5,0 bar ugyanabba a szintbe kerül, és a határok is elcsúsznak az eredeti
> 5.0 feltételhez képest.
Mikor elfogadható? Ha a szintek amúgy is durva kategóriák (kijelzés, jelzőlámpa színe,
naplózási szint), és a határ ±0,5 bar-os bizonytalansága nem okoz gondot. Nem elfogadható
szabályozásnál, riasztási küszöbnél és mindenütt, ahol a határérték biztonsági jelentőségű —
ott maradjon az IF a REAL értékkel.
12.4. feladat — Mérd meg a ciklusidőt
Értékelési szempontok
A várt tapasztalat: a ciklusidő a tömbméret növelésével közel arányosan nő. A pontos
értékek eszközfüggők, ezért a saját mérés a helyes válasz — a jegyzőkönyvben szerepeljen a
task típusa és intervalluma, a Time és a Sensitivity beállítása, valamint a
task-monitorozó átlagos és maximális ciklusideje mindhárom tömbméretnél.
A watchdog akkor lép közbe, amikor egy ciklus túllépi a Time × Sensitivity szorzatot
(8.7). A tanulság nem az, hogy „a FOR ciklus tilos”, hanem az, hogy a hosszú ciklus
felemészti a task idejét — a megoldás a munka több ciklusra osztása.
⚠ Gyakori hiba: a mérés az átlagos ciklusidőre hagyatkozva. A watchdogot a maximum váltja ki (23.7).
12.5. feladat — Írd meg a mintafeladat bővítését
Mintamegoldás
VAR rsSzalag : RS; (* a 12.7. mintafeladatból *) ctuDarab : CTU; (* a 12.7. mintafeladatból *) rtErzekelo : R_TRIG; tpVillan : TP; END_VAR VAR RETAIN iDarab : UDINT; (* (c) túléli az újraindítást — 10.3 *) END_VAR (* (a) a szalag csak zárt biztonsági ajtóval indulhat — a 12.7. mintafeladat RS-logikáját megtartva, kiegészített feltételekkel *) rsSzalag(SET := bIndit AND bAjtoZarva, RESET1 := bLeallit OR bVesz OR NOT bAjtoZarva OR ctuDarab.Q); bSzalag := rsSzalag.Q1; (* darabszámlálás élfigyeléssel — 18.2 *) rtErzekelo(CLK := bErzekelo); IF rtErzekelo.Q THEN iDarab := iDarab + 1; END_IF (* (b) minden 100. darabnál fél másodperces villanás — 17.5 *) tpVillan(IN := rtErzekelo.Q AND (iDarab MOD 100 = 0), PT := T#500MS); bJelzoLampa := tpVillan.Q;
A felhasznált elemek:
| Elem | Honnan |
|---|---|
R_TRIG élfigyelés |
18.2 |
TP impulzusidőzítő |
17.5 |
VAR RETAIN |
10.3 |
MOD operátor |
12.2 |
RS bistabil elem a mintafeladatból |
12.7 |
⚠ Gyakori hiba: a TP bemenetére a iDarab MOD 100 = 0 feltételt élfigyelés nélkül
kötni. A TP ugyan csak felfutó élre indul, de a nulla is osztható százzal: bekapcsoláskor,
nullázott számlálóval a feltétel már igaz, tehát a lámpa mindjárt induláskor felvillan. A két
feltétel AND-elése (ahogy fent) ezt is kizárja, mert az élfigyelő csak valódi darabérkezéskor
ad impulzust.
Tudáspróba — megoldókulcs
| # | Válasz | Indoklás | Szakasz |
|---|---|---|---|
| 1 | a | Az értékadás jele :=; az = az egyenlőség vizsgálata. |
12.1 |
| 2 | b | A zárójel köt a legerősebben — ez a precedenciatáblázat első sora. | 12.2 |
| 3 | c | Az OR a leggyengébben kötő operátor. |
12.2 |
| 4 | d | Az IF/ELSIF láncban az első igaz feltételű ág fut le, a többi nem. |
12.3 |
| 5 | a | A CASE feltétele egész típusú kifejezés. |
12.4 |
| 6 | b | A 10..20 a 10-től 20-ig terjedő tartományt jelenti. |
12.4 |
| 7 | c | A REPEAT a hátultesztelő ciklus, ezért legalább egyszer lefut. |
12.5 |
| 8 | d | A CONTINUE a következő ciklusmenet elejére ugrik (az EXIT lép ki). |
12.5 |
| 9 | a | A soha nem hamis feltétel végtelen ismétlést és futásidejű hibát okoz — a fordító ezt nem veszi észre. | 12.5 |
| 10 | b | Egy cikluson belül az utolsó értékadás érvényesül — ez a kettős írás klasszikus csapdája. | 12.9 |