SCL與STL的區別是什麼?

SCL與STL的區別是什麼?

一、SCL 與 STL

SCL(Structured Control Language)語言,也就是結構化控制語言,它其實和IEC標準制定的ST語言是一樣的。S7-SCL 可以編譯成 STL, 雖然其程式碼量相對於 STL 程式設計有所增加,但我們更關心的是程式結構和程式的總體效率。類似於計算機行業的發展,組合語言已經被捨棄,取而代之的是 C/C++等高階語言。S7-SCL 對工程設計人員要求較高,需要其具有一定的計算機高階語言的知識和程式設計技巧。

STL是STEP7時代推出的語言,它不是STRUCT TEXT LANGUAGE的縮寫,所以它和ST語言完全沒關係。STL語言是一種組合語言,是面向機器底層的語言,可以直接操作暫存器,可讀性不強,和80C51微控制器的機器語言是一個層面。所以它是一種低階語言,而ST和SCL都是中高階語言。

二、S7-SCL 常見問題

1)如何規範地的開發一個 S7-SCL 程式?

解答:開發一個 S7-SCL 程式,應當遵循如下流程:

規劃需要的塊型別,即程式的整體結構;

規劃子任務(FB,FC 等等);

定義各個子任務的之間輸入/輸出介面;

定義各個子任務在原檔案中的順序及呼叫關係;

定義符號表

編譯檢查;

下載除錯。

2)S7-SCL 支援哪些 STEP7 塊,與其它語言有什麼關係?

解答:S7-SCL 支援如下

STEP7 的塊:OB,FC,FB,DB,UDT。

在 S7 程式中,S7-SCL 塊可以與其它STEP7 程式語言生成的塊互相呼叫。

S7-SCL 可以被編譯成 STL, S7-SCL 生成的塊也可以作為庫檔案被其它語言引用。

由於 S7-SCL 程式由 ASCII 文字構成,所以它非常容易被匯入或匯出。

3)為什麼雙擊開啟 S7-SCL 型別的程式後,顯示的格式卻是 STL 格式?

解答:S7-SCL 程式編譯後生成的執行程式碼實際上為 STL 格式,如下圖中的 FC1, 雖然其標示為 SCL格式,但如果使用者將 Source 目錄中的 FC1 的原始檔刪除後,再雙擊開啟 FC1 後,顯示的將為 STL格式。

4)什麼是 OK Flag?

解答:在 S7-SCL 程式中,OK 是一個布林型別的特殊本地變數。它用來顯示塊執行是否正確。

OK 標誌的使用與 STL 程式設計中對於 FC/FB 的 ENO 處理(STL 是用狀態字的 BR 位來儲存狀態)非常相似。

在程式的開始,可以將 OK 標誌賦值為 TURE,如果程式執行有錯誤(例如 0 作為除數),則當程式退出時,使用者透過程式將 OK 標誌改寫為 FALSE,此數值將被儲存在輸出引數 ENO 當中。

OK 標誌是一個系統變數,不需要定義,如果使用者希望在程式中使用此標誌,可以在 S7-SCL程式設計選單 Options>Customize>Compiler 中,應當選擇 Set OK flag。項。否則 ENO 將無法被評估。

OK 標誌使用的例子:

OK:= TRUE;

Division:= 1 / IN;

IF OK THEN // 除法操作正常;

// 此處可以新增在除法操作正常情況下,其它的使用者程式ELSE //除法操作不正常;

// :END_IF;

5)在 STL 中可以讀取一個組織塊的資訊 (例如 OB1 中的迴圈時間),在 S7-SCL 中是否存在同樣的可能?

解答:STEP7 中的任意 OB 塊在生成之後,其內部都自動生成一些特有的臨時變數,例如 OB1 中的變數OB1_PREV_CYCLE 即為CPU 上個掃描週期所用的時間。在 S7-SCL 編輯器中,透過“Insert> Block Template > OB”建立一個 OB 模板。

在預設情況下,此模板的臨時變數區域將建立一個ARRAY OF BYTE 型別的臨時變數。此區域與 OB 塊的臨時變數區域是相對應的,但由於沒有變數名稱標識,並且資料型別也不相同,所以使用者使用起來非常不方便。如果使用者想要使用 S7-SCL格式的 OB 塊內的特有變數,請按下列步驟進行:

在路徑 STEP7 的安裝路徑 \Step7\S7DATA\S7wiz 下,包含所有 OB 塊的 STL 格式模板,可以使用寫字板開啟這些模板 (例如 OB31.awl), 並複製相應變數定義。

建立一個新的 S7-SCL 原始檔並插入剛才複製的變數定義。

調整 S7-SCL 原始檔中的語法結構;

在這個程式的開始部分, 可以設定 "Title" 和"Version" , 例如 Title=' ' 和 Version= '0.1';

