Tải bản đầy đủ (.pdf) (41 trang)

Bài giảng Đo lường và điều khiển bằng máy tính Chương 3 Card thu thập tín hiệu và điều khiển

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (341.45 KB, 41 trang )

Chương 3

CARD THU THẬP TÍN HIỆU VÀ
ĐIỀU KHIỂN
3.1 CARD PCL-818L ADVANTECH
PCL-818L là card ISA có nhiều chức năng dùng để đo lường
và điều khiển. Do tính năng ưu việt của card, việc tìm hiểu hoạt
động của nó rất cần thiết để tiếp cận kỹ thuật thu thập số liệu
bằng máy tính DAS (Data Acquisition System).
Sau đây là các chức năng chính của card:
- Chuyển đổi A/D 16 kênh 12 bit tốc độ lấy mẫu 40000/s
- Chuyển đổi D/A 1 kênh 12 bit
- 16 ngõ vào digital TTL
- 16 ngõ ra digital TTL
- 1 Bộ đếm/ đònh thời 16 bit cho người dùng

Hình 3.1: Vò trí cá c cầu nố i, biế n trở và đầu nối của card PCL-818L


Hình 3.2: Sô ñoà khoá i Card PCL-818L


CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN

115

Hình 3.3: Sơ đồ chân các đầu nối của card PCL-818L
Chú thích
A/DS: vào Analog (đơn)

DI: vào Digital



A/DH: vào Analog cao (vi sai)

DGND: mass Digital và nguồn

A/DL: vào Analog thấp (vi sai)

CLK: Clock Counter 0 của 8254

AGND: mass Analog

GATE: Gate Counter 0 của 8254

D/A: ra Analog

OUT: tín hiệu ra của 8254

DO: ra Digital

VREF: nguồn chuẩn trong
VREF IN: nguồn chuẩn ngoài

3.2 CÁC THANH GHI CỦA CARD
PCL- 818L có 16 thanh ghi, đòa chỉ gốc có thể chọn bởi công
tắc SW1, gồm 6 tiếp điểm, chọn các đường đòa chỉ SA4  SA9,
thường đặt đòa chỉ gốc BASE là 300h.


116


CHƯƠNG 3

Bảng 3.1 Các thanh ghi
Đòa chỉ

Đọc

Viết

BASE+0

Byte thấp A/D và số kênh

Kích mềm A/D

BASE+1

Byte cao A/D

Điều khiển tầm A/D

BASE+2

Quét kênh MUX

Quét kênh MUX và chỉ tầm điều khiển

BASE+3

Byte thấp Digital Input


Byte thấp Digital Output

BASE+4

N/A

Byte thấp Analog Output

BASE+5

N/A

Byte cao Digital Output

BASE+6

N/A

N/A

BASE+7

N/A

N/A

BASE+8

Trạng thái


Xóa yêu cầu ngắt

BASE+9

Điều khiển

Điều khiển

BASE+10

N/A

Cho phép Counter

BASE+11

Byte cao Digital Output

Byte cao Digital Output

BASE+12

Counter 0

Counter 0

BASE+13

Counter 1


Counter 1

BASE+14

Counter 2

Counter 2

BASE+15

N/A

Điều khiển counter

3.2.1 Các thanh ghi cơ sở + 0 và cơ sở +1
Khi đọc thanh ghi
BASE+0 (đọc) - Chứa Byte thấp A/D và số kênh
Bit

D7

Value AD3

D6

D5

D4


D3

D2

D1

D0

AD2 AD1 AD0 C3

C2

C1

C0

D1

D0

BASE+1 (đọc) - Byte cao A/D
Bit

D7

D6

D5

D4


D3

D2

Value AD11 AD10 AD9 AD8 AD7 AD6 AD5 AD4
trong đó:

AD11  AD0 là dữ liệu Analog đổi sang Digital
C3  C0 là số của ngõ vào analog tương ứng

Khi ghi vào thanh ghi BASE+0 : kích mềm bộ A/D, khởi động
ADC. Có thể kích bộ A/D bằng phần mềm, hoặc bằng xung clock
trên board (pacer), hoặc bằng xung ngoài. Các bit 0 và 1 trong
BASE+9 sẽ chọn nguồn kích. Nếu chọn kích mềm thì ta chỉ việc
ghi vào BASE+0 bất cứ một giá trò nào cho mỗi lần kích. Nếu là
kích ngoài thì cầu nối JP3 chọn nguồn kích là DI0 (CN2) hay


117

CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN

TRIG0 (CN3).
Điều khiển tầm A/D (BASE+1):
Mỗi kênh A/D đều có một tầm điện áp ngõ vào riêng cho nó,
được điều khiển bởi mã lưu trữ trong RAM của PCL-818L và được
đặt bởi cầu nối JP7. Nếu chúng ta muốn thay đổi tầm cho một
kênh, chọn kênh như là kênh Start ở thanh ghi BASE+2, quét
kiểu MUX, rồi ghi mã vào bit 0 và bit 1 của thanh ghi BASE+1.

BASE+1 (Ghi) - Điều khiển tầm A/D
Bit

