Do Projektu iAutomatyka dołączyli:

https://iautomatyka.pl/wp-content/uploads/2019/09/s7-300_header.jpg

Adresowanie pośrednie w sterownikach S7 – Tips and Tricks

autor: mateczek.

Adresowanie pośrednie w ogólności polega na tym, że nie podaje się adresu na sztywno a ten adres jest wyliczany i przechowany w jakieś zmiennej. Zmienną, która przechowuje adres nazywamy wskaźnikiem. Wyobraźmy sobie, iż mamy kilkanaście struktur danych w bloku DB i chcemy się dostać do przepisu X pola Y. To jest jedna z tych sytuacji, gdzie samo narzuca się by skorzystać z adresowania pośredniego.  W tym artykule chciałbym przedstawić sposoby realizacji adresowania pośredniego w sterownikach Siemens.

A gdzie w ogóle mamy do czynienia z adresowaniem pośrednim? Są to:

  • pętle (indeksowanie elementów),
  • rzutowanie typów,
  • wskaźniki i arytmetyka na nich.

Artykuł będzie w formie kursu więc więc zaczynamy.

Przykład na rozgrzewkę

W tym przykładzie pokarzę jak uzyskać w metodzie adresowania pośredniego dostęp do n-tego bitu w przestrzeni wejść. Posłużmy się dwulinijkowym programem napisanym w STL:

A     I [MD 0]   //to, o który bit chodzi jest zapisane właśnie w MD0 
=     Q 0.0

No i to już cały program (długością nie poraża🙂). Choć program krótki, to myślę że wart pokazania i wart tego by zaprezentować efekt jego działania. 

  1. Jeśli do MD0 jest wpisane 0 to następuje przepisanie z I0.0 do Q0.0.
  2. A jeśli do MD0 jest wpisana 5 to na Q0.0 jest przepisywany 5 bit (czyli „I0.5”).

Ten przykład miał na celu pokazanie, że w adresowaniu pośrednim po prostu można podawać nr bitu do którego chcemy się odwołać (tą właściwość wykorzystam dalej w tym mini kursie).


Podróż po Bloku Danych – wstęp

Przejdźmy do kolejnego przykładu zastosowania adresowania pośredniego. Niech przykładowy blok danych wygląda jak na rysunku.

Mamy więc takie zestawy parametrów dla poszczególnych przepisów. Napiszmy program, który przy pomocy numeru przepisu wyciągnie nam odpowiednie dane i zapamięta jako parametry aktualne.

L     "Prg_nr"         //będzie przechowywało żądany numer przepisu 
SLD   5                //nr programu mnożenie przez 32. Bo przepis ma właśnie 32 bity   
T     #adrZmienna1     //wskaźnik na "zmienna1" z przepisu określonego w zmiennej "Prg_nr" 
L     16               //tyle bitów ma słowo   
+D   
T     #adrZmienna2    //wskaźnik na  "zmienna2" z przepisu określonego w zmiennej "Prg_nr"

Ten network służył do policzenia ustawienia adresów na aktualną recepturę. Wyjaśniam, że rotacja bitów o jeden w lewo „SLD 1” to inaczej mnożenie przez 2. A ponieważ przepis ma 2 słowa, a słowo ma 2 bajty, a bajt ma 8 bitów to w sumie wychodzi 2*2*8=32 i odpowiada przesunięciu o pięć pól w lewo – „SLD 5”. Przypominam, że adresowanie pośrednie w gruncie rzeczy opiera się na wskazaniu numeru bitu.

W kolejnym networku, korzystając z wyliczonych adresów, po prostu sięgnijmy po nasze parametry aktualne.

