Trao đổi kinh nghiệm lập trình trên Step 7

123 views
Skip to first unread message

nchun...@gmail.com

unread,
Jun 2, 2007, 11:30:27 AM6/2/07
to Diễn Đàn 8X, thhung...@yahoo.com
Trao đổi kinh nghiệm lập trình trên Step 7


Cho đến nay, họ các thiết bị PLC của nhiều hãng nổi tiếng thế giới như
Siemens, AB, Omron đã trở nên quen thuộc và gần như là một sự lựa chọn
đầu tiên của nhiều bạn sinh viên, kỹ sư khi thực hiện một dự án công
nghiệp. Như vậy, có thể nói chúng ta đã có khá nhiều kinh nghiệm sử
dụng, cài đặt chủng loại thiết bị này.

Mở đầu

Trước hết chúng ta có thể dễ dàng đồng ý với nhau rằng không phải mọi
thứ là hoàn hảo, ngay cả những sản phẩm ruột của các hãng lớn, ví dụ
như Step7 của Siemens. Tuy nhiên, điều chúng ta bàn luận ở đây không
phải là soi mói những sản phẩm này mà đơn giản chỉ là trao đổi với
nhau đó là những lỗi gì để còn khắc phục hoặc loại bỏ chúng trong quá
trình sử dụng.

Hai loại lỗi mà chúng tôi đề cập trong bài trao đổi này là lỗi về khối
dữ liệu (DB), cụ thể là:

- Lỗi về giá trị khởi tạo (Initial value).

- Tính không thống nhất của việc truy nhập trực tiếp và gián tiếp.

Lỗi về giá trị khởi tạo trong khối DB và cách khắc phục

Đây là lỗi sẽ gặp phải khi soạn thảo một khối dữ liệu kiểu DB. Để có
một khối dữ liệu DB chúng ta có hai cách soạn thảo:

- Soạn thảo trực tiếp từ cửa sổ màn hình chính của Step7 bằng việc
chọn trên thanh công cụ:

sau đó viết tên khối, ví dụ DB1.

- Soạn thảo gián tiếp qua local block của một khối chương trình FB .

Trước hết ta nói về việc soạn thảo trực tiếp. Sau khi đã có khối DB1 ,
ta nháy kép chuột trái tại tên khối DB1 để vào màn hình soạn thảo như
mô tả ở hình dưới:

Nhằm mục đích minh họa lỗi giá trị khởi tạo, ta chỉ cần soạn thảo DB1
một cách đơn giản với hai biến nhớ có tên Value1 và Value2 , sau đó
gán cho Value1 giá trị khởi tạo W#16#F0F0 dưới dạng số Hexa . Đây được
hiểu là giá trị mặc định của biến nhớ Value1 , tức là nếu chương trình
không can thiệp và thay đổi nội dung của Value1 thì nó luôn có giá trị
bằng F0F0 .

Bây giờ ta sẽ viết một chương trình nhỏ nhằm kiểm tra giá trị khởi tạo
này của Value1 , chẳng hạn như xuất giá trị đó ra cổng số QW4 để quan
sát, bằng hai lệnh sau trong OB1 :

LDB1.DBW0

TQW4

Tất nhiên rằng khi được thực hiện, chương trình trên sẽ cho ra kết
quả:

Quay lại màn hình soạn thảo DB1 của Step7, ta sửa lại giá trị khởi
tạo, chẳng hạn từ W#16#F0F0 thành W#16#606 :

sau đó đổ ngược lại (download) vào PLC. Chạy lại chương trình trên và
điều ngạc nhiên xảy ra là kết quả của QW4 hoàn toàn không thay đổi
tương ứng với giá trị khởi tạo mới. Nó giữ nguyên giá trị khởi tạo cũ
là W#16#F0F0 cho dù giá trị khởi tạo của Value1 bây giờ đã là
W#16#606 . Ta có thể kiểm tra điều này trực tiếp từ bộ nhớ của PLC ở
chế độ online.

Hiện tượng trên vẫn không thay đổi, ngay cả khi ta đã cẩn thận xóa
toàn bộ bộ nhớ của PLC (bằng công tắc MRES trên module CPU) và đổ
(download) lại chương trình cùng khối dữ liệu DB1 có giá trị khởi tạo
mới.