D7 D6 D5 D4 D3 D2 D1 D0

Value N/A N/A N/A N/A N/A N/A G1 G0

Bảng 5.2 Mã tầm và JP7
Tầm điện áp ngõ vào

Mã tầm

JP7 = 5

JP7 = 10

5V

10V

0

0

2.5V

5V

0


1

1,25V

2,5V

1

0

0,625V

1,25V

1

1

3.2.2 Thanh ghi quét phân kênh (BASE+2):
- Đọc/ghi BASE+2 để điều khiển/đọc số kênh A/D được quét.
Nửa byte cao chỉ kênh Stop, nửa byte thấp chỉ kênh Start. Việc
quét phân kênh (MUX) được khởi động đến kênh Start khi chúng
ta ghi vào thanh ghi này. Mỗi Trigger A/D sẽ chuyển đến kênh
đo tiếp theo.
- Khi kích chuyển đổ i liên tục, MUX sẽ quét từ kênh Start
đến kênh Stop rồi lặp lại từ đầu. Ví dụ, nếu kênh Start là 4 và
Stop là 7 thì quét tuần tự: 4, 5, 6, 7, 4, 5, 6, 7. Nếu cài đặt ở chế
độ 8 đầu vào vi sai thì các bit CH3 và CL3 phải là 0.
- Nếu chỉ chọn một kênh để biến đổi A/D thì cài đặt kênh
Start và Stop cùng một trò số là số của kênh cần thực hiện biến

đổi A/D.
BASE+2 (Viết) - Các kênh quét đầu và cuối
Bit

D7

D6

D5

D4

D3 D2 D1 D0

Value CH3 CH2 CH1 CH0 CL3 CL2 CL1 CL0

CH3  CH0 là kênh Stop, CL3  CL0 là kê nh Start.


118

CHƯƠNG 3

Nửa bit thấp của thanh ghi quét phân kênh CL3 đến CL0
cũng có tác dụng như 1 con trỏ khi chúng ta lập trình tầm điện
áp vào A/D. Khi đặt kênh Start là N, thì mã tầm viết vào thanh
ghi BASE+1 là cho kênh N.

3.2.3 Các thanh ghi xuất/nhập số (BASE + 3/11)
PCL-818L có 16 ngõ vào số và 16 ngõ ra số riêng biệt. Các

kênh I/O này dùng chung port có đòa chỉ BASE+3 và BASE+11.
Khi đọc
BASE+3 (đọc port) - Byte thấp Digital Input
Bit

D7

D6

D5

D4

D3

D2

D1 D0

Value D17 D16 D15 D14 D13 D12 D11 D10
BASE+11 (đọc port) - Byte cao Digital Input
Bit

D7

D6

D5

D4


D3

D2

D1 D0

Value DI15 DI14 DI13 DI12 DI11 DI10 DI9 DI8

Khi ghi
BASE+3 (viết port) - Byte thấp Digital Input
Bit

D7

D6

D5

D4

D3

D2

D1

D0

Value DO7 DO6 DO5 DO4 DO3 DO2 DO1 DO0

BASE+11 (viết port) - Byte cao Digital Input
Bit

D7

D6

D5

D4

D3

D2

D1

D0

Value DO15 DO14 DO13 DO12 DO11 DO10 DO9 DO8

3.2.4 Thanh ghi xuất Analog D/A (BASE + 4/5)
Khi ghi
BASE+4 - Byte thấp ngõ ra D/A
Bit

D7

D6


D5

D4

Value DA3 DA2 DA1 DA0

D3

D2

D1

D0

x

x

x

x

D1

D0

BASE+5 – Byte cao ngõ ra D/A
Bit

D7


D6

D5

D4

D3

D2

Value DA11 DA10 DA9 DA8 DA7 DA6 DA5 DA4

trong đó: DA11  DA0 là dữ liệ u Digital sang Analog

Tầm điện áp ra được chọn nhờ cầu nối JP4 và JP5. Nếu JP4


119

CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN

đặt ở IN thì JP5 chọn nguồn chuẩn trong là -5V hay -10V, áp ra
của D/A sẽ là 0 đến +5V hay 0 đến +10V. Nếu JP4 đặt vò trí EXT
thì điện áp ra D/A là kết quả nhân số digital trong hai thanh ghi
với điện áp đặt vào chân 31 VREF IN ( -10V..+10V) của đầu nối
CN3 chia cho 4095.

3.2.5 Thanh ghi trạng thái BASE+8
- Đọc BASE+ 8 để nhận thông tin về cấu hình và hoạt động

A/D.
- Ghi vào BASE+ 8 một giá trò bất kỳ thì nó sẽ xóa bit INT
của BASE+ 8, còn những bit dữ liệu khác không đổi.
BASE+8 - Trạng thái A/D
Bit

D7

D6

D5

D4 D3

D2

D1

D0

Value EOC N/A MUX INT CN3 CN2 CN1 CN0

 EOC: End Of Conversion
EOC= 0: đã đổi xong, kết quả đổi chứa trong BASE+ 0 và
BASE+ 1.