OPN   DB     1                        //otwarcie bloku db1 
L     DBW [#adrZmienna1]              //dorwanie się do zmiennej 1 za pomocą adresowania Pośredniego 
T     MW     0                        //parametr aktualny zapamiętanie 
L     DBW [#adrZmienna2]              //dorwanie się do zmiennej 2 za pomocą adresowania Pośredniego 
T     MW     2                       //parametr aktualny zapamiętanie

Wynik działania naszego programu przedstawiam na rysunku poniżej.

I jak widać na rysunku zestaw parametrów „2” ląduje w zmiennych dla parametrów aktualnych.

Podróż po Bloku Danych – Rejestr AR1

Skoro wyliczanie adresów „na krótko” mamy już opanowane, rozwiążmy ten sam problem co wyżej w troszkę inny sposób.

L     "Prg_nr" SLD   5                        //nr programu *8*4=32 bity na przepis 
LAR1                           //adres Struktury ładujemy do rejestru adresowego 
OPN   DB     1                 //otwarcie bloku danych 
L     DBW [AR1,P#0.0]         //adresowanie pośrednie typu Baza+Offset 
T     MW     0                //parametr aktualny 
L     DBW [AR1,P#2.0]         //adresowanie pośrednie typu Baza+Offset 
T     MW     2                //parametr aktualny

Przy pomocy rejestru adresowego „AR1” możemy dorwać się do szukanej zmiennej korzystając z dwóch parametrów: adresu początku struktury, oraz przesunięcia w tej strukturze (offsetu).

Oczywiście ten program będzie działał tak samo jak program z rozdziału wyżej. Więc z tego powodu  zdjęć nie będę dublował. Zapis wykorzystujący rejestr „AR1” jest chyba trochę czytelniejszy, bo jawnie liczymy tylko początek przepisu. A wzór na policzenie początku struktury poniżej.

adresStruktury = nr_przepisu * rozmiar przepisu (w bitach).

Dekodowanie sekwencji – wskaźniki w FB

W tym rozdziale chciałbym przedstawić taką metodę pisania sekwencji, którą ja nazywam licznikową. Jest sobie pewna zmienna, która liczy kolejne kroki programu. Chciałbym przedstawić jak wykorzystać adresowanie pośrednie do zdekodowania licznika sekwencji na tablice kroków programu, lub strukturę z opisem kroków programu.

Instrukcja DECO(FC97) właściwie sama dekoduje „nrLicznika” na numer bitu w podwójnym słowie. Ale jest to niezbyt wygodne w użyciu. Celem programu będzie rzucenie zdekodowanego „nrLicznika” na tablicę (opcjonalnie strukturę). To, na co chciałbym zwrócić uwagę to network drugi. A co tam się dzieję wyjaśniam w punktach poniżej:

  1. Załaduj do akumulatora wskaźnik na tablicę „kroki” (to może być również struktura).
  2. Ten wskaźnik na tablicę (strukturę) „kroki” ląduje w rejestrze adresowym „AR1”.
  3. Załaduj zdekodowany, za pomocą „fc97”, licznik programu do akumulatora.
  4. Odwrócenie bajtów.
  5. Transfer akumulatora na tablicę „kroki”.
    • Transferuj do bloku danych, który jest instancją (DID[] – odwołanie do instancji jako DWord) pod adres, który jest w rejestrze adresowym „AR1” (przypominam, że siedzi tam wskaźnik na tablice „kroki”).
  6.  W ramach ciekawostki i do przeanalizowania.
    • DIX[ar1,p#0.1] Odwołanie się do instancji (jako BIT) gdzie bazę wskazuje rejestr „AR1” (tablica „kroki”) ale dodatkowo plus jeden bit offsetu (czyli po prostu zmienna „kroki[1]” inaczej).

W networku nr. 3 to już tylko prezentacja w LADzie jak „nrLicznika” odwzorowany jest w tablicy „kroki”. A jeśli piszemy program w języku LAD to korzystanie z takiej tablicy czy struktury jest o wiele bardziej przejrzyste.

Uwaga!!!

W dotychczasowych rozdziałach wystąpiły takie odwołania jak DBW[] i DID[]

  • DBW[] stosujemy gdy chcemy się dorwać do otwartego bloku danych (instrukcja OPN ). Zaś DIW[] gdy chcemy się dorwać do bloku danych, który jest instancją FB.  Analogicznie Będzie DIX[] vs DBX[] itp.


Rzutowanie w SCL

SCL jest językiem podobnym składnią do mocno ograniczonego Turbo-Pascala. Umożliwia przy tym w prostszy sposób zrobienie takiego rzucenia słowa na strukturę. W języku tym można  zrobić coś podobnego jak w rozdziale wyżej za pomocą instrukcji „AT” (dodam że, „AT” dostępna w S-1500 nawet w ladzie, ale trzeba doczytać od której wersji TIA i jaki minimalny Firmware sterownika).

Dla przykładu napiszmy program, który wyciągnie nam aktualną minutę i sekundę z czasu pobranego ze sterownika PLC.

Dla zrozumienia programu kluczowe są dwie deklaracje

czas_dt :DT;

Tutaj deklarujemy zmienną „czas_td” jako typ danych „DataAndTime” właśnie tego typu zmiennej wymaga funkcja systemowa „sfc1”. Funkcja „sfc1” pobiera datę i czas z zegara RTC sterownika PLC. Ale mnie w tym przykładzie nie interesuje cała ta zmienna, lecz tylko ta malutka jej część jaką jest aktualna minuta. Należy więc zdekodować czas rzucając zmienną „czas_dt” na przygotowaną wcześniej strukturę

czas AT czas_dt: STRUCT

END_STRUCT;

Tak więc nowa zmienna „czas” będzie strukturą do interpretacji zmiennej „czas_dt”. Zmienne te zajmują dokładnie to samo miejsce. Pisząc do jednej, modyfikujemy drugą. Cały trik polega na tym, że jeden i ten sam adres jest interpretujemy różnie w zależności od sytuacji.

Na dowód tego co pisze, wrzucam wygenerowany blok danych db20. Jak „nie widać” zmiennej „czas” brak w bloku danych.

Struktura „czas” to nie nowa zmienna, ale sposób na interpretację. Podobnie działają unie w C++. W unii kilka typów zmiennych dziedziczy dokładnie tą samą przestrzeń i umożliwia nam różną interpretacje tego samego obszaru pamięci.

Podsumowanie

W tym mini-kursie przedstawiłem zagadnienia związane z adresowaniem pośrednim. To nie są ścisłe podstawy, więc materiał raczej dla osób, które pierwsze starcie z Step7 mają już za sobą. Mam nadzieję, że osobom początkującym przybliży możliwości jakie daje tego typu dostęp do zmiennych. A może komuś mój artykuł posłuży jako ściągawka odnośnie składni. Ja sam tak mam, że jeśli czegoś używam rzadziej to lukam na ściągawki aby sobie składnie jakiegoś wywołania przypomnieć.

Artykuł został nagrodzony w Konkursie iAutomatyka – edycja Wrzesień 2019

Nagrodę Stripax + zestaw gadżetów dostarcza ambasador konkursu, firma Weidmüller



Utworzono: / Kategoria: , , ,

Reklama

Newsletter

Zapisz się i jako pierwszy otrzymuj nowości!



PRZECZYTAJ RÓWNIEŻ



NAJNOWSZE PUBLIKACJE OD UŻYTKOWNIKÓW I FIRM

Reklama



POLECANE FIRMY I PRODUKTY