PLC的本質(zhì)是個(gè)計(jì)算機(jī)。 和計(jì)算機(jī)的編程語(yǔ)言一樣,在程序中是需要用到各種變量的。
所以先從計(jì)算機(jī)高級(jí)語(yǔ)言說(shuō)起。
不管是VB還是C++,各種編程語(yǔ)言都有一個(gè)比較重要的章節(jié),講變量的存儲(chǔ)類型。
我一開始以為它們是在第一章第一課就講的。 還好先翻了翻書。
第七章
7.8 局部變量和全局變量
7.9 動(dòng)態(tài)存儲(chǔ)變量和靜態(tài)存儲(chǔ)變量
在實(shí)際的高級(jí)語(yǔ)言的編程應(yīng)用中,用的最多的是局部變量和全部變量, 以及極少數(shù)情況下會(huì)用到局部的靜態(tài)變量。 有多極少數(shù)呢?我甚至想不起來(lái)應(yīng)用靜態(tài)變量的標(biāo)準(zhǔn)場(chǎng)景了。
幸虧翻了下書, 書里有例子講到了,如此珍貴, 我抄下來(lái)算了:
#include
int main()
{
int i;
for(i=1;i<=5;++i)
printf("%d!=%d\n",i,fact(i));
return 0;
}
int fact(int n)
{
static int f = 1;
f=f*n;
return (f);
}
這里面的static int f 就是靜態(tài)變量。
其中一個(gè)最大的技巧是, 在函數(shù)計(jì)算5!的時(shí)候, 用到了前面計(jì)算4!的計(jì)算結(jié)果。對(duì)早期的計(jì)算機(jī)計(jì)算資源特別寶貴的情況下, 起到了節(jié)省一點(diǎn)點(diǎn)計(jì)算資源的作用。
但是, 這個(gè)技巧又相當(dāng)扯淡。如果你只想求5!而對(duì)前面的1!,2!,3!,4!皆不感興趣,則這個(gè)函數(shù)反而不能用了。 還逼著你非要在外面做一次循環(huán),重復(fù)調(diào)用那個(gè)函數(shù)fact,才能真正得到5!的答案。
一個(gè)計(jì)算功能, 原生的函數(shù)還不能直接得到答案, 還需要再做一次循環(huán)處理,才可以。 這事兒換誰(shuí)誰(shuí)不煩?。?/p>
嗯, 還真有不煩的。 誰(shuí)不煩?
PLC不煩。
因?yàn)镻LC的OB1是天生自動(dòng)循環(huán)的。
只要計(jì)算結(jié)果不是需要在一個(gè)周期內(nèi)立馬得到答案, 就可以充分使用OB1循環(huán)運(yùn)行的特性, 在函數(shù)中實(shí)現(xiàn)想要的功能。
比如MODBUS輪詢,就可以由OB1的循環(huán)調(diào)用機(jī)制本身來(lái)驅(qū)動(dòng)。 不需要自己做循環(huán)程序(而且也不能做, 如果做的話CPU單個(gè)周期運(yùn)轉(zhuǎn)時(shí)間過(guò)長(zhǎng), 會(huì)累死。)
所以, 以往在高級(jí)語(yǔ)言中,只有概念, 而鮮有用武之地的STATIC靜態(tài)變量在PLC系統(tǒng)中,閃亮登場(chǎng)了, 而且大放異彩。
變量作用域和生存期列表:
備注
* 對(duì)于被嵌套調(diào)用的函數(shù)塊FB/FC/OB來(lái)說(shuō), 各自定義的TEMP變量不繼承,不滲透。
** 地址區(qū)間先分給INPUT和OUTPUT,而后才是STATIC。
*** 所有TEMP變量, 必須先寫入數(shù)值后使用。 不能假設(shè)初始都為0,或者上個(gè)周期運(yùn)行的結(jié)果。
所以,不同的應(yīng)用需求, 需要的變量類型是不一樣的。
比如要計(jì)算OUT=(A+B)/(C+D),
在LAD或者STL 里,通常要用1個(gè)或者2個(gè)臨時(shí)變量。
L #A
L #B
+R
T LD10
L #C
L #D
+R
T LD14
L LD10
L LD14
/R
T #OUT
這里使用的L區(qū),雙字,存儲(chǔ)REAL數(shù)據(jù)。 在STEP7中可以未加定義直接使用。 而在TIA PORTAL中要么提前定義, 要么直接使用名字后補(bǔ)充定義到LOCAL變量。不再允許絕對(duì)尋址。
如果同一個(gè)函數(shù)中, 還有要使用同樣數(shù)據(jù)類型的地方,可以重復(fù)使用。 但都是要先寫入后讀取。
同樣的程序, 使用其它的內(nèi)存地址來(lái)實(shí)現(xiàn)當(dāng)然也可以。 比如可以使用MD10/MD14替代上面的LD10/LD14。 運(yùn)算效果完全相同。 但是,對(duì)資源使用造成了浪費(fèi), 也容易導(dǎo)致變量重復(fù)使用, 會(huì)干擾其他的使用了同地址的函數(shù)塊。
如果見到有人做的這樣的程序,你立馬可以判定: 這是個(gè)新手做的。
MODBUS輪詢問(wèn)題,用SCL語(yǔ)言的部分代碼(用LAD和STL原理相同)
IF "FirstScan" THEN
#cycle := 0;
#step := 1;
#j := -1;
END_IF;
IF #Data.MB_ADDR = 0 THEN
#i := #i + 1;
RETURN;
END_IF;
其中的#cycle ,#step,#i,#j等變量,都是定義的STATIC靜態(tài)變量。具體細(xì)分的話, 個(gè)別變量可能可以使用TEMP臨時(shí)變量, 但圖省事, 也就不那么細(xì)了。 反正最終完全封裝, 不會(huì)影響到外面其它函數(shù)的變量使用。
同樣的道理,這些變量如果使用全局變量M, 能不能同樣實(shí)現(xiàn)目的呢?
答案是:有時(shí)候能,有時(shí)候不能!
看這個(gè)函數(shù)使用的情況。 如果在系統(tǒng)中只調(diào)用1次, 那是可以的。 而如果需要調(diào)用n次, 使用全局變量的話, 反而不可以了!多個(gè)實(shí)例時(shí)間會(huì)亂串, 會(huì)互相干擾。所以如果不幸要多次調(diào)用, 還需要復(fù)制另存,更改其中的M變量,換一批來(lái)!
上面的功能中還使用了定時(shí)器, 只不過(guò)代碼沒有貼出來(lái)。 也是同樣的道理。 只不過(guò)定時(shí)器比較復(fù)雜, 使用的是多重背景的數(shù)據(jù)塊,本質(zhì)也是STATIC變量。
emmmm, 我這是在做什么?
我是在重復(fù)印證我所主張的“好的程序的標(biāo)準(zhǔn)是:不使用M中間量,不使用Timer?!?br />
審核編輯:劉清
-
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7500瀏覽量
88032 -
SCL
+關(guān)注
關(guān)注
1文章
239瀏覽量
17094 -
靜態(tài)變量
+關(guān)注
關(guān)注
0文章
13瀏覽量
6662 -
plc編程語(yǔ)言
+關(guān)注
關(guān)注
0文章
7瀏覽量
1172
原文標(biāo)題:【萬(wàn)泉河】PLC系統(tǒng)變量的作用域和生存期
文章出處:【微信號(hào):PLC標(biāo)準(zhǔn)化編程,微信公眾號(hào):PLC標(biāo)準(zhǔn)化編程】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論