EOC= 1: đang chuyển đổi A/D.
 MUX: chọn 8 kênh vi sai hoặc 16 kênh đơn, phản ảnh vò trí cầu
nối JP6.


MUX= 0: 8 kênh vi sai
MUX= 1: 16 kênh đơn
 INT: tín hiệu ngắt
INT = 0: dữ liệu không có giá trò (không có một biến đổi nào kể
từ khi bit INT bò xóa).

INT = 1: A/D đã biến đổi xong, dữ liệu có giá trò.
Nếu bit INTE= 1 (BASE+ 9) thì khi đổi xong một kênh, tín
hiệu ngắt sẽ gởi đến PC qua ngõ IRQn (IRQn được chọn bởi các
bit I2  I0 trong BASE+9). Dù thanh ghi trạng thái A/D là chỉ
đọc, nhưng khi ghi vào nó một giá trò bất kỳ sẽ xóa bit INT, còn
các bit khác không đổi.


CN3CN0: khi EOC = 0 thì các bit này chứa số kênh kế
tiếp sẽ được biến đổi.

Lưu ý: Nếu kích bộ A/D bằng xung clock trên board (‘pacer’)
hoặc xung ngoài thì phần mềm của bạn phải kiểm tra bit INT


120

CHƯƠNG 3

trước khi đọc dữ liệu (không phải bit EOC). EOC có thể bằng 0
trong hai trường hợp:
Biến đổi đã hoàn tất
Không có một biến đổi nào đã được bắt đầu.
Do đó phần mềm của bạn phải đợi tín hiệu INT = 1 trước khi

đọc số liệu chuyển đổi. Rồi cần phải xóa bit INT bằng cách ghi
bất kỳ giá trò nào vào thanh ghi trạng thái BASE+8.

3.2.6 Thanh ghi điều khiển (BASE+9)
Đọc/ghi thanh ghi BASE+9 để nhận/cung cấp thông tin về
chế độ hoạt động của PCL-818L.
BASE+9 - Điều khiển chế độ hoạt động

Bit

D7 D6 D5 D4 D3

D2

D1 D0

Value INTE I2 I1 I0 x DMAE ST1 ST0

 INTE : cấm/cho phép ngắt.
INTE = 0: cấm ngắt
INTE = 1: cho phép ngắt.


Nếu DMAE = 0: PCL-818L sẽ phát một tín hiệu ngắt khi
nó hoàn tất một chuyển đổi A/D. Vậy cấu hình INTE = 1.
DMAE = 0 dùng để báo cho CPU biết bằng ngắt là đã đổi
A/D xong.




Nếu DMAE = 1: PCL-818L sẽ phát một tín hiệu ngắt khi
nó nhận một tín hiệu đếm tràn T/C (Terminal count) từ bộ
điều khiển DMA của máy tính để chỉ rằng chuyển đổi
truyền DMA đã hoàn tất. Truyền DMA bò dừng bởi ngắt
gây ra bởi tín hiệu T/C. Xem DMAE bên dưới.



I2  I0: chọn số ngắt cho data interrupt hoặc truyền data
DMA (không được trùng với số ngắt của thiết bò khác).ba
bit này chọn số ngắt từ 2 (010) đến 7 (111).

 DMAE: cấm/cho phép PCL-818L truyền DMA.
DMAE = 0: cấm truyền DMA.
DMAE = 1: cho phép truyền DMA. Mỗi biến đổi A/D sẽ khởi
động hai tín hiệu yêu cầu ngắt liên tiếp. Các tín hiệu này cho
phép bộ điều khiển DMA 8237 truyền 2 byte dữ liệu chuyển đổi


121

CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN

AD từ PCL-818L đến bộ nhớ. Chọn kênh truyền DMA 1 hay 3
nhờ cầu nối JP1.
Lưu ý: phải lập trình bộ điều khiển DMA và thanh ghi trang
DMA 8237 của máy tính trước khi đặt DMAE = 1.


ST1  ST0: chọn nguồn kích

Bảng 5.3
Nguồn kích ST1 ST0
Kích mềm

0

X

Kích ngoài

1

0

Kích Pacer

1

1

3.2.7 Thanh ghi cho phép đếm/ đònh thời (BASE+10)
Card PCL-818L có vi mạch 8254 gồm ba bộ đếm 0, 1, 2 và sử
dụng hai bộ đếm 1, 2, còn bộ đếm 0 cho người dùng. Xung nhòp
cho bộ đếm 1 có thể chọn là 10MHz hay 1MHz nhờ cầu nối JP2,
ngõ ra bộ đếm 1 đưa vào ngõ nhòp của bộ đếm 2, ngõ ra của bộ
đếm 2 đưa vào kích A/D (kích pacer), vậy tần số kích phụ thuộc
tần số xung nhòp và số ghi vào hai bộ đếm 1, 2.
Tần số của pacer là Fclk /( Div1  Div2) với Fclk  1 MHz hay
10MHz, Div1 và Div2 là số đặt trong bộ đếm 1 và bộ đếm 2.
Bộ đếm 0 có ngõ vào Clk là 100 KHz hay xung nhòp ngoài ở