Để khắc phục lỗi này, ta có thể thực hiện một trong hai cách sau:

- Xóa khối dữ liệu cũ khỏi Project rồi soạn thảo một khối dữ liệu khác
với giá trị khởi tạo mới.

- Soạn thảo gián tiếp thông qualocal block của một khối chương trình
FB.

Để minh họa cách thứ hai ta làm ví dụ với khối chương trình FB1 có nội
dung:


sau đó gọi nó từ OB1 bằng lệnh:

CALLFB1 , DB2

Output:="QW6

thì tại cổng ra số QW6 sẽ có:

đúng như giá trị khởi tạo W#16#C0C0 của biến nhớ Value1 . Đó cũng là
điều dễ hiểu.

Bây giờ ta sửa lại giá trị khởi tạo của Value1 trong FB1 thành:

tiếp theo, ta viết lại lệnh (bắt buộc):

CALLFB1 , DB2

Output:="QW6

trong OB1. Lúc này, khi được thực hiện, chương trình sẽ xuất ra cổng
đúng giá trị mới:

Tính không thống nhất của việc truy nhập trực tiếp và gián tiếp

Để truy nhập nội dung một biến nhớ trong khối dữ liệu DB , chẳng hạn
DB1, DB2 , ta có hai cách:

- Truy nhập trực tiếp (giống như truy nhập xa ở máy tính) với toán
hạng là địa chỉ ô nhớ và tên khối dữ liệu, ví dụ:

LDB1.DBW0

TDB2.DBW2

Cách truy nhập này tỏ ra khá đơn giản, dễ hiểu, song lại có nhược điểm
là không sử dụng được với hai thanh ghi con trỏ địa chỉ AR1 , AR2 mà
đấy lại là công cụ hữu hiệu để xử lý các mảng dữ liệu lớn.

- Truy nhập gián tiếp thông qua nội dung thanh ghi chứa tên khối dữ
liệu. Họ S7-300/400 có hai thanh ghi chứa tên khối dữ liệu, được phân
biệt bằng DB và DI . Để chuyển tên khối dữ liệu vào các thanh ghi đó
ta dùng lệnh:

OPENDB1 // Viết tên khối DB1 vào thanh ghi DB

OPENDI2 // Viết tên khối DB2 vào thanh ghi DI

Sau khi đã có tên khối dữ liệu trong các thanh ghi đó, để truy nhập,
ta chỉ cần chỉ thị trong toán hạng một mình địa chỉ biến nhớ là đủ.
Chẳng hạn:

LDBW0 // Đọc biến nhớ DB1.DBW0

TDIW2 // Ghi vào ô nhớ DB2.DBW2

Mỗi khi sử dụng lại lệnh OPEN , tên khối dữ liệu mới sẽ được ghi đè
lên nội dung cũ. Ví dụ:

OPENDB1 // Viết tên khối DB1 vào thanh ghi DB

L DBW0 // Đọc biến nhớ DB1.DBW0

OPENDB2 // Viết tên khối DB1 vào thanh ghi DB

T DBW2 // Ghi vào ô nhớ DB2.DBW2

Tuy nhiên điều cần bàn là tính không thống nhất giữa hai cách truy
nhập trên, cụ thể là mỗi khi truy nhập trực tiếp, ví dụbằng lệnh:

LDB2.DBW2

thì tên khối dữ liệu DB2 cũng sẽ được chuyển vào thanh ghi DB . Nói
cách khác, một lệnh truy nhập trực tiếp trên được CPU thực hiện bằng
hai lệnh gián tiếp sau:

OPENDB2 // Viết tên khối DB2 vào thanh ghi DB

LDBW2 // Đọc biến nhớ DB2.DBW2

Điều này rất dễ gây ra sự nhầm lẫn địa chỉ khối dữ liệu trong lập
trình, đặc biệt là lập trình có cấu trúc. Kinh nghiệm của chúng tôi là
luôn hạn chế tới mức tối thiểu, hoặc hoàn toàn không sử dụng hình thức
truy nhập trực tiếp

Reply all
Reply to author
Forward
0 new messages