在 BEGIN 語句後面插入一個分號,至此,即完成格式修改。另外,也可以開啟本文中的 S7-SCL 例子目錄中的 OB_Templ 專案,其中包括了 44 個 S7-SCL 原始檔格式的組織塊。

6)如何理解 FC/SFC 的輸出引數 RET_VAL(返回值)?

解答:對於此問題,如果讀者對 PASCAL 語言或者高階程式語言非常熟悉,可能此問題就非常容易解釋。許多 SFC (系統功能) 都有輸出引數 RET_VAL (返回值) ,它提供一個可供評估的錯誤程式碼。STEP 7 線上幫助中提供有更多關於系統功能和輸出引數 RET_VAL 的資訊。

透過在 SIMATIC管理器中選中 SFC 然後按“F1”鍵可以獲取相關的線上幫助資訊。同樣,一個 FC 也可以返回一個結果,下面給出了一些例子,說明了如何在 S7-SCL 中呼叫帶有返回值 (RET_VAL) 的功能 (FC 或 SFC)。

定義 FC1, 函式型別為 INT (返回值)

呼叫 FC1,得到返回值:

呼叫一個系統功能 (SFC24):當呼叫系統功能 SFC 24 “TEST_DB”(測試資料塊) 時,得到關於 CPU主記憶體中一個數據塊的資訊。SFC24 確定指定 DB 的資料位元組數,並檢查該 DB 是否受到防寫。選定 DB 所包含的資料位元組數透過引數“DB_LENGTH”輸出,引數“WRITE_PROT”包含關於選定 DB 的防寫 ID 的資訊 (FALSE 表示沒有防寫)。

SCL與STL的區別是什麼?

7)在 S7-SCL 程式中,PLC 中的地址標識與 STL/LAD 中的地址標識有何區別,使用中有何注意事項?

解答:在 S7-SCL 程式中,PLC 中的地址標識與 STL/LAD 中的地址標識基本相同,方便了程式設計人員快速掌握 S7-SCL 語言。下圖為 PLC 中的 S7-SCL 程式地址標識格式,圖中一些格式有些特殊,實際上,下面的格式在 S7-SCL 中都是正確的。

DB1.D0.0:=DB1.DBX0.1;

DB1.DB1:=DB1.DBB1;

DB1.DW2:=DB1.DBW2;

DB1.DD4:=DB1.DBD4;

QX0.0:=Q0.0;

IX0.0:=I0.0;

MX0.0:=M0.0;

所以說,在一般情況下,程式設計人員依舊可以 STL 的標識方式用於 S7-SCL。注意:如果資料塊編號及地址都使用了間接定址方式,則必須使用 S7-SCL特定的標識方式,例如如下語句:

STATUS_1:=WORD_TO_BLOCK(INDEX).DW [COUNTER]; (此格式正確)

STATUS_1:=WORD_TO_BLOCK(INDEX).DBW [COUNTER] ; (此格式錯誤)

SCL與STL的區別是什麼?

上圖為S7-SCL 中的 PLC 地址格式。x 可以為 0 至 65535 之間的數字(絕對地址),y 可以為 0 至 7 之間的數字(位地址),對於其它 FB,OB,DB, T,C 等等的標識格式,S7-SCL 格式基本與 STL 格式相同,此處不做說明。

8)為什麼使用者人工輸入的程式在編譯時經常提示語法錯誤?

解答:S7-SCL 程式和所有的高階語言一樣,有著自己特定的語法,而很多程式設計人員容易在人工輸入程式時忽視語法格式,這樣就造成編譯錯誤。因此強烈建議程式設計人員使用 S7-SCL 的模板嚮導。在選單 Insert 中,提供了 Block Call, Block Template, Control Structure, 三個嚮導,使用者可以透過使用此嚮導,提高輸入效率。例如在下圖中指出了兩個常見錯誤,使用者如果使用嚮導,就不容易出錯誤:

SCL與STL的區別是什麼?

9)S7-SCL 程式中如何使用多重背景?

解答:S7-SCL 程式中可以使用多重背景,下面的程式列出了正確格式,宣告完成後,在程式中即可呼叫:

Supply1 : FB10; //將 Supply1 定義為 FB10 型別;

Supply2,Supply3,Supply4 : FB100;

//將 Supply2,Supply3,Supply4 定義為 FB100 型別。

10)如何在 S7-SCL 程式中實現資料塊間接定址?

解答:S7-SCL 程式中對資料塊間接定址提供了良好的支援,程式設計也很簡單。

下面的程式列出了正確格式:

STATUS_1:= DB11.DW[COUNTER]; //位元組間接定址;

STATUS_2:= DB12.DX[WNO, BITNO]; //位間接定址,使用者改變 WNO,BITNO 數值即可;

STATUS_1:= Database1.DW[COUNTER];// Database1 為 DB 型別的本地變數;

STATUS_2:= Database2.DX[WNO, BITNO];