chân 17 CN3 chọn nhờ BASE+ 10, chân Gate là DI2 (chân 3
CN2) hay GATE0 (chân 36 CN3) chọn nhờ cầu nối JP3.
Ghi vào BASE+10 để cho phép hoặc cấm bộ đếm/ đònh thời
của PCL-818L tạo xung.
BASE+10 - Cho phép pacer
Bit

D7 D6 D5 D4 D3 D2 D1

Value x

x

x

x

x

D0

x TC1 TC0


122

CHƯƠNG 3

 TC0: cấm/ cho phép pacer
TC0 = 0; cho phép pacer

TC0 = 1; pacer được điều khiển bởi TRIG0 (chân 35 CN3). Tín
hiệu này chặn xung trigger gởi từ ‘pacer’ đến bộ A/D khi nó bằng
0.
 TC1: chọn chế độ nguồn xung nhòp ngõ vào Counter 0.
TC1 = 0; counter 0 nhận xung clock ngoài (chân 17 CN3)
TC1 = 1; counter 0 nhận xung clock 100KHz ở bên trong.

3.2.8 Các thanh ghi điều khiển và đọc/ghi bộ đếm
Bộ đònh thì 8254 sử dụng bốn thanh ghi BASE+12, BASE+13,
BASE+14, BASE+15. Các chức năng của các thanh ghi này được
liệt kê trong bảng 5.14.
Bảng 5.4
Thanh ghi

Chức năng

Thanh ghi

Chức năng

BASE+12

Counter 0 đọc/ghi

BASE+14

Counter 2 đọc/ghi

BASE+13


Counter 1 đọc/ghi

BASE+15

Điều khiển bộ đếm

Do bộ đếm 8254 có cấu trúc 16 bit, nên mỗi dữ liệu đọc/ ghi
được chia làm 2 byte: byte thấp (LSB), byte cao (MSB). Để tránh
phạm lỗi đọc/ghi sai, cần chú ý thao tác đọc ghi từng đôi (tức mỗi
lần đọc/ghi hai byte) và theo đúng thứ tự byte. Chi tiết về thanh
ghi điều khiển của 8254 xem ở Chương 3.


CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN

123

3.3 CHUYỂN ĐỔI A/D, D/A & DO
5.3.1 Lập trình trực tiếp
Card PCL-818 có thể lập trình bằng kỹ thuật đã trình bày ở
Chương 4, nghóa là truy cập trực tiếp các thanh ghi của card.
1- Chuyển đổi A/D
Có thể kích đổi A/D bằng phần mềm, bằng xung ngoài hay
bằng pacer on board. Bit 1 và 0 của thanh ghi BASE+9 sẽ chọn
nguồn trigger tương ứng.
Khi chọn kích pacer tần số kích từ 2,5 MHz đến 71 phút một
xung. Khi chọn kích ngoài, nguồn kích đònh bởi cầu nối JP3 chọn
tín hiệu kích là TRIGO (chân 35 CN3) hay DI0 (chân 1 CN2).
Việc truyền kết quả A/D cho máy tính có thể thực hiện bằng
chương trình điều khiển, bằng ngắt hay DMA.

Các bước hình thành để chuyển đổi A/D với trigger bằng
phần mềm và truyền kết quả A/D bằng chương trình điều khiển:
- Đặt tầm vào cho mỗi kênh A/D.
- Đặt kênh vào bằng cách chỉ rõ tầm quét kênh.
- Kích đổi A/D bằng cách ghi vào BASE+0 một số bất kỳ nào đó.
- Kiểm tra chuyển đổi đã kết thúc chưa bằng cách đọc bit
EOC của thanh ghi trạng thái.
- Đọc kết quả chuyển đổi ở thanh ghi BASE+ 0 và BASE+ 1.
- Chuyển dữ liệu từ số nhò phân thành số nguyên.
2- Chuyển đổi D/A
Ghi vào thanh ghi BASE+ 4 và BASE+ 5. Khi ghi dữ liệu cho
kênh D/A phải ghi byte thấp trước. Byte thấp này được giữ tạm
thời trong một thanh ghi và không được xuất ra. Sau khi ghi xong
byte cao thì khi đó byte cao và byte thấp được kết hợp lại để
chuyển thành D/A.
3- Digital input và output (DI&DO)
Ta đọc DI từ thanh ghi BASE+3 (byte thấp) và thanh ghi
BASE+11 (byte cao). Sau khi đọc dữ liệu sẽ không được chốt,
đường vào sẽ ở trạng thái thứ ba. Ta có thể xuất ra DO cũng


124

CHƯƠNG 3

bằng cách dùng hai thanh ghi BASE+3 và BASE+11 này. Thanh
ghi sẽ chốt giá trò đã ghi (có thể đọc lại). Để an toàn nên ghép
nối các ngõ vào/ra digital thông qua ghép quang.

3.3.2 Lập trình theo software driver của nhà sản xuất

