Trong bài viết PLC & chuẩn IEC 61131-3, bạn đọc đã được giới thiệu một cái nhìn tương đối tổng quan về chuẩn IEC 61131-3. Bài viết này sẽ giới thiệu chi tiết hơn về các thành phần cơ bản trong mô hình lập trình được quy định trong chuẩn.
TS. Hoàng Minh Sơn - Nghiêm Xuân Trường
Các thành phần này được coi là những yếu tố cơ bản nhất cấu thành nên chương trình điều khiển trong một PLC và chúng hầu như không phụ thuộc vào một ngôn ngữ lập trình cụ thể. Hơn nữa, để có thể lập trình hiệu quả cho PLC theo chuẩn IEC 61131-3, dù bằng ngôn ngữ lập trình nào, thì những hiểu biết về các thành phần này là không thể thiếu. Trong bài viết này, để tiện diễn tả các khái niệm, ngôn ngữ lập trình ST được sử dụng cho các ví dụ minh họa. Mặc dù ngôn ngữ lập trình này chưa được giới thiệu song điều này sẽ không gây khó khăn cho người đọc bởi đây là một ngôn ngữ lập trình có cấu trúc mang nhiều nét giống với ngôn ngữ lập trình Pascal vốn đã quen thuộc với mọi người.
Trước khi bắt đầu vào nội dung của bài viết cũng cần nhắc lại một số ý chính về chuẩn IEC 61131-3 đã giới thiệu trong phần trước. IEC 61131 là một bộ tiêu chuẩn về bộ điều khiển khả trình (PLC) và các thiết bị ngoại vi đi kèm, trong đó phần 3 (tức IEC 61131-3, từ nay sẽ gọi tắt là chuẩn) quy định về các ngôn ngữ lập trình của PLC cũng như cách thức lập trình điều khiển với PLC sử dụng các ngôn ngữ này. Một số ưu điểm chính của mô hình lập trình được quy định trong IEC 61131-3 là:
+ Cho phép dùng kết hợp nhiều ngôn ngữ lập trình điều khiển trong cùng một chương trình,
+ Khả năng tái sử dụng các khối chương trình,
+ Thư viện chuẩn các hàm và khối chương trình rất phong phú,
+ Các công cụ đặt cấu hình,
+ Công cụ lập trình tiện lợi, hỗ trợ tối đa việc lập trình điều khiển,
+ Lập tài liệu dự án một cách tiện lợi và nhanh chóng.
Có bốn ngôn ngữ lập trình được quy định trong IEC 61131-3 cùng với một phương pháp tổ chức chương trình điều khiển theo biểu đồ chức năng trình tự (SFC). Trong đó, đáng chú ý nhất là SFC và hai ngôn ngữ lập trình FBD và ST.
Trở lại với bảng 2 và hình 1 trong bài viết PLC & chuẩn IEC 61131-3, các thành phần cơ bản nhất trong mô hình lập trình được quy định trong chuẩn có thể liệt kê ra bao gồm: kiểu dữ liệu, biến, đơn vị tổ chức chương trình (hàm, khối chức năng, chương trình) và tác vụ. Dưới đây sẽ lần lượt giới thiệu về các thành phần này, lấy trọng tâm là các đơn vị tổ chức chương trình.
Đơn vị tổ chức chương trình (POU - Program Organisation Unit)
Đối với các chương trình điều khiển lớn và phức tạp, phương pháp lập trình có cấu trúc được sử dụng thay cho phương pháp lập trình tuyến tính. Trong các hệ lập trình cho PLC trước kia, phương pháp lập trình có cấu trúc được hỗ trợ thông qua việc tổ chức chương trình thành các khối (block), với ý nghĩa như là các thành phần nhỏ nhất xây dựng nên chương trình (vì vậy gọi là các building block). Các khối này được phân loại theo nội dung chứa bên trong khối, thông thường bao gồm: khối tổ chức chương trình (OB - Organisation Block), khối chức năng (FB - Function Block), khối dữ liệu (DB - Data Block). Có thể thấy là ở đây khối chức năng và dữ liệu của khối chức năng được tách rời nhau tương ứng trong các khối FB và DB. Cách phân chia như thế này gợi nhớ đến các ngôn ngữ lập trình quen thuộc như Pascal hay C với chương trình chính, hàm và dữ liệu toàn cục (global data).
Chuẩn IEC 61131-3 đã tiến một bước xa hơn khi phân chia các khối, được gọi tên là các đơn vị tổ chức chương trình (POU), theo chức năng và sự phân cấp cấu trúc. Có ba loại POU được quy định là: Hàm (FUN - FUNction), khối chức năng (FB - Function Block) và chương trình (PROG - PROGram). Một điểm đáng chú ý là dữ liệu của các khối chức năng không nằm riêng nữa mà được đưa vào ngay trong chính khối đó. Đó chính là sự đóng gói dữ liệu, một trong những nguyên tắc cơ bản của phương pháp lập trình hướng đối tượng. Bảng 1 tóm tắt những thông tin chính về ba loại POU này.
|
Bảng 1: Các loại POU |
||
|
Kiểu POU |
Từ khóa |
Đặc điểm |
|
Hàm (FUNC) |
FUNCTION |
Có thể có nhiều tham số vào. Có một giá trị trả về (trực tiếp). Không có biến tĩnh (static variable), không có trạng thái. Không được phép sử dụng các biến ngoài. |
|
Khối chức năng (FB) |
FUNCTION_BLOCK |
Có thể có nhiều tham số vào và ra, có biến tĩnh, có thể có trạng thái và sử dụng các biến ngoài. |
|
Chương trình (PROG) |
PROGRAM |
Là chương trình chính. Giống với khối chức năng nhưng có thể khai báo và sử dụng các biến vào/ra (I/O), dữ liệu toàn cục và các lối truy cập. |
Cần phân biệt rõ sự khác nhau giữa ba loại POU này. Một chương trình về cơ bản giống với một khối chức năng. Điểm khác biệt chủ yếu là trong chương trình có khai báo các biến vào/ra (I/O variables) - các biến được gắn với các địa chỉ vào/ra vật lý cụ thể - cùng với các dữ liệu toàn cục và các lối truy cập (một phương cách cho phép giao tiếp với các hệ thống ngoài, xem lại phần 1). Các biến cục bộ của một chương trình hay của một khối chức năng đều là biến tĩnh, nghĩa là giá trị của biến được duy trì giữa các lần thực thi khác nhau của khối. Nói cách khác, các khối này có nhớ (hay có trạng thái) và do đó, với cùng các giá trị đầu vào, chúng có thể cho kết quả khác nhau giữa các lần thực thi khác nhau, tùy thuộc vào trạng thái hiện thời của khối. Có thể hình dung một sự tương ứng giữa khối chức năng trong chuẩn với đối tượng (hay thực thể lớp - class instance) trong các ngôn ngữ lập trình hướng đối tượng. Các khối chức năng là các thực thể tồn tại trong suốt quá trình thực thi của toàn bộ chương trình trong PLC.
Ngược lại, biến cục bộ của hàm không phải là biến tĩnh, nghĩa là giá trị của biến không được nhớ giữa các lần thực thi. Nói cách khác, các hàm không có nhớ, không có trạng thái và do đó, hàm luôn cho cùng một kết quả với cùng các giá trị đầu vào giữa các lần thực thi khác nhau. Bên cạnh đó, trong hàm không được phép sử dụng các biến ngoài, dù là biến toàn cục hay lối truy cập. Có quy định chặt chẽ như vậy là để đảm bảo tính chất không có trạng thái của hàm, bởi nếu được sử dụng biến ngoài, hàm có thể lưu giữ trạng thái của nó trong các biến này. Để giúp người đọc dễ dàng hình dung về sự khác nhau giữa hàm và khối chức năng, bảng 2 đưa ra một số ví dụ về các khối này.
|
Bảng 2 Ví dụ về hàm và khối chức năng |
|
|
Hàm |
Các hàm toán học: cộng, trừ, nhân, chia, lượng giác,… Các hàm chuyển đổi kiểu dữ liệu Các hàm thời gian hệ thống Các hàm so sánh, lựa chọn Các hàm xử lý chuỗi Các hàm xử lý bit |
|
Khối chức năng |
Các bộ đếm (counter), bộ định thời (timer) Các khối flip-flop Các khối phát hiện sườn tín hiệu Các khối truyền thông |
Chuẩn IEC 61131-3 quy định một số các hàm và khối chức năng chuẩn mà tất cả các hệ thực thi đều phải cung cấp (giống như trường hợp thư viện lập trình chuẩn của C/C++). Thư viện chuẩn này rất phong phú và đáp ứng được hầu hết các nhu cầu sử dụng thông thường. Các ví dụ trong là nội dung chính của các hàm và khối chức năng chuẩn đã được quy định.
Các thành phần của một POU
Trong IEC 61131-3, mỗi khối POU được coi như một đơn vị toàn vẹn, có thể được định nghĩa và dịch một cách hoàn toàn độc lập với các thành phần khác trong chương trình. Tuy nhiên, để thực hiện được như vậy, chương trình dịch (của hệ lập trình cho PLC) cần biết đầy đủ thông tin về giao diện (interface) của các POU khác được sử dụng trong POU đang được dịch. Vì lí do này, chuẩn quy định tất cả các POU đều phải có nguyên mẫu (prototype), chính là giao diện của nó với bên ngoài. Một cách nôm na, nguyên mẫu là những thông tin cần thiết để xác định một POU, bao gồm: tên của POU, danh sách các tham số vào và ra (tên và kiểu dữ liệu của từng tham số), kiểu dữ liệu trả về (đối với hàm). Những quy định này của chuẩn hoàn toàn tương ứng với khả năng biên dịch riêng rẽ và các quy định về khai báo (declaration) của ngôn ngữ lập trình C++. Trong các phần sau chúng ta sẽ thấy rõ hơn sự tương đồng giữa ngôn ngữ lập trình này với các quy định trong chuẩn.
Bên cạnh phần khai báo, mỗi POU đều phải có phần mã (code) thực thi chức năng của khối. Phần mã này có thể được thực hiện bằng một ngôn ngữ lập trình hay kết hợp một cách linh hoạt nhiều ngôn ngữ lập trình khác nhau. (Hình 1 biểu diễn một cách trực quan các thành phần của một POU).

