準(zhǔn)詳解:PLC編程語言與工程實(shí)踐)
1. 標(biāo)準(zhǔn)背景為什么做PLC項(xiàng)目必須懂IEC 61131做PLC開發(fā)這行干了幾年你就會(huì)發(fā)現(xiàn)一個(gè)尷尬的事同樣一段邏輯換個(gè)品牌PLC就得重寫一遍。早些年可不是這樣各家控制器廠商都有自己的編程方式互不通用——這種方言林立的狀態(tài)對(duì)整個(gè)工控行業(yè)來說其實(shí)是巨大的隱性成本。后來IEC國(guó)際電工委員會(huì)牽頭搞了個(gè)統(tǒng)一標(biāo)準(zhǔn)也就是今天要聊的IEC 61131目的很直接把PLC編程從手工作坊推向工業(yè)化標(biāo)準(zhǔn)化。我第一次接觸這套標(biāo)準(zhǔn)是在一個(gè)跨平臺(tái)的設(shè)備改造項(xiàng)目里當(dāng)時(shí)我們要把一套老產(chǎn)線的控制邏輯從某品牌的專用環(huán)境遷移到另一家控制器上程序幾乎推倒重來整整折騰了兩個(gè)月。后來技術(shù)負(fù)責(zé)人一句話點(diǎn)醒了我你們?nèi)钡牟皇羌影鄷r(shí)間是對(duì)IEC 61131的理解。從那以后我開始系統(tǒng)地啃這套標(biāo)準(zhǔn)越深入越發(fā)現(xiàn)它不只是規(guī)定了幾種編程語言那么簡(jiǎn)單它其實(shí)是一整套關(guān)于工業(yè)控制軟件怎么組織、怎么寫、怎么維護(hù)的方法論。對(duì)剛?cè)胄械墓こ處焷碚f直接學(xué)IEC 61131可能有點(diǎn)抽象畢竟平時(shí)工作里大家都在用具體的編程環(huán)境和硬件很少會(huì)翻開標(biāo)準(zhǔn)文檔去研究軟件模型任務(wù)調(diào)度這些概念。但我必須負(fù)責(zé)任地說如果你只看編程手冊(cè)而不理解標(biāo)準(zhǔn)本身的架構(gòu)遇到跨平臺(tái)項(xiàng)目、復(fù)雜功能塊復(fù)用、程序性能優(yōu)化這類問題就會(huì)非常吃力。這篇文章我打算從工程實(shí)操的角度把IEC 61131標(biāo)準(zhǔn)的結(jié)構(gòu)、五種編程語言、工程實(shí)現(xiàn)方法、以及我在實(shí)際項(xiàng)目里踩過的坑完整地拆解一遍。不管你現(xiàn)在用的是哪個(gè)品牌的PLC、或者正在考慮從傳統(tǒng)的梯形圖轉(zhuǎn)向結(jié)構(gòu)化文本這套標(biāo)準(zhǔn)背后的思想都值得認(rèn)真搞懂。學(xué)完以后你會(huì)發(fā)現(xiàn)很多原來靠記型號(hào)、記指令解決的經(jīng)驗(yàn)題其實(shí)都有統(tǒng)一的理論答案。2. 標(biāo)準(zhǔn)全貌拆解IEC 61131到底是什么2.1 十大部分組成的完整標(biāo)準(zhǔn)族IEC 61131不是一個(gè)單一的文件它是一整套包含多個(gè)部分的標(biāo)準(zhǔn)族。很多工程師只聽說過其中的第3部分因?yàn)槟鞘侵v編程語言的實(shí)際上整個(gè)標(biāo)準(zhǔn)覆蓋了從硬件到軟件的方方面面。我整理了完整的構(gòu)成部分編號(hào)內(nèi)容說明工程相關(guān)度61131-1通用信息與術(shù)語定義中61131-2設(shè)備要求與測(cè)試條件高61131-3編程語言與軟件模型極高61131-4用戶指導(dǎo)規(guī)范中61131-5通信與服務(wù)規(guī)范高61131-6功能安全相關(guān)說明中61131-7模糊控制編程低61131-8編程語言應(yīng)用指南中61131-9通信數(shù)字接口低61131-10開放式通信低日常項(xiàng)目里接觸最多的是第2、3、5部分。第2部分規(guī)定了PLC硬件設(shè)備的各項(xiàng)技術(shù)指標(biāo)比如抗干擾等級(jí)、工作溫度范圍、絕緣性能選型的時(shí)候參考價(jià)值很高。第3部分是編程的核心我們接下來重點(diǎn)展開。第5部分是PLC之間的通信規(guī)范例如多品牌控制器組網(wǎng)時(shí)就需要對(duì)照這套規(guī)范來處理。2.2 第3部分是整個(gè)標(biāo)準(zhǔn)的心臟第3部分IEC 61131-3定義了完整的軟件模型、編程語言、以及標(biāo)準(zhǔn)化的功能塊。它解決的幾個(gè)核心問題包括程序怎么組織、變量怎么定義、邏輯怎么復(fù)用、不同語言寫的代碼怎么互相調(diào)用。這些問題放在今天看很基礎(chǔ)但在標(biāo)準(zhǔn)出來之前完全是各搞各的。舉個(gè)例子早期某品牌PLC的定時(shí)器指令用法是TIM X001, K50這樣的形式時(shí)間單位是固定的0.1秒想改成秒級(jí)定時(shí)得自己換算。而IEC 61131-3引入的TON定時(shí)器功能塊時(shí)間單位由數(shù)據(jù)類型明確約束端口含義標(biāo)準(zhǔn)化換任何符合標(biāo)準(zhǔn)的平臺(tái)用法幾乎一致。這種細(xì)節(jié)上的統(tǒng)一帶來的是工程師學(xué)習(xí)成本的急劇下降——精通了一個(gè)平臺(tái)再轉(zhuǎn)到另一個(gè)符合標(biāo)準(zhǔn)的平臺(tái)大部分知識(shí)可以直接平移。3. 軟件模型與工程落地方法3.1 配置、資源、任務(wù)、程序這四層關(guān)系IEC 61131-3把控制軟件的組織方式歸納為從大到小的四層配置Configuration→ 資源Resource→ 任務(wù)Task→ 程序Program。這個(gè)分層模型值得認(rèn)真理解因?yàn)閷?shí)際編程環(huán)境里的工程、任務(wù)、程序組織方式基本都是對(duì)它的具體實(shí)現(xiàn)。配置相當(dāng)于整個(gè)控制系統(tǒng)的軟件架構(gòu)對(duì)應(yīng)一個(gè)完整的控制器系統(tǒng)可以被視為一個(gè)獨(dú)立的PLC節(jié)點(diǎn)。資源可以理解為控制器里的運(yùn)行容器一個(gè)配置里可以有多個(gè)資源對(duì)應(yīng)多核CPU的不同核心或者不同的執(zhí)行單元。任務(wù)資源的調(diào)度單位控制哪些程序在什么時(shí)間執(zhí)行、以什么周期執(zhí)行。程序?qū)嶋H的邏輯代碼容器里面可以調(diào)用功能塊、函數(shù)、訪問全局變量。我在實(shí)際項(xiàng)目中很喜歡用這四層關(guān)系來反推程序結(jié)構(gòu)設(shè)計(jì)。比如在多工位設(shè)備上每個(gè)工位的控制邏輯獨(dú)立成程序通過任務(wù)調(diào)度分配不同的執(zhí)行周期——快速響應(yīng)的安全邏輯用短的掃描周期慢速的溫度控制在主循環(huán)里定期執(zhí)行。這種設(shè)計(jì)思路直接來自標(biāo)準(zhǔn)的軟件模型理念比把所有邏輯塞進(jìn)一個(gè)程序塊要清晰得多。對(duì)于當(dāng)?shù)刭Y源與任務(wù)的配置尤其需要留意任務(wù)與掃描周期的關(guān)聯(lián)一個(gè)資源下的任務(wù)決定程序是按周期循環(huán)執(zhí)行還是按事件觸發(fā)。在實(shí)際工程項(xiàng)目中事件觸發(fā)任務(wù)通常對(duì)應(yīng)通信中斷、硬件中斷這類場(chǎng)景周期任務(wù)則對(duì)應(yīng)常規(guī)循環(huán)掃描。3.2 程序組織單元POU的三種角色程序、功能塊、函數(shù)這三個(gè)概念在標(biāo)準(zhǔn)里統(tǒng)稱為POUProgram Organization Unit是編寫的邏輯載體程序程序的執(zhí)行入口可以訪問全局變量可以調(diào)用功能塊和函數(shù)。程序代表一套完整邏輯通常是和設(shè)備的一個(gè)工作模式或一個(gè)工位對(duì)應(yīng)。功能塊帶內(nèi)部狀態(tài)的邏輯單元有Instance實(shí)例的概念。同一個(gè)功能塊能產(chǎn)生多個(gè)實(shí)例彼此獨(dú)立。典型代表就是定時(shí)器、計(jì)數(shù)器。函數(shù)沒有內(nèi)部狀態(tài)的邏輯單元輸入相同則輸出必定相同類似數(shù)學(xué)函數(shù)。典型代表是算術(shù)運(yùn)算、類型轉(zhuǎn)換。一個(gè)常見的誤區(qū)是把函數(shù)當(dāng)功能塊用或者在功能塊里大量讀寫全局變量。標(biāo)準(zhǔn)的設(shè)計(jì)意圖很清晰函數(shù)應(yīng)該是純粹的計(jì)算功能塊才適合處理帶狀態(tài)的控制邏輯。我在評(píng)審新人代碼時(shí)如果看到哪段邏輯在函數(shù)里依賴某個(gè)全局狀態(tài)基本上一抓一個(gè)準(zhǔn)那就是需要改成功能塊的信號(hào)。3.3 變量范圍與I/O映射的工程實(shí)踐IEC 61131-3定義了不同作用域的變量全局變量、局部變量、直接變量等。工程上我們還會(huì)給變量做明確的命名規(guī)范和I/O映射表。這塊多花點(diǎn)功夫后面的調(diào)試能省一半的時(shí)間。我常用的命名習(xí)慣是前綴加匈牙利命名法bStart布爾量用于啟動(dòng)信號(hào)iSpeed整數(shù)用于速度值rTemp實(shí)數(shù)用于溫度值xRun布爾狀態(tài)量設(shè)備運(yùn)行狀態(tài)tTimeout時(shí)間值超時(shí)設(shè)置I/O映射的原則是程序內(nèi)部盡量不直接訪問物理地址而是通過映射的符號(hào)變量來操作。這樣做的直接好處是當(dāng)設(shè)備硬件地址調(diào)整時(shí)只需要改映射關(guān)系不用動(dòng)控制邏輯代碼。另一個(gè)深層的價(jià)值是可測(cè)試性——邏輯和硬件解耦后你可以在沒有真實(shí)硬件的情況下做邏輯仿真這在整套系統(tǒng)調(diào)試之前就能提前驗(yàn)證大部分控制邏輯的正確性對(duì)項(xiàng)目進(jìn)度管控非常有利。4. 五種編程語言全面對(duì)比4.1 圖形化語言與傳統(tǒng)文本語言的定位差異IEC 61131-3定義了兩大類型共五種編程語言。圖形化語言包括梯形圖LD、功能塊圖FBD、順序功能圖SFC文本語言包括指令表IL和結(jié)構(gòu)化文本ST。實(shí)際項(xiàng)目中許多主流編程環(huán)境都支持混合編程。先說結(jié)論這五種語言沒有絕對(duì)的優(yōu)劣之分適用的場(chǎng)景完全不同。很多初學(xué)者上來就問學(xué)哪種語言最好其實(shí)這個(gè)問題的前提就不對(duì)。應(yīng)該問的是我這套控制邏輯的特征是什么用哪種語言表達(dá)最合適。4.2 梯形圖LD——電氣工程師的母語梯形圖源自電氣控制原理圖保留了觸點(diǎn)和線圈的概念。它的核心特征是直觀電工出身的人看圖就能理解邏輯。在傳統(tǒng)繼電器電路改造項(xiàng)目里梯形圖的表達(dá)方式與現(xiàn)實(shí)電路幾乎一一對(duì)應(yīng)所以它在工廠電氣維修、老舊設(shè)備改造的領(lǐng)域里地位不可撼動(dòng)。在實(shí)際項(xiàng)目中梯形圖最適合表達(dá)組合邏輯和聯(lián)鎖保護(hù)邏輯。比如設(shè)備的安全互鎖、按鈕啟停控制、急?;芈泛蜖顟B(tài)指示邏輯用梯形圖表示出來車間電氣維修人員不需要經(jīng)過專門的軟件培訓(xùn)也能看明白大概邏輯走向。這在實(shí)際設(shè)備維護(hù)中非常寶貴因?yàn)楹芏喱F(xiàn)場(chǎng)問題靠電氣人員快速排查比靠工程師打開電腦看程序快得多。不過梯形圖也有明顯的短板處理復(fù)雜數(shù)學(xué)運(yùn)算、數(shù)據(jù)管理、數(shù)組操作時(shí)非常啰嗦。你寫一個(gè)PID參數(shù)整定的計(jì)算過程用梯形圖可能要寫十幾行網(wǎng)絡(luò)而用ST只需要一個(gè)函數(shù)調(diào)用。所以現(xiàn)代主流編程環(huán)境里優(yōu)化做法是聯(lián)鎖保護(hù)用梯形圖復(fù)雜計(jì)算用ST兩者通過功能塊或者程序段互相調(diào)用。4.3 功能塊圖FBD——信號(hào)流思維的最佳載體功能塊圖是用圖形化的塊表示函數(shù)和功能塊再用連線表示數(shù)據(jù)流和控制流本質(zhì)上是把電子電路圖思維方式搬到控制邏輯里。它非常適合表達(dá)模擬量處理和閉環(huán)控制回路。我在做溫度控制項(xiàng)目時(shí)配置PID功能塊的參數(shù)、給定值、反饋值、輸出限幅這些信息用FBD表達(dá)時(shí)一眼就能看清整個(gè)控制回路的信號(hào)走向。相比梯形圖FBD在處理連續(xù)控制、信號(hào)處理場(chǎng)景下更加自然。FBD另一個(gè)優(yōu)勢(shì)是跨領(lǐng)域的可讀性。工藝工程師比如化工、水處理行業(yè)往往對(duì)純軟件不太熟悉但看圖的能力很強(qiáng)FBD圖示化的特點(diǎn)很好地照顧到了這類協(xié)作場(chǎng)景便于多方對(duì)控制方案的討論與確認(rèn)。4.4 結(jié)構(gòu)化文本ST——復(fù)雜邏輯的利器結(jié)構(gòu)化文本是一種高級(jí)編程語言語法上與Pascal接近。它有循環(huán)、條件分支、數(shù)組、結(jié)構(gòu)體能實(shí)現(xiàn)非常復(fù)雜的控制算法。這是我最推薦有計(jì)算機(jī)基礎(chǔ)的工程師深入學(xué)習(xí)的一種語言。ST的核心優(yōu)勢(shì)有幾點(diǎn)數(shù)學(xué)表達(dá)接近自然語言可讀性高支持局部變量、復(fù)雜數(shù)據(jù)類型適合實(shí)現(xiàn)狀態(tài)機(jī)、數(shù)據(jù)處理算法、通信協(xié)議解析我是強(qiáng)烈建議工程師掌握ST的即使你的日常工作以梯形圖為主。因?yàn)楫?dāng)設(shè)備規(guī)模上去之后程序的復(fù)雜度會(huì)從邏輯復(fù)雜轉(zhuǎn)變到數(shù)據(jù)復(fù)雜。數(shù)據(jù)采集、統(tǒng)計(jì)分析、配方管理、追溯信息傳遞——這些靠梯形圖會(huì)寫到懷疑人生而ST把代碼行數(shù)壓縮到原來的十分之一維護(hù)體驗(yàn)天差地別。舉一個(gè)常見的例子批量設(shè)備中配方管理功能需要根據(jù)不同的產(chǎn)品型號(hào)切換上百個(gè)工藝參數(shù)。用梯形圖寫這個(gè)邏輯需要做一大串比較和傳送指令調(diào)試時(shí)看程序像看天書用ST只需要幾個(gè)CASE語句和一個(gè)配方結(jié)構(gòu)體數(shù)組就可以組織得很清晰。4.5 順序功能圖SFC——流程型邏輯的天然表達(dá)SFC是對(duì)順序控制流程的圖形化描述它來源于工業(yè)界的Petri網(wǎng)思想把整個(gè)控制過程劃分為多個(gè)步Step步與步之間的跳轉(zhuǎn)條件Transition用普通的邏輯表達(dá)式描述。SFC非常適合表達(dá)工序流程、工步動(dòng)作、節(jié)拍控制一類的邏輯。我用SFC寫過一套自動(dòng)化裝配線的控制程序整個(gè)流程分成上料、定位、裝配、檢測(cè)、下料五個(gè)主步每個(gè)步內(nèi)部再調(diào)用不同的功能塊來執(zhí)行具體動(dòng)作。相比用梯形圖實(shí)現(xiàn)一樣的流程SFC程序讓整個(gè)流程結(jié)構(gòu)一目了然當(dāng)前設(shè)備走到哪一步、下一步是什么條件觸發(fā)、卡在哪個(gè)環(huán)節(jié)打開程序就能看到。但SFC需要特別注意同時(shí)激活多個(gè)步的情況處理不好會(huì)出現(xiàn)資源競(jìng)爭(zhēng)問題。比如兩個(gè)步同時(shí)執(zhí)行時(shí)都可能對(duì)同一個(gè)輸出變量做寫操作這種情況必須通過編程規(guī)范約束避免。4.6 指令表IL——從歷史而來往平臺(tái)而去指令表是類似匯編語言的PLC編程形式在早期的PLC編程中廣泛應(yīng)用基本每條指令對(duì)應(yīng)一個(gè)操作。它在IEC 61131-3中被保留下來但實(shí)際新項(xiàng)目中使用得越來越少。對(duì)普通工程師來說指令表主要用于三個(gè)場(chǎng)景一是閱讀別人老設(shè)備上的舊程序很多老設(shè)備還是用IL寫的維護(hù)資料二是某些特殊品牌的專用環(huán)境仍然提供IL支持三是在調(diào)試器里查看編譯后的執(zhí)行指令來排查異常行為。日常新項(xiàng)目開發(fā)一般不建議把IL作為主力的編程語言。特性梯形圖功能塊圖結(jié)構(gòu)化文本順序功能圖指令表邏輯表達(dá)觸點(diǎn)線圈數(shù)據(jù)流文本語句步進(jìn)流程助記指令最佳場(chǎng)景聯(lián)鎖保護(hù)模擬控制復(fù)雜運(yùn)算工序流程歷史維護(hù)學(xué)習(xí)難度低中中高中高代碼復(fù)用性中高高中低調(diào)試體驗(yàn)直觀直觀較抽象直觀較抽象5. 工程設(shè)計(jì)與編程實(shí)現(xiàn)全流程5.1 從需求分析到變量規(guī)劃一個(gè)標(biāo)準(zhǔn)的PLC項(xiàng)目前期規(guī)劃比寫代碼更重要。拿到現(xiàn)場(chǎng)需求之后第一步不是打開編程軟件拖梯形圖而是先把需求拆解清楚。我習(xí)慣用的順序是列出全部輸入信號(hào)包含數(shù)字量、模擬量、通信量明確數(shù)量與數(shù)據(jù)類型列出全部輸出信號(hào)明確執(zhí)行器的類型與驅(qū)動(dòng)能力需求確定控制模式手動(dòng)、自動(dòng)、半自動(dòng)各模式之間的切換關(guān)系劃分功能邊界哪些邏輯屬于安全聯(lián)鎖、哪些屬于工藝控制、哪些屬于數(shù)據(jù)管理建立I/O映射表物理地址與符號(hào)變量一一對(duì)應(yīng)規(guī)劃數(shù)據(jù)結(jié)構(gòu)根據(jù)工藝需求設(shè)計(jì)結(jié)構(gòu)體、數(shù)組、配方變量這套順序走完之后寫代碼就成了一件翻譯的事情。如果跳過前面的步驟直接擼起袖子寫邏輯越寫到后面越混亂返工風(fēng)險(xiǎn)極高。5.2 用ST實(shí)現(xiàn)一個(gè)電機(jī)控制功能塊光說理論沒意思我們來做一個(gè)具體的例子。假設(shè)要寫一個(gè)電機(jī)控制功能塊要求是啟動(dòng)按鈕觸發(fā)后先輸出啟動(dòng)命令、等待電機(jī)運(yùn)行反饋信號(hào)、反饋超時(shí)則報(bào)警并停止。這個(gè)需求在設(shè)備控制里非常典型涉及啟停邏輯、反饋監(jiān)視、超時(shí)處理、故障復(fù)位。用ST寫這個(gè)功能塊代碼如下FUNCTION_BLOCK FB_MotorControl VAR_INPUT bStartCmd : BOOL; // 啟動(dòng)命令 bStopCmd : BOOL; // 停止命令 bRunFb : BOOL; // 運(yùn)行反饋 bFaultReset : BOOL; // 故障復(fù)位 tFeedbackTimeout : TIME : T#2S; // 反饋超時(shí)時(shí)間 END_VAR VAR_OUTPUT xRunCmd : BOOL; // 運(yùn)行輸出 xFault : BOOL; // 故障指示 eState : INT; // 狀態(tài)值0停止 1啟動(dòng)中 2運(yùn)行 3故障 END_VAR VAR tonFeedback : TON; // 反饋超時(shí)定時(shí)器 stRun : BOOL; // 內(nèi)部狀態(tài)運(yùn)行中 END_VAR // 狀態(tài)切換故障復(fù)位 IF xFault AND bFaultReset THEN xFault : FALSE; stRun : FALSE; END_IF // 啟動(dòng)條件滿足 IF bStartCmd AND NOT bStopCmd AND NOT xFault THEN stRun : TRUE; END_IF // 停止條件 IF bStopCmd AND NOT bStartCmd THEN stRun : FALSE; END_IF // 輸出控制 xRunCmd : stRun; // 反饋監(jiān)視 IF stRun THEN tonFeedback(IN : NOT bRunFb, PT : tFeedbackTimeout); IF bRunFb THEN eState : 2; ELSIF tonFeedback.Q THEN xFault : TRUE; stRun : FALSE; eState : 3; ELSE eState : 1; END_IF ELSE tonFeedback(IN : FALSE, PT : tFeedbackTimeout); eState : 0; END_IF // 故障鎖存輸出 IF xFault THEN eState : 3; END_IF這段代碼在結(jié)構(gòu)上體現(xiàn)了幾個(gè)工程配置的關(guān)鍵點(diǎn)功能塊封裝了完整的狀態(tài)邏輯外部程序只需要調(diào)用它并連接輸入輸出反饋超時(shí)的時(shí)長(zhǎng)參數(shù)是外部傳入的VAR_INPUT這樣不同應(yīng)用場(chǎng)景可以靈活配置不需要復(fù)制多份功能塊代碼使用了TON功能塊的Q輸出和定時(shí)器IN由運(yùn)行信號(hào)驅(qū)動(dòng)來實(shí)現(xiàn)超時(shí)邏輯狀態(tài)變量eState方便上位機(jī)監(jiān)視模塊當(dāng)前的運(yùn)行狀態(tài)實(shí)際調(diào)用時(shí)只需要在主程序或者另一個(gè)功能塊里聲明一個(gè)實(shí)例然后執(zhí)行VAR motor1 : FB_MotorControl; END_VAR motor1(bStartCmd : bStartButton, bStopCmd : bStopButton, bRunFb : xRunFeedback, bFaultReset : bResetButton, tFeedbackTimeout : T#3S, xRunCmd xMotorOutput, xFault xMotorFault);調(diào)用處的變量連接一目了然真正做到了邏輯的模塊化復(fù)用。5.3 任務(wù)調(diào)度與掃描周期的工程考量PLC的循環(huán)掃描機(jī)制決定了程序并不是實(shí)時(shí)執(zhí)行所有邏輯而是按一個(gè)固定的周期不斷重復(fù)掃描。這個(gè)周期的長(zhǎng)短直接決定控制系統(tǒng)的響應(yīng)速度。常規(guī)PLC的掃描周期大致在幾毫秒到幾十毫秒之間取決于程序大小、指令復(fù)雜度和硬件性能。在IEC 61131的軟件模型里任務(wù)Task就是用來控制POU執(zhí)行方式和周期的機(jī)制。工程上我用過三種任務(wù)配置模式周期任務(wù)以固定時(shí)間間隔執(zhí)行指定程序比如每10ms執(zhí)行一次快速邏輯每100ms執(zhí)行一次常規(guī)邏輯事件任務(wù)由特定事件觸發(fā)執(zhí)行比如通信請(qǐng)求到達(dá)時(shí)執(zhí)行對(duì)應(yīng)的數(shù)據(jù)解析程序自由運(yùn)行任務(wù)按控制器自身的空閑循環(huán)不斷執(zhí)行適用于非實(shí)時(shí)性要求不高的邏輯在項(xiàng)目實(shí)踐中如果將不同類型的邏輯放入依據(jù)其響應(yīng)速度需求配置的不同任務(wù)中系統(tǒng)實(shí)時(shí)性能會(huì)明顯優(yōu)于把全部邏輯放在同一個(gè)自由運(yùn)行循環(huán)里。比如伺服控制器的使能和急停響應(yīng)必須放在最快的周期任務(wù)里而溫度采集、統(tǒng)計(jì)報(bào)表邏輯完全可以用慢周期完全沒有必要一刀切地讓所有邏輯都以相同的周期掃描。5.4 工程文件組織的實(shí)用結(jié)構(gòu)除了代碼本身工程文件的組織方式也直接決定項(xiàng)目的可維護(hù)性。我見過很多項(xiàng)目持續(xù)開發(fā)半年之后功能和代碼糾纏在一起找人交接的時(shí)候一片混亂。我習(xí)慣的工程結(jié)構(gòu)是按層次組織項(xiàng)目名/ ├── 全局變量/ │ ├── 輸入映射表 │ ├── 輸出映射表 │ └── 全局常量 ├── 設(shè)備控制/ │ ├── 電機(jī)控制功能塊 │ ├── 氣缸控制功能塊 │ ├── 閥門控制功能塊 │ └── 驅(qū)動(dòng)控制功能塊 ├── 工藝邏輯/ │ ├── 主工藝程序 │ ├── 手動(dòng)模式程序 │ └── 報(bào)警處理程序 ├── 通信處理/ │ ├── 上位機(jī)通信程序 │ └── 設(shè)備間通信程序 └── 數(shù)據(jù)處理/ ├── 配方管理功能塊 └── 數(shù)據(jù)記錄功能塊這樣分類的好處是改電機(jī)控制邏輯不會(huì)牽扯到工藝邏輯排查通信問題不需要在控制程序里翻找。模塊之間通過功能塊接口互動(dòng)盡量減少對(duì)全局變量的直接修改這么做既是標(biāo)準(zhǔn)的思想也是大型項(xiàng)目的硬性要求。6. 常見問題與調(diào)試經(jīng)驗(yàn)6.1 變量類型不匹配的隱蔽陷阱IEC 61131-3提供了嚴(yán)格的數(shù)據(jù)類型系統(tǒng)BOOL、INT、REAL、TIME等。但在實(shí)際編程環(huán)境中類型不匹配的問題非常常見。比如梯形圖里習(xí)慣用INT做模擬量處理換成ST后遇到REAL數(shù)據(jù)兩者直接運(yùn)算就會(huì)出問題。我在一個(gè)溫度采集項(xiàng)目中遇到過一個(gè)有意思的Bug上位機(jī)顯示的溫度值在特定區(qū)間內(nèi)會(huì)跳變幾個(gè)數(shù)字。排查到最后原因就是數(shù)據(jù)類型轉(zhuǎn)換。模擬量輸入模塊返回的是INT型數(shù)據(jù)程序里為了濾波計(jì)算直接做了整數(shù)除法結(jié)果小數(shù)部分被截?cái)鄬?dǎo)致計(jì)算誤差被累積。解決方式很簡(jiǎn)單先轉(zhuǎn)換為REAL再做浮點(diǎn)運(yùn)算最后輸出前再轉(zhuǎn)回需要的類型。但這種問題隱蔽性很強(qiáng)容易出現(xiàn)在邏輯代碼本身沒有報(bào)錯(cuò)、但計(jì)算結(jié)果精度不滿足要求的場(chǎng)景。工程上建議養(yǎng)成好習(xí)慣程序里明確區(qū)分?jǐn)?shù)據(jù)類型不寫隱式轉(zhuǎn)換依賴編譯器兜底的代碼。6.2 定時(shí)器使用的經(jīng)典失誤TON定時(shí)器在IEC 61131-3里的行為是當(dāng)IN為TRUE時(shí)開始計(jì)時(shí)輸出Q在時(shí)間到達(dá)后為TRUE??此坪?jiǎn)單但實(shí)際項(xiàng)目中翻車案例不在少數(shù)。最常見的失誤是定時(shí)器復(fù)位條件不正確。此前有人在寫設(shè)備節(jié)拍控制邏輯時(shí)用一個(gè)總體時(shí)間作為節(jié)拍超時(shí)保護(hù)。但實(shí)際上控制節(jié)拍的邏輯在多個(gè)程序段里往復(fù)切換定時(shí)器的IN信號(hào)并不是連續(xù)的TRUE導(dǎo)致定時(shí)器不斷被復(fù)位重新計(jì)時(shí)超時(shí)保護(hù)形同虛設(shè)——這其實(shí)說明他沒有真正理解TON的時(shí)序行為。正確的做法是明確超時(shí)監(jiān)視的時(shí)間段是一個(gè)連續(xù)的狀態(tài)區(qū)間且定時(shí)器的IN信號(hào)必須嚴(yán)格對(duì)應(yīng)這個(gè)狀態(tài)區(qū)間。比如電機(jī)啟動(dòng)監(jiān)視IN就等于啟動(dòng)命令已發(fā)出直到收到反饋才復(fù)位。定時(shí)器使用之前必須先畫出時(shí)序圖搞清楚IN、Q、ET三個(gè)信號(hào)在整個(gè)過程中的行為曲線把時(shí)序想清楚再寫代碼能避開絕大多數(shù)低級(jí)錯(cuò)誤。6.3 通信數(shù)據(jù)解析的字節(jié)序難題PLC與智能儀表、驅(qū)動(dòng)器、視覺系統(tǒng)通信時(shí)數(shù)據(jù)處理是一個(gè)頻率很高的坑。PLC內(nèi)存儲(chǔ)的多字節(jié)變量比如INT是16位DINT是32位在內(nèi)存里的排列方式稱為字節(jié)序不同品牌甚至同一品牌不同系列之間都可能不一致。如果程序里按錯(cuò)誤的字節(jié)序解析收到的數(shù)據(jù)輕則數(shù)值亂跳重則整個(gè)通信數(shù)據(jù)都不可用。字節(jié)序是指多字節(jié)數(shù)據(jù)在內(nèi)存中存放的順序分為大端序和小端序兩種。大端序是高位字節(jié)在前小端序是低位字節(jié)在前。不同的設(shè)備可能采用不同的字節(jié)序解析時(shí)必須搞清對(duì)端設(shè)備的字節(jié)序約定。實(shí)際處理中我一般會(huì)在通信程序的初始化段建立一個(gè)字節(jié)序統(tǒng)一處理的代碼塊收上來的原始數(shù)據(jù)先經(jīng)過統(tǒng)一的字節(jié)序轉(zhuǎn)換函數(shù)再進(jìn)入業(yè)務(wù)邏輯。這樣即使外部設(shè)備更換型號(hào)、字節(jié)序改變只需要調(diào)整這一個(gè)函數(shù)而不會(huì)在業(yè)務(wù)代碼的各個(gè)角落里找問題。字節(jié)序轉(zhuǎn)換函數(shù)的一個(gè)典型實(shí)現(xiàn)思路是利用移位操作重組字節(jié)// 交換16位整數(shù)的高低位字節(jié) FUNCTION SwapBytes16 : INT VAR_INPUT value : INT; END_VAR VAR temp : DINT; END_VAR temp : value; SwapBytes16 : SHL(temp AND 16#FF, 8) OR SHR((temp AND 16#FF00), 8);如果上層業(yè)務(wù)收到的DINT還是一個(gè)組合的結(jié)果還需要在這個(gè)基礎(chǔ)上再疊加字節(jié)序轉(zhuǎn)換邏輯。在編寫這類函數(shù)時(shí)建議配合一組已知特征的測(cè)試數(shù)據(jù)用斷言方式驗(yàn)證轉(zhuǎn)換結(jié)果確保在任何字節(jié)序組合下都能得到正確值。6.4 在線調(diào)試的技巧與經(jīng)驗(yàn)最后談?wù)務(wù){(diào)試方法?,F(xiàn)在主流編程環(huán)境都支持在線監(jiān)視可以實(shí)時(shí)觀察變量的當(dāng)前值、強(qiáng)制修改變量值、查看程序執(zhí)行狀態(tài)。調(diào)試技巧方面我總結(jié)幾點(diǎn)變量監(jiān)視分組要趁早設(shè)置項(xiàng)目剛開始就按信號(hào)類型建好監(jiān)視表比調(diào)試時(shí)一個(gè)個(gè)找變量快得多斷點(diǎn)功能慎用。PLC程序是循環(huán)掃描的在掃描周期里打斷點(diǎn)會(huì)影響控制實(shí)時(shí)性條件允許時(shí)優(yōu)先用程序插入狀態(tài)記錄變量的方式來觀察中間過程強(qiáng)制輸出來定位硬件問題時(shí)好用到離譜但要時(shí)刻記得解除強(qiáng)制值否則總有一天你會(huì)被明明程序改了為什么現(xiàn)場(chǎng)沒動(dòng)作這種問題折磨到崩潰引入過程狀態(tài)記錄變量類似云臺(tái)的步號(hào)變量把程序運(yùn)行的實(shí)時(shí)狀態(tài)記錄下來這樣排查堵在哪一步時(shí)無需重新構(gòu)造現(xiàn)場(chǎng)條件首次上電調(diào)試前務(wù)必備份好初版程序并保留一個(gè)DIFF對(duì)比基線7. 選型參考與標(biāo)準(zhǔn)演進(jìn)方向7.1 符合IEC 61131標(biāo)準(zhǔn)的平臺(tái)怎么選很多人在項(xiàng)目選型時(shí)只盯著CPU性能和I/O點(diǎn)數(shù)對(duì)編程環(huán)境是否符合IEC 61131標(biāo)準(zhǔn)關(guān)注不足。但實(shí)際上編程環(huán)境直接影響后期開發(fā)效率和程序的可維護(hù)性。選型時(shí)建議關(guān)注下列幾點(diǎn)編程環(huán)境支持哪幾種IEC語言是否五選齊全還是只支持梯形圖和ST變量的管理方式是不是支持結(jié)構(gòu)化變量、數(shù)組、結(jié)構(gòu)體、枚舉類型功能塊的封裝與庫(kù)管理能力能不能把自己寫的功能塊打包成庫(kù)文件直接復(fù)用任務(wù)調(diào)度能力能不能配置周期任務(wù)、事件任務(wù)仿真調(diào)試能力有沒有配合的離線仿真環(huán)境軟件支持度從高到低的典型排序是專用軟件開發(fā)環(huán)境傳統(tǒng)廠家各具特色而現(xiàn)在的很多新型軟PLC與PC-Based控制器在滿足IEC 61131-3方面做得更全面。項(xiàng)目上如果遇到多品牌混合組網(wǎng)的情況IEC 61131兼容性高的一方在系統(tǒng)聯(lián)調(diào)時(shí)會(huì)省心很多。7.2 傳統(tǒng)PLC與軟PLC在標(biāo)準(zhǔn)一致性上的差異這里專門提一下軟PLC。軟PLCSoft PLC的本質(zhì)是在標(biāo)準(zhǔn)工控機(jī)或者嵌入式PC上通過軟件方式實(shí)現(xiàn)PLC的控制功能編程模型遵循IEC 61131標(biāo)準(zhǔn)。相比傳統(tǒng)硬PLC軟PLC有幾個(gè)優(yōu)勢(shì)硬件成本低、性能擴(kuò)展性好、通信接口豐富、與IT系統(tǒng)的融合更方便。但軟PLC也不是萬能的。它的實(shí)時(shí)性受操作系統(tǒng)影響較大如果沒有實(shí)時(shí)擴(kuò)展內(nèi)核很難保證硬實(shí)時(shí)控制。另外軟PLC在惡劣工業(yè)環(huán)境下的可靠性不如傳統(tǒng)硬PLC需要額外的硬件防護(hù)設(shè)計(jì)。選傳統(tǒng)PLC還是軟PLC核心看應(yīng)用場(chǎng)景的運(yùn)動(dòng)控制實(shí)時(shí)性要求與系統(tǒng)整體架構(gòu)。如果項(xiàng)目里有高速運(yùn)動(dòng)控制或同步控制需求傳統(tǒng)硬PLC或帶實(shí)時(shí)擴(kuò)展的軟PLC是必然選擇如果項(xiàng)目更偏向數(shù)據(jù)采集、MES系統(tǒng)對(duì)接、視覺聯(lián)動(dòng)這類偏I(xiàn)T的集成場(chǎng)景軟PLC的靈活性和通信資源反而是加分項(xiàng)。7.3 IEC 61131在自動(dòng)化領(lǐng)域的拓展影響標(biāo)準(zhǔn)本身也在持續(xù)演進(jìn)而且它的影響力已經(jīng)超出了PLC本身?,F(xiàn)在很多運(yùn)動(dòng)控制器、機(jī)器人控制器、CNC系統(tǒng)都在參考IEC 61131的軟件模型和編程框架來設(shè)計(jì)自己的開發(fā)平臺(tái)。值得關(guān)注的是PLCopen組織在IEC 61131基礎(chǔ)上擴(kuò)展了運(yùn)動(dòng)控制規(guī)范把單軸運(yùn)動(dòng)、多軸協(xié)調(diào)、電子凸輪、CNC控制等功能塊做了標(biāo)準(zhǔn)化定義。也就是說你熟悉IEC 61131的POU概念和功能塊調(diào)用方式之后再學(xué)運(yùn)動(dòng)控制編程時(shí)上手成本會(huì)大大降低——因?yàn)榛A(chǔ)概念完全同源區(qū)別只是換了具體的功能塊庫(kù)。從長(zhǎng)遠(yuǎn)看工業(yè)自動(dòng)化控制軟件的陣營(yíng)正在逐漸收斂到IEC 61131這個(gè)大的框架下。不管是哪個(gè)品牌開放標(biāo)準(zhǔn)都是趨勢(shì)作為工程師把標(biāo)準(zhǔn)本身學(xué)扎實(shí)而不是只背某一家的手冊(cè)才是長(zhǎng)久之計(jì)。8. 經(jīng)驗(yàn)沉淀與進(jìn)階路徑這行做久了有幾句體己話想跟同行分享。我見過太多剛?cè)胄械耐乱活^扎進(jìn)梯形圖里用點(diǎn)火式的辦法開發(fā)項(xiàng)目——先拖幾個(gè)觸點(diǎn)調(diào)試時(shí)發(fā)現(xiàn)問題再改全憑感覺毫無章法。這樣也不是不能把項(xiàng)目做完但做完的和標(biāo)準(zhǔn)化的開發(fā)方式寫出來的差了幾年功夫。我自己的體會(huì)是IEC 61131標(biāo)準(zhǔn)里最值錢的思想不是那五種語言而是它背后的軟件工程化思想。程序組織方式、功能塊封裝、變量作用域控制、任務(wù)調(diào)度——這些概念在軟件工程領(lǐng)域已經(jīng)被驗(yàn)證了幾十年只是被嫁接到了工業(yè)控制領(lǐng)域。如果你想把這套體系學(xué)扎實(shí)給幾條具體的行動(dòng)建議先把五種語言都試一遍哪怕工作里只用梯形圖。試過才知道什么邏輯適合用什么語言表達(dá)嘗試把一個(gè)常用的控制邏輯比如電機(jī)控制、閥門控制用功能塊方式封裝好然后在不同的項(xiàng)目里復(fù)用它。對(duì)復(fù)用的理解和使用是區(qū)分普通工程師和資深工程師的一個(gè)重要分水嶺把時(shí)序圖、狀態(tài)圖作為編程前的必要步驟。控制邏輯的核心不是寫代碼而是想清楚狀態(tài)的遷移畫好圖再寫代碼效率翻倍配合一個(gè)支持離線仿真或在線聯(lián)調(diào)的IEC開發(fā)環(huán)境一邊操作一邊對(duì)照標(biāo)準(zhǔn)理解比自己純讀標(biāo)準(zhǔn)文檔要高效得多關(guān)于進(jìn)階路徑我做個(gè)小結(jié)入門階段把梯形圖和FBD用熟能完成基本的設(shè)備邏輯控制提高階段掌握ST和功能塊封裝開始關(guān)注程序復(fù)用和數(shù)據(jù)管理進(jìn)階段要完全吃透軟件模型、任務(wù)調(diào)度和通信規(guī)范有能力獨(dú)立設(shè)計(jì)一套可維護(hù)性強(qiáng)的控制軟件架構(gòu)。到了高級(jí)階段無論是跨平臺(tái)遷移還是新系統(tǒng)架構(gòu)你就真正有話語權(quán)了。最后分享一個(gè)小技巧如果你要驗(yàn)證自己對(duì)IEC 61131標(biāo)準(zhǔn)下的定時(shí)器、計(jì)數(shù)器等標(biāo)準(zhǔn)功能塊的理解是否準(zhǔn)確可以用一個(gè)帶離線仿真的開發(fā)環(huán)境故意寫錯(cuò)時(shí)序連接模擬運(yùn)行看波形結(jié)果。我當(dāng)年就是這么干著干著把觸發(fā)器和復(fù)位邏輯徹底弄通的。做工業(yè)控制靠記憶硬背指令永遠(yuǎn)拼不過建立起的工程方法論——方法論是看家本領(lǐng)指令表只是外衣而已。