Mỗi PC_LABCARD có một software driver Adsapi32.dll cho
phép chúng ta có thể dùng các hàm và thủ tục viết sẵn để viết
chương trình ứng dụng bằng ngôn ngữ cấp cao như Delphi, Visual
Basic, Visual C. Điều này giúp lập trình một cách đơn giản hơn là
viết trực tiếp vào các thanh ghi vì mỗi hàm sẽ kéo tất cả các
tham số từ bảng tham số. Chúng ta không cần đònh lại bảng
tham số mỗi khi ta gọi nó, trừ khi bảng tham số có sự thay đổi.
Chương trình cài đặt chứa trong CDROM. Trong chương trình ứng
dụng cần khai báo sử dụng driver. Driver của hãng Advantech
viết có thể sử dụng chung cho nhiều loại card của hãng và việc
đọc tìm hiểu các hàm đã viết sẵn tương đối mất nhiều thời gian.
Mục 5.3.1 trình bày một unit gồm các hàm viết sẵn cho Delphi.
Mục 5.3.4 trình bày sơ lược driver adsapi32.

3.4 LẬP TRÌNH CHO CARD PCL-818L
3.4.1 Unit dùng cho card PCL-818L trong Delphi
Unit PCL818L;
Interface
CONST
base= $300;
reg0= base + 0;
reg1= base + 1;
reg2= base + 2;
reg3= base + 3;
reg4= base + 4;
reg5= base + 5;
reg6= base + 6;
reg7= base + 7;
reg8= base + 8;
reg9= base + 9;

reg10= base + 10;
reg11= base + 11;

đia chi nen cho I/O


125

CARD THU THAP TN HIEU VAỉ ẹIEU KHIEN
reg12= base + 12;
reg13= base + 13;
reg14= base + 14;
reg15= base + 15;

1 Function Read_AD (var channel: byte): word
2 Procedure Trig_AD;
3

Procedure Set_rangeAD (range: byte);

4

Procedure Set_channel AD (start, stop: byte);

5

Function Dig_in: word;

6


Procedure Dig_out (data: word);

7

Procedure Analog_out (data: word);

8

Function EOC: byte;

9

Function MUX: byte;

10

Function INT: byte;

11

Function Next_channel: byte;

12

Function INTE: byte;

13

Function IRQ: byte;


14

Function DMAE: byte;

15

Function Trigsource: byte;

16

Procedure Set_INTE (sint: byte);

17

Procedure Set_IRQ (irq: byte);

18

Procedure Set_DMAE (dmae: byte);

19

Procedure Set_trigsource (trs: byte);

20

Procedure Clear_INT;

21


Procedure Counter_enb (tc: byte);

22

Procedure Set_counter (cnt, mode, dl, dh: byte);

23

Procedure Select_nextchannel (setchan: byte);

24

Function Read_counter (cnt: byte): word;

25

procedure Reload_counter (dl1, dh1, dl2, dh2: byte);

26

procedure Xuat (add:word; data: byte);

27

function Nhap (add:word): byte;

implementation
Function inport (address: word): byte;
var data: word;
begin


ham nhap vao Port


126

CHÖÔNG 3
asm
mov dx, address
in ax, dx
mov data, ax
end;
inport:= data;
end;
Procedure outport (address: word; data: word); ham xuat ra Port
begin
asm
mov dx, address
mov ax, data
out dx, ax
end;
end;

1

Function Read_AD (var channel: byte): word; doc du lieu bo A/D

var dlow, dhigh: byte;
begin
dlo:= inport (reg0);

dhigh:=inport(regl);
channel:= dlow and $0F; lay 4 bit thap
dlow:= (dlow and $F0) shr 4;
Read_AD:= dlow + 16*dhigh;
end;

2

Procedure Trig_AD;

kich mem bo A/D

begin
outport (reg0, $FF);
end;

3

Procedure Set_rangeAD (range: byte);

dat tam dien ap ngo vao AD
var rang: byte;
begin
rang:=range and $03;
outport (reg1, rang);
end;

4

Procedure Set_channel AD (start: byte; stop: byte);


begin
outport (reg2, (stop shl 4) or start);
end;


CARD THU THAP TN HIEU VAỉ ẹIEU KHIEN

5

Function Dig_in: word;

begin
dig_in:=inport (reg3) + 256* inport (reg11);
end;

6

Procedure Dig_out (data: word);

begin
outport (reg3, data and $00FF);
outport (reg11, (data and $FF00) shr 8);
end;

7

Procedure Analog_out (data: word);

begin

outport (reg4, (data and $000F) shl 4);
outport (reg5, (data and $0FF0) shr 4);
end;

8

Function EOC: byte;

begin
EOC:= (inport (reg8) and $80) shr 7;
end;

9

Function MUX: byte;

begin
MUX:= (inport (reg8) and $20) shr 5;
end;

10

Function INT: byte;

begin
INT:= (inport (reg8) and $10) shr 4;
end;

11


Function Next_channel: byte;

begin
Next_channel:= inport (reg8) and $0F;
end;

12

Function INTE: byte;

begin
INTE:= (inport (reg9) and $80) shr 7;
end;

13

Function IRQ: byte;

begin
IRQ:= (inport (reg9) and $70) shr 4;
end;

14

Function DMAE: byte;

127


128


CHÖÔNG 3
begin
DMAE:= (inport (reg9) and $04) shr 4;
end;