Hình 1: Các thành phần của một POU
Kiểu và tên của POU
Một POU được xác định trước hết bởi kiểu và tên gọi của nó. Mỗi POU phải thuộc một trong ba kiểu đã quy định trong chuẩn là hàm, khối chức năng và chương trình, tương ứng với ba từ khóa là FUNCTION, FUNCTION_BLOCK và PROGRAM. Bên cạnh đó, mỗi POU phải có một tên gọi duy nhất, nghĩa là các POU khác nhau phải có tên khác nhau, bất kể kiểu của chúng như thế nào. Tên gọi của POU phải tuân theo quy định của chuẩn về định danh: Định danh chỉ bao gồm các chữ cái, các chữ số và dấu nối dưới; định danh không được bắt đầu bằng một chữ số hay nhiều hơn một dấu nối dưới; định danh không được kết thúc bởi dấu nối dưới; định danh không phân biệt chữ hoa và chữ thường. Chiều dài tối đa của định danh không được quy định trong chuẩn mà tùy thuộc vào từng hệ thực thi cụ thể, nhưng tối thiểu phải là 6.
Dưới dạng văn bản, phần khai báo kiểu và tên của một POU như trong bảng 3.

Bảng 3: Khai báo kiểu và tên POU
Có hai điểm cần chú ý trong phần khai báo kiểu và tên POU cũng như trong phần khai báo tham số và biến (sẽ giới thiệu sau):
+ Thứ nhất, các từ khóa và cách khai báo dưới dạng văn bản như trên không phụ thuộc vào một ngôn ngữ lập trình cụ thể nào. Điều này nghĩa là dù POU được thực hiện bằng ngôn ngữ lập trình FBD, ST, LD, IL hay dưới dạng SFC thì cách khai báo vẫn giống nhau, điểm khác biệt chỉ là ở phần mã.
+ Thứ hai, IEC 61131-3 quy định một cách lập trình chuẩn dưới dạng văn bản của phần khai báo cũng như của tất cả các ngôn ngữ lập trình, kể cả các ngôn ngữ đồ họa. Tuy nhiên điều đó không có nghĩa là việc lập trình theo chuẩn bắt buộc phải thực hiện dưới dạng văn bản. Các hệ thực thi khác nhau có thể cung cấp các cách thức khác nhau, hầu hết là dưới dạng giao diện đồ họa rất tiện dụng, để thực hiện các công việc này.
Khai báo tham số và biến của POU
Biến được sử dụng để lưu trữ thông tin, phục vụ cho quá trình xử lý thông tin. Mỗi biến được gắn với một địa chỉ vật lý cụ thể trong bộ nhớ. Khác với các hệ lập trình cho PLC trước kia, chuẩn IEC 61131-3 không bắt buộc người lập trình phải xác định địa chỉ của từng biến một cách trực tiếp mà việc quản lý và bố trí các biến trong bộ nhớ sẽ do hệ lập trình đảm nhiệm. Tuy nhiên, người lập trình vẫn có thể tự quy định địa chỉ cho từng biến, đặc biệt là với trường hợp các biến vào/ra. Bên cạnh đó, mỗi biến phải thuộc một kiểu dữ liệu xác định đã được quy định rõ trong chuẩn. Nội dung này sẽ được trình bày chi tiết hơn trong mục sau.
Có nhiều loại biến khác nhau được quy định, phân thành ba nhóm chính như trong bảng 4