STATUS_1:=WORD_TO_BLOCK_DB(INDEX).DW[COUNTER];

//INDEX 被定義為 BLOCK_DB 資料型別,COUNTER 為整數資料型別,這樣可以實現資料塊編號,位元組地址同時間接定址,此功能是一種功能很強間接定址方式。

以下是資料塊直接定址方式格式:

STATUSBYTE :=DB101.DB10; //位元組直接定址格式;

STATUS_3 :=DB30.D1.1; //位直接定址格式;

MEASVAL :=DB25.DW20; //字直接定址格式;

STATUSBYTE :=Status_data.DB10;

STATUS_3:="New data ".D1.1;

MEASVAL :=Measdata.DW20;

STATUS_1 :=WORD_TO_BLOCK_DB (INDEX).DW10;

11)在 S7-SCL 程式中呼叫 FC/FB 與在 STL/LAD 中呼叫 FB/FC 有何區別?

解答:在 STL/LAD 程式中呼叫 FB 可以不把引數填寫完整,但在 S7-SCL 程式中呼叫 FB 時,必須把FB引數填寫完整;對於FC的呼叫S7-SCL與STL/LAD區別不大。強烈建議程式設計人員使用S7-SCL的模板嚮導呼叫 FB。

12)為了將 S7-SCL 中的位資料型別(BYTE, WORD 或 DWORD)轉換到“REAL”資料型別時,需要使用哪種資料型別轉換程式?

解答:為了將 S7-SCL 中的位資料型別(BYTE, WORD 或 DWORD)轉換到數字資料型別“REAL”時,需要使用以下指令:

從 BYTE 到 REAL:“DINT_TO_REAL(DWORD_TO_DINT(BYTE_TO_DWORD(value)) ”

從 WORD 到 REAL:“DINT_TO_REAL(DWORD_TO_DINT(WORD_TO_DWORD(value))”

從 DWORD 到 REAL:“DINT_TO_REAL(DWORD_TO_DINT(value)) ”

注意事項:使用者在將 BYTE, WORD 或 DWORD 資料型別轉換到 “REAL” 資料型別時,S7-SCL中常見的錯誤可以參考下例:

從WORD 到 REAL:“DWORD_TO_REAL(WORD_TO_DWORD(value))”(錯誤程式)。

如果執行了這一轉換,會得到錯誤的結果。原因:DINT_TO_REAL 函式將把源資料轉換並按照 IEEE REAL 的格式儲存到目的變數,而DWORD_TO_REAL 僅僅是從源資料複製位串至目的變數。因此,為了獲得正確的“REAL”數,必須總是透過中間步驟“DWORD_TO_DINT”和“DINT_TO_REAL”實現。

13)在 S7-SCL 中如何區分某個變數名是本地變數,還是符號名?

解答:S7-SCL 中本地變數與符號名的引用有如下區別:

如果引用中只有變數名,則此變數為本地變數,如:Motor_Status:= Motor_1;

如果引用中變數名稱上包括“”,則此變數為符號名,如:Motor_Status:= “Motor_1”。

14)如何訪問一個字串中的單個字元?

解答:對於字串中的單個字元,使用如下的訪問格式,是錯誤的:

MB10 := str[5] 這樣的表示式無法實現將字串的第 5 個字元送至 MB10 中。

方法:可以使用 IEC 函式 MID 來得到字串的某個部分,例子如下:

VAR

str : STRING[20];

END_VAR

MB10:=CHAR_TO_BYTE(STRING_TO_CHAR(MID(IN:=str,L:=1,P:=5)));

15)如何加密我的 S7-SCL 程式?

解答:S7-SCL 程式加密與 STL 程式加密方法幾乎一樣,使用者可以在程式中加入關鍵字:

KNOW_HOW_PROTECT,再進行編譯即可,下圖中的 FC1 在編譯後,即出現了加鎖保護的圖示 。

注意:提供給終端使用者的專案中應當刪除 S7-SCL 原始碼,否則使用者在雙擊加密的塊後(例如下圖中的 FC1),依然可以關聯開啟 S7-SCL 原始碼。

SCL與STL的區別是什麼?

注意:提供給終端使用者的專案中如果刪除 S7-SCL 原始碼,使用者將只能看到 STL 格式的程式,稍微複雜些的 S7-SCL 程式在 STL 格式下幾乎是無法閱讀的。此方法類似於加密的效果。

16)如何對 S7-SCL 程式中的資料塊及靜態變數初始化?

解答:S7-SCL 程式中對資料塊及靜態變數初始化和 STL 語言格式類似,下面的程式列出了正確格式:

DAT1 : REAL := 100.5;

A1 : INT := 10 ;

A2 : STRING[6] := 'FACTOR';

A3 : ARRAY[1..12] OF REAL := 0.0, 10(100.0), 1.0;

頂部