15

Function Trigsource: byte;

begin
Trigsource:= inport (reg9) and $03;
end;

16

Procedure Set_INTE (sint: byte); {dat xoa INTE}

var i: byte;
begin
i:= inport (reg9) and $7F;
outport (reg9), (sint shl 7) or i);
end;

17

Procedure Set_IRQ (irq: byte); {chon ngo ngat}

var i: byte;
begin

i:= inport (reg9) and $8F;
outport (reg9, (irq shl 4) or i);
end;

18

Procedure Set_DMAE (dmae: byte); {dat xoa DMAE}

var i: byte;
begin
i:= inport (reg9) and $FB;
outport (reg9, (dmae shl 2) or i);
end;

19

Procedure Set_trigsource (trs: byte);

var i: byte;
begin
i:= inport (reg9) and $FC;
outport (reg9, i or trs);
end;

20

Procedure Clear_INT;

begin
outport (reg8, $FF);

end;

21

Procedure Counter_enb (tc: byte);

begin
outport (reg10, tc and $03);
end;


129

CARD THU THAP TN HIEU VAỉ ẹIEU KHIEN

22

Procedure Set_counter (cnt, mode, dl, dh: byte);

begin
outport (reg15, $30) + (cnt shl 6) + (mode shl 1);
outport (reg12 + cnt, dl);
outport (reg12 + cnt, dh)
end;

23

Procedure Select_nextchannel (setchan: byte)

var i: byte;

begin
i:= (inport (reg8) and $F0) or setchan;
outport (reg8, i)
end;

24

Function Read_counter (cnt: byte): word; {doc LSB truoc, MSB sau}

var dl, dh, cnt0: byte;
begin
cnt0:= cnt +1;
if cnt0 = 3 then cnt0:=4
outport (reg15, $D0 + (cnt0 shl 1));
dl:= inport (reg12 + cnt);
dh:=inport (reg12 + cnt);
Read_counter:= dl + 256*dh;
end;

25

Procedure Reload_counter (dl1, dh1, dl2, dh2: byte);

var dl, dh: byte;
begin
outport (reg15, $D4);
dl:= inport (reg13);
dh:= inport (reg13);
if (dl+dh = 0) then
begin

Counter_enb (1); counter 1, mode 2
Set_counter (1, 2, dl1, dh1);
end;
outport (reg15, $D8);
dl:= inport (reg14);
dh:= inport (reg14);
if (dl+dh = 0) then
begin
Counter_enb(2);

counter 1, mode 2

Set_counter (2,2, dl1, dh1);


130

CHệễNG 3
end;
end;

26

Procedure Xuat (add: word; data: byte);

begin
outport (add, data);
end;

27


Function Nhap (add: word): byte;

begin
nhap:=inport (add);
end;
end.

3.4.2 Chửụng trỡnh C ủoồi tửụng ủong ra soỏ duứng kớch mem
#include <stdio.h>
#include <dos.h>
#include
#include <conio.h>
char *gain_str[4]={"5V","2.5V","1.25V","0.625V"};
void main()
{
int status, s_end, start, stop;
int dtl, dth, adl, adt, c_reg, s_ch_val, r_ch;
int chv, ch_gain[16];
int port, val, i, j;
port= 0x300;

/* Set I/O port base address */

/********** STEP 1: INITIALIZE & SELECT SOFTWARE TRIGGER *************/
val= 0x70;
outportb(port+9, val);

/* software trigger */


c_reg = inportb(port+9);
if (c_reg != val)
{
printf("PCL-818L hardware verification failed!\n");
exit(0);
}


CARD THU THAP TN HIEU VAỉ ẹIEU KHIEN
outportb(port+8,1);

/* Clear interrupt request */

printf("\n***** Please set PCL-818L's jumper 7 (A/D IN) to 5V *****\n\n");
/* ******** STEP 2: READ A/D STATUS REGISTER **************************** */
status = inportb(port+ 8);
if ((status & 0x20)== 0x20)
s_end = 1;
else
s_end = 0;
redo:
if(s_end==1)
{
printf("Enter start channel number <0-15>: ");
scanf("%d",&start);
printf("Enter stop channel number <0-15>: ");
scanf("%d",&stop);
}
else
{

printf("Enter start channel number <0-7>: ");
scanf("%d",&start);
printf("Enter stop channel number <0-7>: ");
scanf("%d",&stop);
}
if ((s_end== 0) & (stop>7))
{
printf("Entered channel failed! Re-do!\n");
goto redo;
}
if ((s_end==1) & (stop>15))
{
printf("Entered channel failed! Re-do!\n");

131


132

CHÖÔNG 3
goto redo;
}
if (start > stop)
{
printf("Entered channel failed!\n");
goto redo;
}
/*********** STEP 3: SET A/D RANGE CODE *****************/
for(i=start; i<=stop; i++)
{

printf("Enter range code <0 -- 3> for channel %d :",i);
re_enter_gain:
scanf("%d",&ch_gain[i]);
if( ch_gain[i] < 0 || ch_gain[i] > 3 )
{
printf("Wrong code! Enter again: ");
goto re_enter_gain;
}
outportb(port+2, i);
outportb(port+1, ch_gain[i]);
printf("\n");
}
/********* STEP 4: SET SCAN CHANNEL RANGE ***********************/
s_ch_val=stop*16+start;

/* Set scan channel value */

outportb(port+2,s_ch_val);
r_ch = inportb(port+ 2);

/* Read back channel value */

if (r_ch != s_ch_val)
{
printf("Scan channel setting failed!\n");
exit(0);
}


CARD THU THAP TN HIEU VAỉ ẹIEU KHIEN


133

delay(1);
/********* STEP 5: PERFORM SINGLE A/D CONVERSION ***********/
do {
outportb(port+8, 0);
outportb(port, 0);
reread:
status = inport(port+ 8);
if ((status & 0x10)== 0x10)
goto reread;
delay(1);
dtl = inportb(port);
dth = inportb(port+1);
adl = dtl/16;
adt = dth*16+ adl;
chv = dtl- adl*16;
printf(" A/D data = %d\n",adt);
printf(" Current channel = %d A/D range = %-7s\n",chv, gain_str[ch_gain[chv]]);
printf(" Next scan channel = %d\n",(status & 0x0f));
printf(" Start scan channel= %d\n",start);
printf(" Stop scan channel = %d\n",stop);
printf(" Type 'ESC' to exit or other key for another conversion.\n\n");
} while(getche()!=27);
}