Bảng 4: Các loại biến được quy định trong chuẩn
Khái niệm biến cục bộ (khai báo với từ khóa VAR) hoàn toàn giống như các khái niệm tương tự trong các ngôn ngữ lập trình như C++ hay Pascal. Tuy nhiên các khái niệm về tham số (hay biến hình thức) được quy định trong chuẩn có một số điểm khác biệt so với các ngôn ngữ lập trình quen thuộc. Ta sẽ tìm hiểu cụ thể hơn về từng loại biến này để hiểu rõ bản chất của chúng cũng như cách thức sử dụng cho phù hợp.
+ Biến vào VAR_INPUT: là biến hình thức để đưa dữ liệu từ ngoài vào POU khi thực thi. Các tham số thực được truyền vào POU bằng giá trị, nghĩa là chỉ có một bản sao của tham số thực được truyền vào. Do đó, POU sẽ không thể thay đổi được giá trị của biến bên ngoài.
+ Biến vào/ra VAR_IN_OUT: là biến hình thức cho phép POU đọc và ghi biến bên ngoài. Tham số thực được truyền vào trong POU không phải bằng giá trị mà bằng con trỏ đến địa chỉ của biến ngoài trong bộ nhớ. Do đó, POU có thể đọc cũng như thay đổi giá trị của biến ngoài.
+ Biến ra VAR_OUTPUT: là biến cho phép POU đưa dữ liệu ra ngoài. Điểm khác biệt giữa loại biến này với loại biến VAR_IN_OUT là nó không được sử dụng trực tiếp trong giao diện gọi thực thi mà được coi như một thuộc tính (attribute) của khối POU (nhớ lại rằng POU trong IEC 61131-3 rất gần với khái niệm đối tượng trong ngôn ngữ lập trình C++). Trong quá trình thực thi, POU có thể gán dữ liệu vào các biến này nhưng các giá trị đó không được truyền ngay ra ngoài khi quá trình thực thi kết thúc. Nếu muốn lấy các giá trị ra này, mã gọi bên ngoài phải truy nhập trực tiếp vào các biến VAR_OUTPUT như các thuộc tính của POU.
Không phải tất cả các loại biến trên đều có thể sử dụng được trong tất cả các loại POU mà phải căn cứ vào đặc thù của từng loại POU. Ví dụ như hàm không thể sử dụng các biến toàn cục vì về bản chất, hàm không có trạng thái. Không chỉ bị giới hạn về loại biến, mỗi loại POU còn bị những giới hạn nhất định về kiểu dữ liệu có thể sử dụng cho biến. tóm tắt về khả năng sử dụng của từng loại biến trong các loại POU khác nhau.
Bảng 5 Khả năng sử dụng của các loại biến
Các kiểu dữ liệu
Chuẩn IEC 61131-3 quy định một số kiểu dữ liệu cơ sở. Ngoài ra còn có các kiểu dữ liệu tổng quát và các kiểu dữ liệu dẫn xuất (các kiểu dữ liệu mới do người dùng định nghĩa).
Các kiểu dữ liệu cơ sở trong IEC 61131-3 được liệt kê trong bảng 6.