3.4.3 Chửụng trỡnh Qbasic
230 SCREEN 0,0,0:WIDTH 80:CLS:KEY OFF
240 PORT%=&H300


'SET I/O PORT BASE ADDRESS

310 DIM GAIN%(16)
320 '******** STEP 1: INITIALIZE & SELECT SOFTWARE TRIGGER ***************
330 'PORT%+9 ---- CONTROL REGISTER
340 OUT PORT%+9,&H70

'SELECT SOFTWARE TRIGGER

350 C.REG%=INP(PORT%+9)
360 IF C.REG% <> &H70 THEN PRINT"PCL-818L VERIFICATION FAILED!":STOP


134

CHÖÔNG 3
370 OUT PORT%+8,1

'CLEAR INTERRUPT REQUEST

380 PRINT "***** PLEASE SET PCL-818L'S JUMPER 7 (A/D IN) TO 5V *****"
400 '******** STEP 2: READ A/D STATUS REGISTER ****************************
420 S.END=0
430 ST%=INP(PORT%+8)
450 IF (ST% AND &H20)=&H20 THEN S.END=1 ELSE S.END=0
538 '******** STEP 3: SET A/D RANGE ****************
540 FOR I=START% TO STP%
542


PRINT "ENTER RANGE CODE <0 -- 3> FOR CHANNEL ";I;

544

INPUT GR%

546

OUT PORT%+2,I

548

OUT PORT%+1,GR%

549

GAIN%(I)=GR%

550

PRINT

'CHANNEL SETTING
'RANGE SETTING

552 NEXT I
555 '******** STEP 4: SET SCAN CHANNEL RANGE *****************************
560 S.CH.VAL%=STP%*16+START%

'SET SCAN CHANNEL VALUE


562 OUT PORT%+2,S.CH.VAL%
564 R.CH%=INP(PORT%+2)

'READ BACK CHANNEL VALUE

570 IF R.CH% <> S.CH.VAL% THEN PRINT"SET SCAN CHANNEL FAILED!":STOP
600 '******** STEP 5: PERFORM SINGLE A/D CONVERSION **********
620 OUT PORT%+0,0
630 ST%=INP(PORT%+8)
640 IF (ST% AND &H80)=&H80 GOTO 630

'CHECK CONVERSION OK ?

650 DTL%=INP(PORT%+0)
660 DTH%=INP(PORT%+1)
670 ADL%=DTL%\16
680 ADT%=DTH%*16+ADL%
690 CHV%=DTL%-ADL%*16
695 PRINT"A/D READING = ";ADT%
700 PRINT"CURRENT CHANNEL

= ";CHV%;


135

CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN
710 PRINT"NEXT CHANNEL


= ";(ST% AND &HF)

720 PRINT"START SCAN CHANNEL = ";START%
730 PRINT"STOP SCAN CHANNEL = ";STP%
740 PRINT
750 PRINT"PRESS 'SPACE' KEY TO CONTINUE"
760 A$=INKEY$ :IF A$ ="" GOTO 760
770 IF A$=" " GOTO 620
780 END