Bảng 6: Các kiểu dữ liệu cơ sở
IEC 61131-3 đưa ra khái niệm “kiểu dữ liệu tổng quát” để đại diện cho một nhóm các kiểu dữ liệu có chung một tính chất nào đó. Ví dụ, tất cả các kiểu dữ liệu để biểu diễn số (thực hay nguyên) đều được nhóm vào cùng một kiểu tổng quát là ANY_NUM. Các kiểu dữ liệu tổng quát chỉ được dùng cho các biến vào và ra của hàm và khối chức năng. Điều này làm cho các hàm và khối chức năng đó mang tính tổng quát và có thể áp dụng cho nhiều kiểu dữ liệu khác nhau. Các kiểu dữ liệu tổng quát không có ý nghĩa nào khác trong một chương trình và không thể được sử dụng cho một biến bình thường.
Chuẩn cho phép người sử dụng định nghĩa các kiểu dữ liệu riêng từ các kiểu dữ liệu cơ sở, được gọi là các kiểu dữ liệu dẫn xuất. Có năm kiểu dẫn xuất là:
+ Các kiểu dẫn xuất trực tiếp (từ các kiểu dữ liệu cơ sở).
+ Các kiểu liệt kê (enumerated data type).
+ Các kiểu dãy con (subrange data type).
+ Các kiểu cấu trúc (STRUCT data type).
+ Các kiểu mảng (ARRAY data type).
Với các kiểu dữ liệu cơ sở tương đối phong phú cùng với các kiểu dữ liệu tổng quát và khả năng định nghĩa các kiểu dữ liệu dẫn xuất linh hoạt, việc lập trình theo chuẩn IEC 61131-3 tương đối thuận lợi và nói chung đáp ứng được mọi yêu cầu thực tế của người lập trình.
Phần mã của POU
Như đã trình bày, phần khai báo của POU hoàn toàn độc lập với phần mã của POU, nghĩa là không phụ thuộc vào ngôn ngữ lập trình cụ thể được sử dụng. Phần mã (hay còn gọi là phần thân) của POU có thể được lập trình bằng bất kì ngôn ngữ lập trình nào đã được quy định trong chuẩn. Bên cạnh đó, các ngôn ngữ lập trình khác nhau có thể được sử dụng kết hợp trong cùng một POU (theo một số quy tắc nhất định) để tận dụng ưu điểm của từng loại ngôn ngữ khác nhau. Điều này thể hiện rõ nhất trong các biểu đồ SFC khi các điều kiện chuyển tiếp hoặc các hành động thường được thực hiện bằng các ngôn ngữ lập trình khác nhau.
Tuy nhiên, không phải ngôn ngữ lập trình nào cũng có thể sử dụng được trong tất cả các loại POU, cũng giống như các loại biến và các kiểu dữ liệu. Cả chương trình và khối chức năng đều có thể được thực hiện bằng tất cả các ngôn ngữ lập trình đã quy định nhưng SFC thì thường chỉ được sử dụng trong chương trình. Hàm không thể được thực hiện bằng SFC (vì SFC có trạng thái), hầu như không sử dụng ngôn ngữ FBD (vì ngôn ngữ FBD thường sử dụng các khối chức năng, vốn không được dùng trong hàm). Được sử dụng phổ biến nhất để thực hiện các hàm là các ngôn ngữ lập trình dạng văn bản, bao gồm ST và IL.
Gọi thực thi các POU
Chuẩn IEC 61131-3 quy định việc gọi thực thi các POU phải tuân theo các quy tắc sau:
+ Chương trình có thể gọi hàm và khối chức năng nhưng ngược lại thì không được.
+ Khối chức năng có thể gọi các khối chức năng khác.
+ Khối chức năng có thể gọi hàm nhưng ngược lại thì không được.
+ Các POU không được phép gọi đệ quy (recursive).
Như vậy có thể thấy là hàm chỉ được phép gọi hàm khác chứ không được phép gọi chương trình hay khối chức năng, cũng không được phép gọi lại chính nó. diễn tả một cách trực quan ba quy tắc đầu tiên về gọi thực thi các POU trong chuẩn.

Hình 2: Quy tắc gọi các POU
Một điểm quan trọng cần chú ý là chuẩn không cho phép các POU được gọi đệ quy, dù dưới bất kì hình thức nào. Nếu một POU không gọi đệ quy một cách trực tiếp mà gián tiếp thông qua một POU khác (nghĩa là POU thứ hai gọi lại POU thứ nhất) thì trường hợp này cũng bị cấm. Nói cách khác, nếu tại một thời điểm mã của một POU đang được thực thi, dù từ bất kì vị trí nào trong chương trình, thì POU đó không thể được gọi thực thi. Sở dĩ có quy định chặt chẽ như vậy là để giảm thiểu khả năng mắc lỗi về bộ nhớ trong chương trình (cụ thể là lỗi tràn bộ nhớ ngăn xếp), một lỗi đặc biệt dễ mắc nếu chương trình có sử dụng gọi đệ quy và cũng là lỗi rất nguy hiểm đối với các chương trình điều khiển. Trong thực tế, các thuật toán đệ quy đều có thể được thực hiện tương đương bằng cách sử dụng các vòng lặp, do đó quy định này không làm giảm đi khả năng lập trình của hệ thống.
Việc lập trình gọi thực thi một POU có thể được thực hiện dưới dạng đồ họa hoặc dưới dạng văn bản. Dưới dạng đồ họa, một POU (hàm hoặc khối chức năng) được biểu diễn bằng một hình chữ nhật với các cổng vào và ra tương ứng với các tham số vào và ra đã khai báo khi định nghĩa POU đó. Thông thường, để sử dụng một POU nào đó, người lập trình chỉ cần kéo hình biểu diễn đồ họa của POU đó vào màn hình soạn thảo và nối các đường tín hiệu tương ứng vào các cổng của khối. Dưới dạng văn bản, việc gọi một POU phụ thuộc vào ngôn ngữ lập trình cụ thể được sử dụng, nhưng về cơ bản thường bao gồm tên của POU theo sau bởi một danh sách các tham số thực đặt giữa một cặp dấu ngoặc đơn.
Khác với các hàm được gọi bằng tên, các khối chức năng được gọi bằng các thực thể (FB instance) giống như việc sử dụng các đối tượng trong ngôn ngữ lập trình C++. Do vậy, trước khi sử dụng một khối chức năng cần khai báo một biến thuộc kiểu khối chức năng đó và sử dụng biến này để thực thi.
Xét ví dụ về một khối chức năng tên Foo. Hình dưới là dạng thể hiện đồ họa của khối chức năng này.
Để gọi thực thi khối chức năng này trong ngôn ngữ lập trình ST, ta cần khai báo một biến thuộc kiểu FOO và sử dụng các lệnh như sau.
VAR
FOO_OBJ: FOO; (* Biến thuộc kiểu FOO *)
FOO_OUT: BOOL;
END_VAR (* Khai báo biến *)
FOO_OBJ(VarIn1:="TRUE," VarIn2:="FALSE);" (* Gọi thực thi *)
FOO_OUT := FOO_OBJ.VarOut ; (* Lấy giá trị ra *)
Tác vụ
Tác vụ (task) là thành phần điều khiển quá trình thực thi chương trình điều khiển, có thể theo chu kỳ hoặc theo sự kiện (sườn lên của một biến logic nào đó). Một tác vụ có thể điều khiển quá trình thực thi của một nhóm các chương trình hoặc các khối chức năng. Khi được gắn trực tiếp với một tác vụ, khối chức năng sẽ hoạt động theo sự điều khiển của tác vụ đó mà không phụ thuộc vào sự hoạt động của chương trình chứa nó. Nói chung, tất cả các chương trình đều phải gắn với một tác vụ để hoạt động.
Các tác vụ được khai báo trong các tài nguyên (resource) và có thể được biểu diễn dưới dạng đồ họa hoặc dạng văn bản. Một tác vụ có ba thuộc tính chính là:
+ SINGLE: trong trường hợp tác vụ hoạt động theo sự kiện thì thuộc tính này xác định biến logic mà sườn lên của nó sẽ gây ra sự kiện.
+ INTERVAL: trong trường hợp tác vụ hoạt động theo chu kỳ thì thuộc tính này xác định chu kỳ đó. Độ phân giải thời gian không được quy định trong chuẩn mà tùy thuộc vào hệ thực thi cụ thể.
+ PRIORITY: mức độ ưu tiên của tác vụ, với mức 0 là cao nhất, giá trị mức càng lớn thì độ ưu tiên càng thấp. Độ ưu tiên càng cao thì tác vụ càng được ưu tiên thực hiện trong quá trình lập lịch của hệ thống.
Tài liệu tham khảo
1) International Electrotechnical Commission: Final Draft IEC 61131-3, 2nd Ed. - Programmable Controllers - Programming Languages.
2) Karl-Heinz John, Michael Tiegelkamp. IEC 61131-3: Programming Industrial Automation Systems. Springer. 2001
HIENDAIHOA.COM(Theo: Tạp chí TĐHNN)