3.4.4 Thư viện adsapi32.dll
File adsapi32.dll do hãng cung cấp được cài vào thư mục hệ
thống, trong chương trình ứng dụng phải khai sử dụng driver
khai báo các hàm trong dll. Sử dụng các hàm trong thư viện giúp
chương trình mang tính chuyên nghiệp hơn, có thể lập trình
ngắt, DMA trong hệ điều hành Win988, Win2000XP. Vì file
driver (.pas, .h, .bas) khá lớn nên chỉ trình bày một phần nhỏ ở
đây (xem website www.advantech.com).
Đầu tiên phải cài đặt driver vào máy tính thư mục
Advantech\Adsapi\include sẽ chứa các file driver (.pas, .bas,.h)
khai báo các hàm của adsapì.dll (chứa trong windows\system).
Sau khi đã gắn card vào máy tính chạy chương trình Device
installation để cài đặt thông số card vào máy , card sẽ được gắn
một số là DeviceNum. Có thể có nhiều card sử dụng cùng lúc với
các số khác nhau. Khi lập trình cần phải khai báo sử dụng driver,
các hàm được gọi đến kèm theo thông số do driver qui đònh. Cụ
thể tùy theo ngông ngữ lập trình sử dụng. Phần sau mô tả một số
hàm của driver và ví dụ áp dụng
Device Functions
DRV_DeviceOpen

DRV_DeviceClose
DRV_DeviceGetFeatures
DRV_GetErrorMessage
DRV_SelectDevice
DRV_DeviceGetNumOfList
DRV_DeviceGetList
DRV_GetAddress

Analog Input
DRV_AIConfig
DRV_AIGetConfig
DRV_AIBinaryIn
DRV_AIScale
DRV_AIVoltageIn
DRV_MAIConfig
DRV_MAIBinaryIn
DRV_MAIVoltageIn

Analog Output
DRV_AOConfig
DRV_AOBinaryOut
DRV_AOVoltageOut
DRV_AOScale


136

CHƯƠNG 3

Digital In/Out

DRV_DioReadPortByte
DRV_DioWritePortByte
DRV_DioReadBit
DRV_DioWriteBit
DRV_DioGetCurrentDOByte
DRV_DioGetCurrentDOBit

Port I/O Functions
DRV_WritePortByte
DRV_WritePortWord
DRV_ReadPortByte
DRV_ReadPortWord
DRV_outp
DRV_outpw
DRV_intp
DRV_intpw

Các hàm có dạng chung
status = FUNCTION_Name(parameter 1, parameter 2...parameter n)
status là biến 4 byte, nếu hàm thực hiện tốt thì biến status trả về bằng 0, nếu không tốt thì
status<>0
Mở card để dùng
status = DRV_DeviceOpen(DeviceNum,DriverHandle)
Tên
Hướng Loại
Miêu tả
DeviceNum
Input
unsigned long
Số của card do chương trình cài đặt của

advantech quiđònh
DriverHandle output
unsigned long
Con trỏ đến cấu hình card
Đóng card khi không dùng, giải phóng bộ nhớ
status = DRV_DeviceClose(DriverHandle)
Nhận thông báo lỗi tùy theo mã lỗi
status = DRV_GetErrorMessage(ErrorCode,ErrorMsg)
Tên
ErrorCode
DriverHandle

Hướng
Input
output

Loại
unsigned long
con trỏ chỉ đến chuỗi thông báo

Miêu tả
Mã báo sai do driver gởi về
Thông báo sử cố

Liệt kê card
status = DRV_SelectDevice(hCaller, GetModule, DeviceNum, Description)
Tên
hCaller

Hướng

Input

Loại
HWND (windows
handle)

Miêu tả
Specify the Windows handle that is calling
this function.

GetModule
DeviceNum
Description

Input
output
output

bool, true
unsigned long
unsigned char

số của card
miêu tả card

Đặt độ lợi cho chuyển đổi AD
status = DRV_AIConfig(DriverHandle,lpAIConfig)


137


CARD THU THẬP TÍN HIỆU VÀ ĐIỀU KHIỂN
Tên
DriverHandle

Hướng
input

Loại
long

Miêu tả
Do DRV_DevicoOpen trả về

lpAIConfig

input

long pointer trỏ đến record
PT_AIConfig

Qui đònh số kênh AI và độ lợi
kênh

Type PT_AIConfig ‘khai báo cấu trúc kểu Visual Basic
DasChan As Integer
DasGain As Integer
End Type
PT_AIConfig = Record {khai báo cấu trúc kiểu Delphi}
DasChan : Smallint;

DasGain : Smallint;
End;
typedef struct tagPT_AIConfig //khai báo kiểu C
{
USHORT
DasChan; //USHORT :unsigned short
USHORT
DasGain;
} PT_AIConfig, FAR * LPT_AIConfig;
Đọc độ lợi
status = DRV_AIGetConfig(DriverHandle,lpAIGetConfig)
lpAIGetConfig: input/output con trỏû đến PT_AIGetConfig
Type PT_AIGetConfig
buffer As Long
' LPDEVCONFIG_AI
size As Integer
End Type
Đọc kết quả nhò phân của A/D
status = DRV_AIBinaryIn(DriverHandle,lpAIBinaryIn)
lpAIBinaryIn:input/output, con trỏ đến PT_AIBinaryIn
Type PT_AIBinaryIn
chan
As Integer ‘số kênh
TrigMode As Integer ‘ cách kích chuyển đổi
reading As Long
'kết quả nhò phân USHORT far * reading
End Type
Đọc kết quả dạng điện áp
status = DRV_AIVoltageIn(DriverHandle, lpAIVoltageIn)
Type PT_AIVoltageIn

chan
As Integer
gain
As Integer
TrigMode As Integer


×