Professional Documents
Culture Documents
Chương 1
KIẾN TRÚC VÀ HOẠT ĐỘNG CỦA HỆ VI XỬ LÝ /
MÁY TÍNH
Cấp n Máy ảo Mn dùng ngôn Chương trình trong Ln được dịch thành
ngữ máy Ln ngôn ngữ của máy cấp thấp hơn
Cấp 3 Máy ảo M3 dùng ngôn Chương trình trong L3 được dịch thành
ngữ máy L3 ngôn ngữ L2 hay L1
Cấp 2 Máy ảo M2 dùng ngôn Chương trình trong L2 được dịch thành
ngữ máy L2 ngôn ngữ máy L1
Cấp 1 Máy tính số M1 dùng Chương trình trong L1 được thực thi trực
ngôn ngữ máy L1 tiếp bằng các mạch điện tử
Một máy tính số có n cấp có thể xem như có n-1 máy ảo khác nhau, mỗi máy ảo có
một ngôn ngữ máy riêng. Các chương trình viết trên các máy ảo này không thể thực thi
trực tiếp mà phải dịch thành các ngôn ngữ máy cấp thấp hơn. Chỉ có máy thật dùng ngôn
ngữ máy L1 mới có thể thực thi trực tiếp bằng các mạch điện tử. Một lập trình viên sử
dụng máy ảo cấp n không cần biết tất cả các trình dịch này. Chương trình trong máy ảo
cấp n sẽ được thực thi bằng cách dịch thành ngôn ngữ máy cấp thấp hơn và ngôn ngữ máy
này sẽ được dịch thành ngôn ngữ máy thấp hơn nữa hay dịch trực tiếp thành ngôn ngữ
máy L1 và thực thi trực tiếp trên các mạch điện tử.
Cấp 0 chính là phần cứng của máy tính. Các mạch điện tử của cấp này sẽ thực thi
các chương trình ngôn ngữ máy của cấp 1. Trong cấp logic số, đối tượng quan tâm là các
cổng logic. Các cổng này được xây dựng từ một nhóm các transistor.
Cấp 1 là cấp ngôn ngữ máy thật sự. Cấp này có một chương trình gọi là vi chương
trình (microprogram), vi chương trình có nhiệm vụ thông dịch các chỉ thị của cấp 2. Hầu
hết các lệnh trong cấp này là di chuyển dữ liệu từ phần này đến phần khác của máy hay
thực hiện việc một số kiểm tra đơn giản.
Mỗi máy cấp 1 có một hay nhiều vi chương trình chạy trên chúng. Mỗi vi chương
trình xác định một ngôn ngữ cấp 2. Các máy cấp 2 đều có nhiều điểm chung ngay cả các
máy cấp 2 của các hãng sản xuất khác nhau. Các lệnh trên máy cấp 2 được thực thi bằng
cách thông dịch bởi vi chương trình mà không phải thực thi trực tiếp bằng phần cứng.
Cấp thứ 3 thường là cấp hỗn hợp. Hầu hết các lệnh trong ngôn ngữ của cấp máy
này cũng có trong ngôn ngữ cấp 2 và đổng thời có thêm một tập lệnh mới, một tổ chức bộ
nhớ khác và khả năng chạy 2 hay nhiều chương trình song song. Các lệnh mới thêm vào
sẽ được thực thi bằng một trình thông dịch chạy trên cấp 2, gọi là hệ điều hành. Nhiều
lệnh cấp 3 được thực thi trực tiếp do vi chương trình và một số lệnh khác được thông dịch
bằng hệ điều hành (do đó, cấp này là cấp hỗn hợp).
Cấp 4 thật sự là dạng tượng trưng cho một trong các ngôn ngữ. Cấp này cung cấp
một phương pháp viết chương trình cho các cấp 1, 2, 3 dễ dàng hơn. Các chương trình
viết bằng hợp ngữ được dịch sang các ngôn ngữ của cấp 1, 2, 3 và sau đó được thông dịch
bằng các máy ảo hay thực tương ứng.
Cấp 5 bao gồm các ngôn ngữ được thiết kế cho người lập trình nhằm giải quyết
một vấn đề cụ thể. Các ngôn ngữ này được gọi là cấp cao. Một số ngôn ngữ cấp cao như
Basic, C, Cobol, Fortran, Lisp, Prolog, Pascal và các ngôn ngữ lập trình hướng đối tượng
như C++, J++, … Các chương trình viết bằng các ngôn ngữ này thường được dịch sang
cấp 3 hay 4 bằng các trình biên dịch (compiler).
1 40
2 GND VCC 39
3 AD14 AD15 38
4 AD13 A16/S3 37
74LS245 5 AD12 A17/S4 36
VCC 1 6 AD11 A18/S5 35
19 DIR 7 AD10 A19/S6 34
G 8 AD9 BHE/S7 33
9 11 9 AD8 MN/MX 32
8 A8 B8 12 10 AD7 RD 31
7 A7 B7 13 11 AD6 HOLD (RQ/GT0) 30
6 A6 B6 14 12 AD5 HLDA (RQ/GT1) 29
5 A5 B5 15 13 AD4 WR (LOCK) 28
4 A4 B4 16 14 AD3 IO/M (S2) 27
3 A3 B3 17 15 AD2 DT/R (S1) 26
2 A2 B2 18 16 AD1 DEN (S0) 25
A1 B1 17 AD0 ALE (QS0) 24
1 18 NMI INTA (QS1) 23
INT7 INTR TEST
2 19 22
INT6 CLK READY
3 20 21
INT5 GND RESET
4
INT4
8 8086
5
INT3
6
INT2
11
INT1
12
INT0
- DMAC gởi tín hiệu HRQ (Hold Request) đến chân HOLD của CPU để yêu cầu
treo CPU. Tín hiệu này sẽ giữ ở mức cao cho đến hết quá trình trao đổi dữ liệu.
- Sau khi nhận yêu cầu treo, CPU sẽ thực hiện hết chu kỳ bus của m?nh rồi treo
các bus và gởi tín hiệu HLDA (Hold Acknowledge) để báo cho DMAC biết có
thể sử dụng các bus.
- DMAC chuyển dữ liệu từ bộ nhớ đến ngoại vi bằng cách: đưa địa chỉ byte đầu
tiên ra bus địa chỉ và đưa tín hiệu MEMR để đọc 1 byte từ bộ nhớ, kế tiếp
DMAC đưa tín hiệu IOW để ghi dữ liệu ra ngoại vi. Sau đó, DMAC giảm số
byte cần truyền, cập nhật địa chỉ bộ nhớ và lặp lại quá trình cho đến khi hết
byte cần truyền.
Address bus
μP
Data bus
Control bus
CLK
HOLD
HLDA
3. Bus
CPU
Registers Bus hệ thống (system bus)
Bus cục bộ
(local bus)
Đồng xử lý
T1 T2 T3 T4
Clk
Address
bus Địa chỉ
Address
Địa chỉ
bus
Ghi bộ
IOW hay nhớ hay
MEMW I/O
Dữ liệu ra
Data bus
Trong một chu kỳ bus, μP có thể thực hiện đọc I/O, ghi I/O, đọc bộ nhớ hay ghi bộ
nhớ. Các đường address bus và control bus dùng để xác định địa chỉ bộ nhớ hay I/O và
hướng truyền dữ liệu trên data bus.
Chú ý rằng μP điều khiển tất cả các quá trình trên nên bộ nhớ bắt buộc phải cung
cấp được dữ liệu vào lúc MEMR lên mức cao trong trạng thái T4. Nếu không, μP sẽ đọc
dữ liệu ngẫu nhiên không mong muốn trên data bus. Để giải quyết vấn đề này, ta có thể
dùng thêm các trạng thái chờ (wait state).
Truyền theo khối:
Ngoài các chu kỳ đọc/ghi, một số bus truyền dữ liệu đồng bộ còn hỗ trợ truyền dữ
liệu theo khối. Khi bắt đầu thao tác đọc khối, bus master báo cho slave biết số byte cần
được truyền đi, thí dụ truyền con số này đi trong chu kỳ T1, sau đó đáng lẽ truyền đi 1
byte, slave đưa ra trong mỗi chu kỳ 1 byte cho tới khi đủ số byte được thông báo. Như
vậy, khi đọc dữ liệu theo khối, n byte dữ liệu cần n+2 chu kỳ clock chứ không phải 3n
chu kỳ.
Một cách khác để cho truyền dữ liệu nhanh hơn là giảm chu kỳ. Tuy nhiên, giảm
chu kỳ bus dẫn đến khó khăn về mặt kỹ thuật, các tín hiệu truyền trên các đường khác
nhau không phải luôn có cùng tốc độ, dẫn đến hiệu ứng bus skew. Điều quan trọng là thời
gian chu kỳ phải dài hơn so với skew để tránh việc những khoảng thời gian được số hoá
lại trở thành các đại lượng biến thiên liên tục.
3.3. Bus bất đồng bộ( Asynchronous bus)
Bus bất đồng bộ không sử dụng xung clock đồng bộ, chu kỳ của nó có thể kéo dài
tuỳ ý và có thể khác nhau đối với các cặp thiết bị khác nhau. Làm việc với các bus đồng
bộ dễ dàng hơn do nó được định thời một cách gián đoạn , tuy vậy chính đặc điểm này
cũng dẫn đên nhược điểm. Mọi công việc được tiến hành trong khoảng thời gian là bội số
của xung clock, nếu 1 thao tác nào đó của vi xử lý hay bộ nhớ hoàn thành trong 3.1 chu
kỳ thì nó cũng sẽ phải kéo dài trong 4 chu kỳ. Khi đã chọn chu kỳ bus và đã xây dựng bộ
nhớ, I/O card cho bus này thì khó có thể tận dụng những tiến bộ của công nghệ. Chẳng
hạn sau khi đã xây bus với sự định thời như trên, công nghệ mới đưa ra các vi xử lý và bộ
nhớ có thời gian chu kỳ là 100ns chứ không còn là 750ns như cũ, thì chúng vẫn chạy với
tốc độ thấp như các vi xử lý, bộ nhớ loại cũ, bởi vì giao thức bus đòi hỏi bộ nhớ phải đưa
được dữ liệu ra và ổn định trước thời điểm cạnh âm của T3. Nếu có nhiều thiết bị khác
nhau cùng nối với 1 bus, trong đó có thể có một số thiết bị hoạt động nhanh hơn hơn các
thiết bị khác thì cần phải đặt bus hoạt động phù hợp với thiết bị có tốc độ thấp nhất.
Bus bất đồng bộ ra đời nhằm khắc phục những nhược điểm của bus đồng bộ.
Trước hết master phát ra địa chỉ nhớ mà nó muốn truy cập, sau đó phát tín hiệu MEMR
tích cực để xác định cần truy xuất bộ nhớ và yêu cầu quá trình truy xuất là READ để xác
định chiều truyền dữ liệu. Tín hiệu MEMR được đưa ra sau tín hiệu địa chỉ một khoảng
thời gian phụ thuộc tốc độ hoạt động của master. Sau khi 2 tín hiệu này đã ổn định, master
sẽ phát ra tín hiệu MSYN (master synchrization) ở mức tích cực để báo cho slave biết
rằng các tín hiệu cần thiết đã sẵn sàng trên bus, slave có thể nhận lấy. Khi slave nhận
được tín hiệu này, nó sẽ thực hiện công việc với tốc độ nhanh nhất có thể được, đưa dữ
liệu của ô nhớ được yêu cầu lên bus dữ liệu. Khi hoàn thành slave sẽ phát tín hiệu SSYN
(slave synchronization) tích cực.
Address
MEMR
(Control)
MSYN
Data
SSYN
Master nhận được tín hiệu SSYN tích cực thì xác định được dữ liệu của slave đã
sẵn sàng nên thực hiện việc chốt dữ liệu, sau đó đảo các đường địa chỉ cũng như các tín
hiệu MEMR và MSYN . Khi slave nhận được tín hiệu MSYN không tích cực, nó xác
định kết thúc chu kỳ và đảo tín hiệu SSYN làm bus trở lại trạng thái ban đầu, mọi tín hiệu
đều không tích cực, chờ bus master mới.
Trên giản đồ thời gian của bus bất đồng bộ, ta sử dụng mũi tên để thể hiện nguyên
nhân và kết quả. MSYN tích cực dẫn đến việc truyền dữ liệu ra bus dữ liệu và đồng thời
cũng dẫn đến việc slave phát ra tín hiệu SSYN tích cực, đến lượt mình tín hiệu SSYN lại
gây ra sự đảo mức của các đường địa chỉ, MEMR và MSYN . Cuối cùng sự đảo mức của
MSYN lại gây ra sự đảo mức tín hiệu SSYN và kết thúc chu kỳ. Tập các tín hiệu phối
hợp với nhau như vậy được gọi là bắt tay toàn phần (full handshake), chủ yếu gồm 4 tín
hiệu sau:
- MSYN tích cực.
- SSYN tích cực để đáp lại tín hiệu MSYN .
- MSYN được đảo để đáp lại tín hiệu SSYN (tích cực).
- SSYN được đảo để đáp lại tín hiệu MSYN không tích cực.
Ta có thể nhận thấy bắt tay toàn phần là độc lập thời gian, mỗi sự kiện được gây ra
bởi 1 sự kiện trước đó chứ không phải bởi xung clock. Nếu 1 cặp master-slave nào đó
hoạt động chậm thì cặp master-slave kế tiếp không hề bị ảnh hưởng.
Tuy ưu điểm của bus bất đồng bộ rất rõ ràng, nhưng trong thực tế phần lớn các bus
đang sử dụng là loại đồng bộ. Nguyên nhân là các hệ thống sử dụng bus đồng bộ dễ thiết
kế hơn. Vi xử lý chỉ cần chuyển các mức tín hiệu cần thiết sang trạng thái tích cực là bộ
nhớ đáp ứng ngay, không cần tín hiệu phản hồi. Chỉ cần các chọn phù hợp thì mọi hoạt
động đều trôi chảy, không cần phải bắt tay.
3.4. Xử lý ngắt
Ở trên, ta chỉ khảo sát các chu kỳ bus thông thường, trong đó master nhận hay gởi
thông tin từ / đến slave. Một ứng dụng quan trọng nữa của bus là dùng để xử lý ngắt. Khi
CPU ra lệnh cho thiết bị I/O làm một việc gì đó, nó thường chờ đợi tín hiệu ngắt do thiết
bị I/O phát ra khi hoàn thành công việc được CPU yêu cầu. Khi nhận được tín hiệu ngắt,
CPU sẽ đáp ứng ngay, có thể nhận dữ liệu do thiết bị I/O truyền về, hay gởi tiếp dữ liệu ra
thiết bị I/O, hay CPU sẽ sử dụng bus cho một thao tác khác…. Như vậy chính ngắt phát ra
tín hiệu yêu cầu sử dụng bus.
Vì có thể nhiều thiết bị ngoại vi cùng phát ra ngắt, cho nên cần có 1 cơ chế phân
xử giống như đối với các bus thông thường. Giải pháp thường dùng là gán các mức độ ưu
tiên cho các thiết bị và sử dụng 1 arbiter tập trung để trao quyền ưu tiên cho các thiết bị
quan trọng thường xuyên được sử dụng. Hiện trên thị trường có những chip điều khiển
ngắt được tiêu chuẩn hóa và được sử dụng rộng rãi là chip 8259A. Có thể nối 8 chip điều
khiển I/O tới các đầu IRx (Interrupt request) của 8259A. Khi có 1 thiết bị nào đó muốn
ngắt, nó đặt mức tích cực lên chân Irx, 8259A nhận được tín hiệu tích cực ở 1 hay một số
đầu vào Irx thì sẽ đặt mức tích cực lên đầu dây INT. Tín hiệu INT sẽ truyền trực tiếp đến
chân Interrupt của CPU. Khi CPU có thể xử lý được ngắt, nó gởi lại 1 tín hiệu chấp nhận
ngắt cho 8259A. Lúc này, CPU chờ 8259A chỉ ra I/O nào yêu cầu ngắt, bằng cách gởi số
hiệu của I/O đó lên bus dữ liệu (D0-D7) để đi đến CPU. Sau đó, phần cứng CPU sẽ sử
dụng con số đó để tính chỉ số trong 1 bảng con trỏ -bảng vector ngắt (interrupt vector) để
tìm địa chỉ chương trình con, cho chạy chương trình này để phục vụ ngắt. Các chương
trình con này gọi là chương trình con xử lý ngắt.
ASYNC : chọn chế độ làm việc cho tín hiệu RDY. Nếu ASYNC = 1, tín hiệu
RDY có ảnh hưởng đến tín hiệu READY cho đến khi có xung âm của xung clock. Ngược
lại thì RDY chỉ ảnh hưởng khi xuất hiện xung âm.
X1,X2: ngõ vào của thạch anh, dùng để tạo xung chuẩn cho hệ thống.
18 1
17 VCC CSY NC 2
16 X1 PCLK 3
15 X2 AEN1 4
14 ASY NC RDY 1 5
13 EFI READY 6
12 F/C RD2 7
11 OSC AEN2 8
10 RES CLK 9
RESET GND
Vcc
8284
19 10
20 A0 OUT0 13
A1 OUT1 17
11 OUT2
14 G0 8
16 G1 D0 7
G2 D1 6
9 D2 5
15 CLK0 D3 4
18 CLK1 D4 3
CLK2 D5 2
22 D6 1
23 RD D7
21 WR
CS
8253
OUT0
D7 ÷ D0 Đệm dữ Bộ đếm
liệu 0 CLK0
GATE0
RD OUT1
Điều Bộ đếm
BUS NỘI
WR khiển 1 CLK1
A1 đọc/ghi GATE1
A0
CS
OUT2
Thanh Bộ đếm
ghi từ 2 CLK2
điều GATE2
khiển
G0 ÷ G2 (Gate): cho phép hay cấm các bộ đếm hoạt động ( =1: cho phép, =0:
cấm).
PIT 8253 có tất cả 5 chế độ đếm tùy thuộc vào giá trị trong thanh ghi điều khiển.
PIT 8253 có 3 bộ đếm lùi 16 bit có thể lập trình và độc lập với nhau. Mỗi bộ đếm
có tín hiệu xung clock riêng (8254 tương tự như 8253 nhưng có thêm lệnh đọc thanh ghi
từ điều khiển CWR).
Các chế độ đếm:
Chế độ 0 (Interrupt on Terminal Count): tín hiệu ngõ ra ở mức thấp cho tới khi bộ
đếm tràn thì sẽ chuyển lên mức cao.
Chế độ 1 (Programmable Monoflop): tín hiệu ngõ ra chuyển xuống mức thấp tại
cạnh âm của xung clock đầu tiên và sẽ chuyển lên mức cao khi bộ đếm kết thúc.
Chế độ 2 (Rate Generator): tín hiệu ngõ ra xuống mức thấp trong chu kỳ đầu tiên
và sau đó chuyển lên mức cao trong các chu kỳ còn lại.
Chế độ 3 (Square-Wave Generator): tương tự như chế độ 2 nhưng xung ngõ ra là
sóng vuông khi giá trị đếm chẵn và sẽ thêm một chu kỳ ở mức cao khi giá trị đếm lẻ.
Chế độ 4 (Software-triggered Pulse): giống như chế độ 2 nhưng xung Gate không
khởi động quá trình đếm mà sẽ đếm ngay khi số đếm ban đầu được nạp. Ngõ ra ở mức
cao để đếm và xuống mức thấp trong chu kỳ xung đếm. Sau đó, ngõ ra sẽ trở lại mức cao.
Chế độ 5 (Hardware-triggered Pulse): giống như chế độ 2 nhưng xung Gate không
khởi động quá trình đếm mà được khởi động bằng cạnh dương của xung clock ngõ vào.
Ngõ ra ở mức cao và xuống mức thấp sau một chu kỳ clock khi quá trình đếm kết thúc.
4.4. Chip điều khiển ngắt ưu tiên PIC 8259A (Priority Interrupt Controller)
18 11
19 IR0 D0 10
20 IR1 D1 9
21 IR2 D2 8
22 IR3 D3 7
23 IR4 D4 6
24 IR5 D5 5
25 IR6 D6 4
IR7 D7
27 12
A0 CAS0 13
26 CAS1 15
3 INTA CAS2
2 RD 16
1 WR SP/EN
CS 17
INT
8259A
INTA INT
Data bus
buffer Control logic
IR7
INTERNAL BUS
CS
CAS0
Cascade
CAS1
buffer / IMR (Interrupt Mask Register)
CAS2 comparator
SP / EN
18 11 18 11 1 40
19 IR0 D0 10 19 IR0 D0 10 2 GND VCC 39
20 IR1 D1 9 20 IR1 D1 9 3 AD14 AD15 38
21 IR2 D2 8 21 IR2 D2 8 4 AD13 A16/S3 37
22 IR3 D3 7 22 IR3 D3 7 5 AD12 A17/S4 36
23 IR4 D4 6 23 IR4 D4 6 6 AD11 A18/S5 35
24 IR5 D5 5 24 IR5 D5 5 7 AD10 A19/S6 34
25 IR6 D6 4 25 IR6 D6 4 8 AD9 BHE/S7 33
IR7 D7 IR7 D7 9 AD8 MN/MX 32
27 27 10 AD7 RD 31
A0 1 A0 1 11 AD6 HOLD (RQ/GT0) 30
CS 3 CS 3 12 AD5 HLDA (RQ/GT1) 29
RD 2 RD 2 Vcc 13 AD4 WR (LOCK) 28
12 WR 16 12 WR 16 14 AD3 IO/M (S2) 27
13 CAS0 SP/EN 17 13 CAS0 SP/EN 17 15 AD2 DT/R (S1) 26
15 CAS1 INT 26 15 CAS1 INT 26 16 AD1 DEN (S0) 25
CAS2 INTA CAS2 INTA 17 AD0 ALE (QS0) 24
18 NMI INTA (QS1) 23
8259A - Slave 8259A - Master 19 INTR TEST 22
20 CLK READY 21
GND RESET
8086
4.5. Chip điều khiển truy nhập bộ nhớ trực tiếp DMAC 8237 (Direct Memory
Access Controller)
DMAC 8237 có thể thực hiện truyền dữ liệu theo 3 kiểu: kiểu đọc (từ bộ nhớ ra
thiết bị ngoại vi), kiểu ghi (từ thiết bị ngoại vi đến bộ nhớ) và kiểu kiểm tra.
32 30
33 A0 DB0 29
34 A1 DB1 28
35 A2 DB2 27
37 A3 DB3 26
38 A4 DB4 23
39 A5 DB5 22
40 A6 DB6 21
A7 DB7
12 25
CLK DAK0 24
19 DAK1 14
18 DRQ0 DAK2 15
17 DRQ1 DAK3
16 DRQ2 3
DRQ3 MEMR 4
36 MEMW
7 EOP 9
1 HLDA AEN 8
2 IOR ASTB 10
6 IOW HRQ
13 READY
5 RESET
11 VX
CS
8237
Command
MEMW control
MEMR
Write buffer Read buffer
IOW
A8 – A15
IOR
D0 – D1
DB0 – DB7
DRQ0 – DRQ3 Command
RD I/O buffer
Priority encoder
DACK0 – DACK3
and rotating
Mask
prority logic
HLDA
R/W Status Temp
HRQ Request Mode
IOR , IOW (Input, Output): sử dụng trong các chu kỳ đọc và ghi
EOP (End Of Process)(Input,Output): bắt buộc DMAC kết thúc quá trình DMA
nếu là ngõ vào hay dùng để báo cho một kênh biết là dữ liệu đã chuyển xong
(Terminal count – TC), thường dùng như yêu cầu ngắt để CPU kết thúc quá trình
DMA.
A0 – A3 (Input, Output): chọn các thanh ghi trong 8237A khi lập trình hay dùng để
chứa 4 bit địa chỉ thấp.
A4 – A7 (Output): chứa 4 bit địa chỉ
HRQ (Hold Request)(Output): tín hiệu yêu cầu treo đến CPU
DACK0 – DACK3 (DMA Acknowledge)(Output): tín hiệu trả lời yêu cầu DMA cho
các kênh.
AEN (Output): cho phép lấy địa chỉ vùng nhớ cần trao đổi
ADSTB (Address Strobe)(Output): chốt các bit địa chỉ cao A8 – A15 chứa trong
các chân DB0 – DB7
MEMR , MEMW (Output): dùng để đọc / ghi bộ nhớ.
Các thanh ghi nội:
Các thanh ghi nội trong DMAC 8237A được truy xuất nhờ các bit địa chỉ thấp A0
– A3.
Bit địa chỉ Địa
Chọn chức năng R/W?
A3 A2 A1 A0 chỉ
0 0 0 0 X0 Thanh ghi địa chỉ bộ nhớ kênh 0 R/W
0 0 0 1 X1 Thanh ghi đếm từ kênh 0 R/W
0 0 1 0 X2 Thanh ghi địa chỉ bộ nhớ kênh 1 R/W
0 0 1 1 X3 Thanh ghi đếm từ kênh 1 R/W
0 1 0 0 X4 Thanh ghi địa chỉ bộ nhớ kênh 2 R/W
0 1 0 1 X5 Thanh ghi đếm từ kênh 2 R/W
0 1 1 0 X6 Thanh ghi địa chỉ bộ nhớ kênh 3 R/W
0 1 1 1 X7 Thanh ghi đếm từ kênh 3 R/W
1 0 0 0 X8 Thanh ghi trạng thái / lệnh R/W
1 0 0 1 X9 Thanh ghi yêu cầu W
1 0 1 0 XA Thanh ghi mặt nạ cho một kênh W
1 0 1 1 XB Thanh ghi chế độ W
1 1 0 0 XC Xóa flip-flop đầu/cuối W
1 1 0 1 XD Xóa toàn bộ các thanh ghi / đọc thanh ghi tạm W/R
1 1 1 0 XE Xóa thanh ghi mặt nạ W
1 1 1 1 XF Thanh ghi mặt nạ W
Địa chỉ các thanh ghi nội dùng ghi / đọc địa chỉ:
Kênh IOR IOW A3 A2 A1 A0 Thanh ghi R/W?
Mạch 8273A-5 chứa 4 kênh trao đổi dữ liệu DMA với mức ưu tiên lập trình được.
8237A-5 có tốc độ truyền 1 MBps cho mỗi kênh và 1 kênh có thể truyền 1 mảng có độ dài
64 KB. Để có thể sử dụng mạch DMAC 8237A, ta cần tạo tín hiệu điều khiển như sau:
Vcc 2
3 1A 1Y
4
IOR
5 1B 7
6 2A
2B
2Y
IOW
RD
11 9
10 3A
3B
3Y MEMR
14 12
WR 13 4A 4Y
MEMW
4B
AEN 15
G
1
A/B
IO/ M 74LS257
Hình 1.19 – Tín hiệu điều khiển cho hệ thống làm việc với DMAC 8237A
Tín hiệu AEN từ 8237A dùng để cấm các tín hiệu điều khiển từ CPU khi DMAC
đã nắm quyền điều khiển bus.
4.6. Chip điều khiển màn hình CRTC 6845 (Cathode Ray Tube Controller)
RST (Reset): khởi động lại 6845.
MA0 ÷ MA13 (Memory Address): 14 địa chỉ nhớ cho RAM màn hình.
DE (Display Enable): cho phép (=1) hay không (=0) các tín hiệu điều khiển và địa
chỉ vùng hiện lên màn hình.
LPSTD (Light Pen Strobe): lưu trữ địa chỉ hiện hành của RAM màn hình trong
thanh ghi bút sáng. CPU đọc thanh ghi và xác định vị trí bút sáng trên màn hình.
CURSOR: vị trí con trỏ đã quét (=1) hay chưa (=0).
33 4
32 D0 MA0 5
31 D1 MA1 6
30 D2 MA2 7
29 D3 MA3 8
28 D4 MA4 9
27 D5 MA5 10
26 D6 MA6 11
D7 MA7 12
21 MA8 13
CLK MA9 14
23 MA10 15
3 E MA11 16
2 LPSTD MA12 17
24 RST MA13
22 RS 38
25 R/W RA0 37
CS RA1 36
RA2 35
RA3 34
RA4
19
CURSOR 18
DE 39
HS 40
VS
6845
8087:
8087 gồm một đơn vị điều khiển (CU – Control Unit) dùng để điều khiển bus và
một đơn vị số học (NU – Numerical Unit) để thực hiện các phép toán dấu chấm động
trong các mạch tính lũy thừa (exponent module) và mạch tính phần định trị (mantissa
module). Khác với 8086, thay vì dùng các thanh ghi rời rạc là một ngăn xếp thanh ghi.
Đơn vị điều khiển nhận và giải mã lệnh, dọc và ghi các toán hạng, chạy các lệnh
điều khiển riêng của 8087. Do đó, CU có thể đồng bộ với CPU trong khi NU đang thực
hiện các công việc tính toán. CU bao gồm bộ điều khiển bus, bộ đệm dữ liệu và hàng
lệnh.
Bus dữ liệu
Đệm dữ liệu
8086
Ngăn xếp thanh ghi có tất cả 8 thanh ghi từ R0 ÷ R7, mỗi thanh ghi dài 80 bit trong
đó bit 79 là bit dấu, bit 64 ÷ 78 dùng cho số mũ và phần còn lại là phần định trị. Dữ liệu
truyền giữa các thanh ghi này được thực hiện rất nhanh do 8087 có độ rộng bus dữ liệu là
84 bit và không cần phải biến đổi định dạng.
Ngay sau khi reset PC, bộ đồng xử lý kiểm tra xem nó có được nối với PC hay
không bằng các đường BHE /S7. 8087 sẽ điều chỉnh độ dài của hàng lệnh cho phù hợp với
CPU (nếu dùng 8086 thì độ dài là 6 byte).
8087 có một thanh ghi trạng thái là thanh ghi từ thẻ (tag word) gồm các cặp bit
Tag0 ÷ Tag7 để lưu trữ các thông tin liên quan đến nội dung của các thanh ghi R0 ÷ R7
để cho phép thực hiện một số tác vụ nhanh hơn. Mỗi thanh ghi từ thẻ có 2 bit xác định 4
giá trị khác nhau của các thanh ghi Ri.
Tag = 00: xác định
Tag = 01: zero
Tag = 10: NAN, giá trị bất thường
Tag = 11: rỗng
80287:
S0
S1
36 34
38 D0 A0 33
15 10 40 D1 A1 32
16 S0 CLK 13 42 D2 A2 28
S1 PCLK 44 D3 A3 27
7 4 2 23 46 D4 A4 26
X1 READY S0 S0 D0 D5 A5
8 12 1 22 48 25
X2 RESET S1 S1 D1 D6 A6
21 50 24
1 32 D2 20 37 D7 A7 23
17 ARDY 37 CLK D3 19 39 D8 A8 22
5 AYEN CLK286 D4 18 41 D9 A9 21
6 EFI 29 D5 17 43 D10 A10 20
11 F/C 31 CMD0 D6 16 45 D11 A11 19
2 RES 3 CMD1 D7 15 47 D12 A12 18
3 SRDY 39 COD/INTA D8 14 49 D13 A13 17
SYEN 38 CKM D9 12 51 D14 A14 16
34 HLDA D10 11 D15 A15 15
82284 33 NPS1 D11 8 52 A16 14
27 NPS2 D12 7 CAP A17 13
28 NPRD D13 6 31 A18 12
19 13 36 NPWR D14 5 CLK A19 11
S0 S0 D15 A20
3 82288 INTA 12 40 PEACK 54 10
S1 S1 IORC READY BUSY A21
11 35 26 53 8
18 IOWC RESET ERROR 25 64 ERROR A22 7
M/IO 8 BUSY 24 57 HOLD A23
2 MRDC 9 PEREQ 59 INTR 1
CLK MWTC 61 NMI BHE 66
15 5 80287 63 PEREQ COD/INTA 65
14 CEN/AEN ALE 16 29 READY HLDA 68
7 CENL DEN 17 RST LOCK 67
6 CMDLY DT/R 4 M/IO 6
1 MB MCE PEACK 5
READY S0 S0
4
S1 S1
80286
15 10
16 S0 CLK 13
S1 PCLK
7 4
8 X1 READY 12
X2 RESET
1
17 ARDY
5 AYEN
6 EFI
11 F/C
2 RES
3 SRDY
82284
Do 80286 có chế độ mạch bảo vệ nên mạch ghép nối giữa 80286 và 80287 được
thiết kế khác 8087 ở đơn vị điều khiển CU. Bộ đồng xử lý ở đây không thực hiện truy
xuất bộ nhớ trực tiếp. Để truy xuất được bộ nhớ, 80287 không những cần một đơc vị định
địa chỉ đơn giản của nó mà còn phải được tăng cường thêm chức năng quản lý bộ nhớ của
80286. Cấu trúc bên trong của 80287 cũng tương tự như 8087, chỉ có đơn vị bus thay đổi
cho phù hợp với 80286. Khác vơi 8087, 80287 hoạt động không đồng bộ với CPU nên có
thể dùng xung clock riêng.
80387:
Ưu điểm của 80387 so với 80287 là có thể thực hiện các phép toán số học nhanh
hơn. No có bus dữ liệu 32 bit như CPU và sử dụng công nghệ CMOS nên công suất tiêu
thụ thấp hơn.
5. Bộ thanh ghi
μP 8086/8088 có tất cả 14 thanh ghi nội. Các thanh ghi này có thể phân loại như
sau:
- Thanh ghi dữ liệu (data register)
- Thanh ghi chỉ số và con trỏ (index & pointer register)
- Thanh ghi đoạn (segment register)
- Thanh ghi trạng thái và điều khiển (status & control register)
5.1. Các thanh ghi dữ liệu
Các thanh ghi dữ liệu gồm có các thanh ghi 16 bit AX, BX, CX và DX trong đó
nửa cao và nửa thấp của mỗi thanh ghi có thể định địa chỉ một cách độc lập. Các nửa
thanh ghi này (8 bit) có tên là AH và AL, BH và BL, CH và CL, DH và DL.
Các thanh ghi này được sử dụng trong các phép toán số học và logic hay trong quá
trình chuyển dữ liệu.
Bảng 2.8:
Thanh ghi cờ (Flag register) hay từ trạng thái 16 bit chứa 3 bit điều khiển (TF, IF
và DF) và 6 bit trạng thái (OF, SF, ZF, AF, PF và CF) còn các bit còn lại mà 8086/8088
không sử dụng thì không thể truy xuất được.
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
X X X X OF DF IF TF SF ZF X AF X PF X CF
- OF (Overflow - tràn): OF = 1 xác định tràn số học, xảy ra khi kết quả vượt ra
ngoài phạm vi biểu diễn
- DF (Direction- hướng): xác định hướng chuyển string, DF = 1 khi μP làm việc
với string theo thứ tự từ phải sang trái.
- IF (Interrupt - ngắt): cho phép hay cấm các interrupt có mặt nạ
- TF (Trap - bẫy): đặt μP vào chế độ từng bước, dùng cho các chương trình gỡ
rối (debugger).
- SF (Sign - dấu): dùng để chỉ các kết quả số học là số dương (SF = 0) hay âm
(SF = 1).
- ZF (Zero): = 1 nếu kết quả của phép toán trước là 0.
- AF (Auxiliary – nhớ phụ): dùng trong các số thập phân để chỉ nhớ từ nửa byte
thấp hay mượn từ nửa byte cao.
- PF (Parity): PF = 1 nếu kết quả của phép toán là có tổng số bit 1 là chẵn (dùng
để kiểm tra lỗi truyền dữ liệu)
- CF (Carry): CF = 1 nếu có nhớ hay mượn từ bit cao nhất của kết quả. Cờ này
cũng dùng cho các lệnh quay.
Chương 2
NGẮT VÀ SỰ KIỆN
1. Khái niệm
Ngắt (interrupt) là quá trình dừng chương trình chính đang chạy để ưu tiên thực hiện
một chương trình khác, chương trình này được gọi là chương trình phục vụ ngắt (ISR –
Interrupt Service Routine). ISR hoàn toàn giống với một chương trình bình thường trên máy
tính, nghĩa là nó có khả năng truy xuất đến tất cả các lệnh ngôn ngữ máy của µP. Tuy nhiên
cuối ISR sẽ kết thúc bằng lệnh IRET (Interrupt Return) để µP tiếp tục thực hiện lệnh đã kết
thúc trước đây.
Các nguyên nhân dẫn đến ngắt là:
- Bản thân chương trình đang thực hiện bị lỗi, ví dụ như: chia cho 0, …
- Do tác động của thiết bị ngoại vi, ví dụ như: thực hiện lệnh in nhưng máy in lỗi,
ghi dữ liệu vào đĩa nhưng không có đĩa, …
- Do lập trình viên chủ động gọi các ngắt có sẵn.
Một cách đơn giản, chúng ta có thể xem ngắt như là quá trình gọi chương trình con
nhưng các chương trình con này được tạo ra sẵn trong máy tính và quá trình gọi này có thể
xảy ra tại thời điểm không xác định trước.
Sự kiện (Event) là một tác động lên một đối tượng trong môi trường Windows. Khi
có một sự kiện xảy ra, Windows sẽ gởi thông điệp (message) đến đối tượng. Các sự kiện
thường xảy ra là:
- Sự kiện chuột: Click, Double Click, …
- Sự kiện bàn phím: nhấn phím, nhả phím, …
- Sự kiện cửa sổ: Activate, Load, Unload, …
Trong các quá trình ngắt, ta phân biệt thành 2 loại: ngắt cứng và ngắt mềm. Ngắt
mềm là ngắt được gọi bằng một lệnh trong chương trình ngôn ngữ máy. Ngắt mềm được
thục hiện trên hợp ngữ thông qua lệnh INT. Đối với các ngôn ngữ bậc cao hơn, vẫn cho
phép thực hiện gọi ngắt nhưng phải được biên dịch thành lệnh INT trong hợp ngữ rồi mời
thực hiện.
Khác với ngắt mềm, ngắt cứng không được khởi động bên trong máy tính mà do các
linh kiện điện tử tác đông lên hệ thống. Ngắt cứng cũng được chia thành 2 loại: ngắt che
được và ngắt không che được. Ngắt che được là ngắt có thể cho phép hay không cho phép
thực thi bằng phần mềm thông qua cờ ngắt IF (Interrupt Flag): lệnh CLI (Clear Interrupt
Flag) sẽ cấm ngắt và lệnh STI (Set Interrupt Flag) sẽ cho phép các ngắt này hoạt động.
Các loại ngắt khác nhau có thể mô tả như sau:
Ngắt
Khi thực hiện lệnh gọi một ngắt nào đó, chương trình con phục vụ cho ngắt sẽ được
gọi. Để thực hiện các ngắt tương ứng, địa chỉ thực hiện các chương trình con phục vụ ngắt
được đặt trong một bảng, gọi là bảng vector ngắt.
Bảng vector ngắt gồm có 256 phần tử, mỗi phần tử gồm 4 byte ứng với 256 ngắt (từ
ngắt 0 đến ngắt 0FFh). Mỗi phần tử trong bảng vector ngắt chứa 2 địa chỉ: địa chỉ thanh ghi
đoạn đưa vào CS và địa chỉ offset của chương trình phục vụ ngắt đưa vào IP.
Khi có một quá trình ngắt xảy ra, CPU sẽ tìm địa chỉ bắt đầu của chương trình ngắt
được chứa trong bảng vector ngắt theo số thự tự ngắt. Do một phần tử trong bảng vector
ngắt chiếm 4 byte nên để tìm giá trị địa chỉ trong bảng vector ngắt, ta chỉ cần nhân số thứ tự
ngắt với 4.
Danh sách các ngắt mô tả như sau:
Để thực hiện chặn một ngắt, ta cần thực hiện như sau:
;*******************************************************************************
;*
;* LAB6-2.ASM - Assembler Laboratory ZMiTAC
*
;*
;* Sample program that converts lowercase to uppercase when key pressed
*
;*
;*******************************************************************************
.MODEL SMALL
.STACK 100h
.CODE
;*******************************************************************************
;* Variables
;*******************************************************************************
old_proc dd 0 ; address of original interrupt handler
dot_flag db 0 ; dot flag
;*******************************************************************************
;* 09h interrupt handler
;*******************************************************************************
segment_kb EQU 40h ; beggining of keyboard data segment
wsk_kb EQU 1Ch ; offset of pointer to keyboard buffer
kb_buf_begin EQU 80h ; offset of address of begining of the
buffer
kb_buf_end EQU 82h ; offset of address of end of the buffer
;-------------------------------------------------------------------------------
; Calling of original interrupt handler
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; Read the character and check ASCII code
;-------------------------------------------------------------------------------
mov bx,ds:[wsk_kb] ; actual pointer to BX
mov ax,ds:[kb_buf_begin] ; buffer beggining to AX
cmp bx,ax ; is the beggining of the buffer ?
jne mid_buf
mov bx,ds:[kb_buf_end] ; last character is at the end of the
buffer
mid_buf:
mov ax,ds:[bx-2] ; read last character
check_lowercase:
cmp al,'z' ; compare with 'z'
ja keys_end ; end if above
cmp al,'a' ; compare with 'a'
jb keys_end ; end if less
cmp dot_flag,0 ; was dot pressed?
je keys_end ; end if not
;-------------------------------------------------------------------------------
; Change lowercase to uppercase
;-------------------------------------------------------------------------------
sub al,'a'-'A' ; sub difference between cases
mov ds:[bx-2],ax
mov dot_flag,0 ; uppercase - clear flag
jmp keys_end ; return
dot_found:
mov dot_flag,1 ; set flag
jmp keys_end ; return
;-------------------------------------------------------------------------------
; Pop registers and return from interrupt
;-------------------------------------------------------------------------------
keys_end:
pop ds
pop dx
pop bx
pop ax
;*******************************************************************************
;* Main program
;*******************************************************************************
;-------------------------------------------------------------------------------
; Get interrupt
;-------------------------------------------------------------------------------
start proc
mov ah,35h ; function 35h - read handler address
mov al,09h ; of interrupt 09h
int 21h
mov word ptr old_proc,bx ; store 32-bit address
mov word ptr old_proc+2,es ; of original interrupt handler
push cs
pop ds ; handler code segment to DS
mov dx,offset keys ; offset of handler address to DX
mov ah,25h ; function 25h - set new handler
mov al,09h ; of interrupt 09h
int 21h
mov dx,word ptr old_proc+2
mov ds,dx
mov dx,word ptr old_proc
mov ah,25h ; function 25h - set new adress
mov al,60h ; of original interrupt handler
int 21h ; 60h instead of 09h
;-------------------------------------------------------------------------------
; Main loop
;-------------------------------------------------------------------------------
looping:mov ah,08h ; function 08h - read character
int 21h ; ASCII code is returned in AL
cmp al,1Bh ; ESC
je ending ; if ESC end of the loop
mov dl,al ; not ESC - move char to DL
mov ah,02h ; function 02h - display character
int 21h ; ASCII code of char in DL
jmp looping
;-------------------------------------------------------------------------
ending: mov dx,word ptr old_proc+2
mov ds,dx
mov dx,word ptr old_proc
mov ah,25h ; function 25h - set old handler
mov al,09h ; of interrupt 09h
int 21h
phân loại dựa theo loại sự kiện bị chặn. Để gọi được hàm lọc, ta cần phải thực hiện quá trình
gắn (attach) vào quá trình câu móc (như câu móc bàn phím). Việc gắn một hay nhiều hàm
lọc vào một quá trình câu móc được gọi là thiết lập (setting) một quá trình câu móc.
Nếu một quá trình câu móc có nhiều hơn một hàm lọc, Windows sẽ duy trì một chuỗi
các hàm lọc trong đó hàm được cài đặt vào gần nhất sẽ nằm ở đầu chuỗi và hàm cài đặt lâu
nhất sẽ nằm ở cuối chuỗi. Nếu sự kiện xảy ra làm khởi động quá trình câu móc, Windows sẽ
gọi hàm lọc đầu tiên trong chuỗi. Quá trình câu móc vào một sự kiện được sử dụng bằng
hàm SetWindowsHookEx và hàm UnhookWindowsHookEx dùng để xóa bỏ hàm lọc khỏi
quá trình.
Cơ chế câu móc cung cấp các khả năng mạnh mẽ cho một ứng dụng Windows. Các
ứng dụng này có thể dùng quá trình câu móc để:
- Xử lý và thay đổi các thông điệp gởi đến các dialog box, message box, scroll bar
và menu của một ứng dụng (WH_MSGFILTER).
- Xử lý và thay đổi các thông điệp gởi đến các dialog box, message box, scroll bar
và menu của hệ thống (WH_SYSMSGFILTER).
- Xử lý và thay đổi các thông điệp của hệ thống bất cứ khi nào hàm GetMessage
hay PeekMessage được gọi (WH_GETMESSAGE).
- Xử lý và thay đổi các thông điệp của hệ thống bất cứ khi nào hàm SendMessage
được gọi (WH_CALLWNDPROC).
- Ghi hay thực hiện lại các sự kiện bàn phím và chuột (WH_JOURNALRECORD,
WH_JOURNALPLAYBACK).
- Xử lý, sửa đổi hay cấm sự kiện chuột (WH_MOUSE).
- Xử lý, sửa đổi hay cấm sự kiện bàn phím (WH_KEYBOARD).
- Đáp ứng với các hoạt động nào đó của hệ thống, có khả năng phát triển CBT
(computer-based training) cho ứng dụng (WH_CBT).
- Cấm các hàm lọc khác (WH_DEBUG).
Các ứng dụng thường dùng quá trình câu móc để:
- Dùng phím F1 để hỗ trợ cho menu, dialog box và message box
(WH_MSGFILTER).
- Lưu lại quá trình thực hiện khi nhấn phím hay chuột (thường dùng cho macro). Ví
dụ như Windows Recorder sử dụng hook để hỗ trợ chức năng record và playback
(WH_JOURNALRECORD, WH_JOURNALPLAYBACK).
- Quản lý thông điệp để xác nhận thông điệp được gởi tới cửa sổ hay được tạo ra
(WH_GETMESAGE, WH_CALLWNDPROC).
- Mô phỏng ngõ vào chuột và bàn phím (WH_JOURNALPLAYBACK). Quá trình
câu móc là phương pháp tin cậy để thực hiện hoạt động này. Nếu ta thực hiện mô
phỏng bằng cách gởi thông điệp, Windows sẽ không thực hiện cập nhật trạng thái
của bàn phím hay chuột dẫn đến các hoạt động không mong muốn. Nếu quá trình
câu móc thực hiện điều này, nó sẽ được xử lý giống như sự kiện chuột hay bàn
phím xảy ra. Ví dụ như Microsoft Excel dùng hook để thực hiện macro
SENDKEYS.
- Cung cấp khả năng CBT cho ứng dụng thực hiện trên môi trường Windows
(WH_CBT) làm cho quá trình phát triển ứng dụng CBT dễ dàng hơn.
Phạm vi sử dụng: Một trong những đặc trưng của Win32 Hook là cho phép chỉ định
quá trình câu móc là hệ thống hay ở dạng luồng (thread). Hook hệ thống cho phép tác động
đến các cửa sổ khác trong hệ thống còn hook luồng chỉ cho phép tác động đến cửa sổ hiện
hành.
Cách thức sử dụng quá trình câu móc:
Để sử dụng quá trình câu móc, ta cần phải biết:
- Làm thế nào dùng hàm câu móc của Windows để thêm vào hay xóa bỏ một hàm
lọc trong chuỗi hàm xử lý của một quá trình câu móc.
- Cần phải thực hiện các hoạt động gì để cài đặt một hàm lọc.
- Có thể thực hiện được hàm câu móc nào và chúng có thể làm được gì, gởi những
thông tin nào.
WH_CALLWNDPROCRET: cài đặt hàm câu móc quản lý thông điệp sau khi cửa sổ
đã xử lý. Loại này cho phép thay đổi giá trị trả về của thông điệp.
WH_MSGFILTER: cài đặt hàm câu móc quản lý các thông điệp được tạo ra giống
như có một sự kiện của dialog box, message box, menu hay scroll bar.
WH_GETMESSAGE: cài đặt hàm câu móc quản lý các thông điệp được gởi tới hàng
đợi.
WH_CBT: cài đặt hàm câu móc để nhận thông báo từ ứng dụng CBT.
WH_DEBUG: cài đặt hàm câu móc để gỡ rối một hàm câu móc khác.
WH_FOREGROUNDIDLE: cài đặt hàm câu móc trong đó hàm này được gọi khi
luồng (thread) foreground của ứng dụng rảnh (idle). Quá trình này thường sử dụng để thực
thi các tác vụ có độ ưu tiên thấp khi luồng ưu tiên rảnh.
WH_JOURNALPLAYBACK: cài đặt hàm câu móc để gởi các thông điệp đã được
lưu bằng hàm câu móc WH_JOURNALRECORD.
WH_JOURNALRECORD: cài đặt hàm câu móc lưu lại các thông điệp đã gởi đến
hàng đợi.
WH_KEYBOARD_LL: cài đặt hàm câu móc quản lý sự kiện bàn phím ở mức thấp
(dùng cho Windows NT/2000/XP).
WH_MOUSE_LL: cài đặt hàm câu móc quản lý sự kiện chuột ở mức thấp (dùng cho
Windows NT/2000/XP).
WH_SHELL: cài đặt hàm câu móc cho một ứng dụng shell.
WH_SYSMSGFILTER: cài đặt hàm câu móc quản lý các thông điệp được tạo ra
giống như có một sự kiện của dialog box, message box, menu hay scroll bar. Hàm này quản
lý cho tất cả ứng dụng trong cùng một desktop.
- lpfn:
Con trỏ chỉ đến địa chỉ của hàm lọc. Nếu tham số dwThreadId = 0 hay chỉ đến một
luồng được tạo bởi một tiến trình (process) khác, tham số lpfn phải chỉ đến một hàm câu
móc trong một thư viện liên kết động (DLL). Ngược lại, lpfn chỉ đến hàm câu móc chứa
trong bản thân tiến trình hiện hành.
- hMod:
handle chỉ đến DLL chứa hàm xử lý xác định bằng tham số lpfn. Tham số hMod phải
đặt là NULL nếu hàm câu móc nằm trong tiến trình hiện hành
- dwThreadId:
Xác định ID của luồng thực hiện quá trình câu móc. Nếu dwThreadId = 0, hàm câu
móc sẽ tác động đến tất cả các luồng. Ứng dụng có thể dùng hàm GetCurrentThreadId để
xác định ID của luồng hiện hành.
Hook Phạm vi
WH_JOURNALRECORD Hệ thống
WH_JOURNALPLAYBACK Hệ thống
WH_SYSMSGFILTER Hệ thống
Hàm SetWindowsHookEx trả về handle của quá trình câu móc đã cài đặt và trả về
NULL nếu quá trình cài đặt không thành công. Handle này được dùng để xóa quá trình câu
móc khi sử dụng hàm UnhookWindowsHookEx. Các thông báo lỗi khi quá trình câu móc
không thành công là:
- ERROR_INVALID_HOOK_FILTER: mã câu móc sai
- ERROR_INVALID_FILTER_PROC: hàm lọc sai
- ERROR_HOOK_NEEDS_HMOD: một quá trình câu móc toàn cục sử dụng tham
số hMod = NULL hay chỉ đến một luồng không tồn tại.
- ERROR_GLOBAL_ONLY_HOOK: một quá trình câu móc chỉ dùng được cho
hệ thống nhưng được cài đặt cho một luồng xác định.
- ERROR_INVALID_PARAMETER: ID của luồng sai.
- ERROR_JOURNAL_HOOK_SET: Cài đặt thêm một quá trình câu móc dạng
nhật ký (WH_JOURNALRECORD và WH_JOURNALPLAYBACK) trong khi
một quá trình dạng này đang tồn tại (tại một thời điểm chỉ cho phép một quá trình
dạng nhật ký).
- ERROR_MOD_NOT_FOUND: Tham số hMod chỉ đến một hàm không xác định
được.
- Khác: không cho phép do bảo mật của hệ thống hay bộ nhớ tràn.
Chương 3
GIAO TIẾP THIẾT BỊ CHUẨN
1. Giao tiếp bàn phím
1.1. Nguyên lý hoạt động
Keyboard
Keyboard Interface
IRQ1 Y- Decoder
IRQ Logic
D0
Serial 11 bits SDU
D1 Interface
D2 (PC/XT)
Keyboard chip
X - Decoder
D3 or Scan
Keyboard Matrix
D4 Controller
D5 8042/8741/8742 Keyboard cable
(AT ect)
D6 Scan
Enable
D7
Chip xử lý bàn phím liên tục kiểm tra trạng thái của ma trận quét (scan matrix) để
xác định công tắc tại các tọa độ X, Y đang được đóng hay mở và ghi một mã tương ứng vào
bộ đệm bên trong bàn phím. Sau đó mã này sẽ được truyền nối tiếp tới mạch ghép nối bàn
phím trong PC. Cấu trúc của SDU (Serial Data Unit) cho việc truyền số liệu:
0 10
STRT DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 PAR STOP
Chân 1: clock
Chân 2: dữ liệu
Chân 3: Reset
Chân 4: GND
Chân 5: Vcc
Chân 1: dữ liệu
Chân 2: không dùng
Chân 3: GND
Chân 4: Vcc
Chân 5: clock
Chân 6: không dùng
Mỗi phím nhấn sẽ được gán cho 1 mã quét (scan code) gồm 1 byte. Nếu 1 phím được
nhấn thì bàn phím phát ra 1 mã make code tương ứng với mã quét truyền tới mạch ghép nối
bàn phím của PC. Ngắt cứng INT 09h được phát ra qua IRQ1.
Chương trình xử lý ngắt sẽ xử lý mã này tuỳ theo phím SHIFT có được nhấn hay
không. Ví dụ: nhấn phím SHIFT trước, không rời tay và sau đó nhấn ‘C’:
make code được truyền - 42(SHIFT) - 46 (‘C’).
Nếu rời tay nhấn phím SHIFT thì bàn phím sẽ phát ra break code và mã này được
truyền như make code. Mã này giống như mã quét nhưng bit 7 được đặt lên 1, do vậy nó
tương đương với make code cộng với 128. Tuỳ theo break code, chương trình con xử lý
ngắt sẽ xác định trạng thái nhấn hay rời của các phím. Thí dụ, phím SHIFT và ‘C’ được rời
theo thứ tự ngược lại với thí dụ trên:
break code được truyền 174 ( bằng 46 cộng 128 tương ứng với ‘C’) và 170
(bằng 42 cộng 128 tương ứng với SHIFT).
Phần cứng và phần mềm xử lý bàn phím còn giải quyết các vấn đề vật lý sau:
- Nhấn và nhả phím nhưng không được phát hiện.
- Khử nhiễu rung cơ khí và phân biệt 1 phím được nhấn nhiều lần hay được
nhấn chỉ 1 lần nhưng được giữ trong một khoảng thời gian dài.
Thanh ghi trạng thái xác định trạng thái hiện tại của bộ điều khiển bàn phím. Thanh
ghi này chỉ đọc (read only) và đọc bằng lệnh IN tại port 64h.
7 0
PARE TIM AUXB KEYL C/D SYSF INPB OUTB
PARE: Lỗi chẵn lẻ của byte cuối cùng được vào từ bàn phím; 1 = có lỗi chẵn lẻ, 0
= không có.
TIM: Lỗi quá thời gian (time-out); 1 = có lỗi, 0 = không có.
AUXB: Đệm ra cho thiết bị phụ (chỉ có ở máy PS/2); 1 = giữ số liệu cho thiết bị,
0 = giữ số liệu cho bàn phím.
KEYL: Trạng thái khóa bàn phím; 1 = không khóa, 0 = khóa.
C/D: Lệnh/dữ liệu; 1 = Ghi qua port 64h, 0 = Ghi qua port 60h.
SYSF: cờ hệ thống; 1 = tự kiểm tra thành công, 0 = reset khi cấp điện
INPB: Trạng thái đệm vào; 1 = dữ liệu CPU trong bộ đệm vào, 0 = đệm vào rỗng.
OUTB: Trạng thái đệm ra; 1 = dữ liệu bộ điều khiển bàn phím trong bộ đệm ra, 0
= đệm ra rỗng.
Keyboard Controller
Buffer
Input
60h
Keyboard
Output
Port
Output
Buffer
PC System Bus
60h
Register
Control
64h
PS/2 only
Input
Port
Register
Status
64h
Mã Lệnh Mô tả
EDh Bật/tắt LED Bật/tắt các đèn led của bàn phím
EEh Echo Trả về byte EEh
F0h Đặt/nhận dạng mã quét Đặt 1 trong 3 tập mã quét và nhận diện các mã quét
tập mã quét hiện tại.
F2h Nhận diện bàn phím Nhận diện ACK = AT, ACK+abh+41h=MF II.
F3h Đặt tốc độ lặp lại/trễ Đặt tốc độ lặp lại và thời gian trễ của bàn phím
F4h Enable Cho phép bàn phím hoạt động
F5h Chuẩn/không cho phép Đặt giá trị chuẩn và cấm bàn phím.
F6h Chuẩn/cho phép Đặt giá trị chuẩn và cho phép bàn phím.
FEh Resend Bàn phím truyền ký tự cuối cùng một lần nữa tới bộ
điều khiển bàn phím
FFh Reset Chạy reset bên trong bàn phím
Thí dụ: lệnh bật đèn led cho phím NUMCLOCK, tắt tất cả các đèn khác.
MOV AL,0EDh
OUT 60H, AL
WAIT:
IN AL, 64H ; đọc thanh ghi trạng thái
JNZ WAIT
MOV AL,02h
OUT 60H, AL ; bật đèn cho numclock
1.3. Lập trình giao tiếp qua các hàm của DOS, BIOS
BIOS ghi các ký tự do việc nhấn các phím vào bộ đệm tạm thời được gọi là bộ đệm
bàn phím (keyboard buffer), có địa chỉ 40h:1Eh, gồm 32 byte và kết thúc ở địa chỉ 40h:3Dh.
Mỗi ký tự được lưu trữ bằng 2 byte, byte cao là mã quét, và byte thấp là mã ASCII. Chương
trình xử lý ngắt sẽ xác định mã ASCII từ mã quét bằng bảng biến đổi và ghi cả 2 mã vào bộ
đệm bàn phím. Bộ đệm bàn phím được tổ chức như bộ đệm vòng (ring buffer) và được quản
lý bởi 2 con trỏ. Các giá trị con trỏ được lưu trữ trong vùng dữ liệu của BIOS ở địa chỉ
40h:1Ah và 40h:1Ch. Con trỏ ghi (40h:1Ch) cho biết vị trí còn trống kế tiếp để ghi ký tự
nhập, con trỏ đọc (40h:1Ah) cho biết vị trí ký tự đầu tiên sẽ đọc. Từ đó, bộ đệm bàn phím
rỗng khi con trỏ ghi và con trỏ đọc trùng nhau Æ bộ đệm chỉ chứa được 15 ký tự.
7 6 5 4 3 2 1 0
INS CAPS NUM SCROLL ALT CTRL LEFT RIGHT
LOCK LOCK LOCK SHIFT SHIFT
Nguon sang
Truc lan
Y
Vien bi
Di cong COM
Bo khuech dai
Chú ý rằng toạ độ con trỏ xác định theo pixel với độ phân giải 640x200 trong khi chế
độ văn bản sử dụng toạ độ ký tự 80x25 nên để chuyển sang toạ độ ký tự thì phải chia cho 8.
Con trỏ chuột hiển thị trên màn hình đồ hoạ bằng cách thực hiện:
Từ mới = (từ cũ AND mặt nạ màn hình) XOR mặt nạ con trỏ
Nếu ta đặt mặt nạ màn hình là 0 thì ký tự màn hình tại đó sẽ bị xoá.
15 14 13 12 11 10 9 8
BLNK BAK2 BAK1 BAK0 INT FOR2 FOR1 FOR0
7 6 5 4 3 2 1 0
CHR7 CHR6 CHR5 CHR4 CHR3 CHR2 CHR1 CHR0
Trong chế độ văn bản, 6845 liên tục xuất các địa chỉ cho RAM video qua MA0-
MA13. Ký tự ở góc tận cùng phía trên bên trái màn hình có địa chỉ thấp nhất mà 6845 sẽ
cung cấp ngay sau khi quét dọc ngược. Logic ghép nối định địa chỉ cho RAM video bằng
việc lấy ra mã ký tự cùng với thuộc tính. Mã ký tự dùng cho máy phát ký tự như là chỉ số
thứ nhất trong ROM ký tự. Lúc này, 6845 định địa chỉ hàng quét đầu tiên của ma trận ký tự,
địa chỉ hàng bằng 0. Các bit của ma trận điểm ảnh bây giờ sẽ được truyền đồng bộ với tần
số video từ thanh ghi dịch tới máy phát tín hiệu. Nếu máy phát tín hiệu nhận được giá trị 1
từ thanh ghi dịch, nó sẽ phát tín hiệu video tương ứng với màu của ký tự. Nếu nhận được 0
nó sẽ cấp tín hiệu tương ứng với màu nền. Vậy dòng quét thứ nhất được hiện phù hợp với
các ma trận điểm ảnh của các ký tự trong hàng ký tự thứ nhất. Khi tia điện tử đạt tới cuối
dòng quét, 6845 kích hoạt lối ra HS (Horizontal Synchronization) để tạo ra quá trình quét
ngược và đồng bộ ngang. Tia điện tử quay trở về bắt đầu quét dòng tiếp. Sau mỗi dòng
quét, 6845 tăng giá trị RA0-RA4 lên 1. Địa chỉ dòng này hình thành một giá trị offset bên
trong ma trận điểm ảnh cho ký tự được hiện. Dựa trên mỗi dòng quét như vậy, một dòng các
điểm ảnh của ký tự trong hàng ký tự được hiện ra. Điều này có nghĩa là với ma trận 9x14
điểm ảnh cho 1 ký tự, hàng ký tự thứ nhất đã được hiện sau 14 dòng quét. Khi địa chỉ RA0-
RA4 trở về giá trị 0, 6845 sẽ cấp 1 địa chỉ MA0-MA13 mới và hàng ký tự thứ hai sẽ được
hiện ra cũng như vậy. Ở cuối dòng quét cuối cùng, 6845 sẽ reset địa chỉ MA0-MA13 và
RA0-RA4 và cho phép lối ra VS (Vertical Synchronization) phát ra tín hiệu quét ngược
cùng tín hiệu đồng bộ dọc.
Mỗi ký tự có chiều cao cực đại ứng với 32 dòng vì có 5 đường địa chỉ RA0-RA4, còn
bộ nhớ video trong trường hợp này được tới 16K từ vì có địa chỉ MA0-MA13 là 14 bit.
Trong chế độ đồ họa, chúng kết hợp với nhau để tạo thành địa chỉ 19 bit, lúc đó 6845 có thể
định địa chỉ cho bộ nhớ video lên tới 512K từ. Trong trường hợp này, các byte trong RAM
video không được dịch thành mã ký tự và thuộc tính nữa mà trực tiếp xác định cường độ
sáng và màu của điểm ảnh. Đa số các RAM video được chia thành vài băng được định địa
chỉ bởi RA0-RA4. Các đường MA0-MA13 sẽ định địa chỉ offset bên trong mỗi băng. Dữ
liệu trong RAM video lúc này được trực tiếp truyền tới thanh ghi dịch và máy phát tín hiệu.
ROM ký tự và máy phát ký tự không làm việc.
RAM video được tổ chức khác nhau tuỳ theo chế độ hoạt động và bản mạch ghép
nối. Thí dụ, với RAM video 128 KB, có thể địa chỉ hóa toàn bộ bộ nhớ màn hình qua CPU
như bộ nhớ chính. Nhưng nếu kích thước RAM video lớn hơn thì làm như vậy sẽ đè lên
vùng ROM mở rộng ở điạ chỉ C0000h. Do đó, card EGA và VGA với trên 128 KB nhớ
được tăng cường thêm 1 chuyển mạch mềm (soft-switch) cho phép thâm nhập các cửa sổ
128 KB khác nhau vào RAM video lớn hơn nhiều. Các chuyển mạch này được quy định bởi
riêng các nhà sản xuất board mạch.
Các lệnh copy, type và print trong command.com cho phép hiện text trên màn hình.
DOS gộp chung bàn phím và monitor thành 1 thiết bị mang tên CON (console). Ghi CON là
truyền số liệu tới monitor, còn đọc CON là nhận ký tự từ bàn phím. Ví dụ: để hiện nội dung
của file output.txt lên màn hình của monitor sẽ có các cách sau:
- copy output.txt con
- type output.txt > con
- print output.txt /D:con
7
Đầu = 0 Đầu = 0 Đầu = 6 Đầu = 7
Cuối = 7 Cuối = 1 Cuối = 7 Cuối = 0
- Hàm 0Ch: hiện một điểm trên màn hình (dùng cho chế độ đồ hoạ)
AL = giá trị pixel (0 – 3), nếu AL.7 = 1 thì giá trị màu là phép toán XOR vứi giá trị
màu hiện hành
CX = cột, DX = hàng
- Hàm 0Dh: đọc một điểm trên màn hình (dùng cho chế độ đồ hoạ)
Vào: CX = cột, DX = hàng
Ra: AL = giá trị pixel
- Hàm 0Fh: xác định chế độ màn hình hiện hành
Ra:
AL = chế độ
AH = số cột
BH = số trang
- Hàm 13h: xuất chuỗi
Vào:
AL = chế độ xuất (bit0 = 1: cập nhật vị trí con trỏ sau khi xuất, bit1 = 1: chuỗi có
chứa thuộc tính ký tự)
BH = trang
BL = thuộc tính (theo bảng trang 61)
CX = số ký tự cần xuất
CX = số ký tự cần xuất
DH, DL = hàng, cột xuất chuỗi
Các card EGA/VGA có riêng BIOS của chúng. Trong quá trình khởi động PC, nó sẽ
chặn int 10h lại và chạy chương trình BIOS riêng. Thường trình cũ (của BIOS trên board
mach chính) được thay địa chỉ tới int 42h. Tất cả các lệnh gọi int 10h sẽ được BIOS của
EGA/VGA thay địa chỉ tới int 42h nếu board mạch EGA/VGA đang chạy các kiểu hiện
tương thích với MDA hay CGA. Có các kiểu hoạt động từ 0 đến 7.
BIOS của EGA/VGA dùng vùng 40:84h tới 40:88h để lưu số liệu BIOS và các thông
số của EGA/VGA. Nó có các hàm mới với các hàm phụ sau:
- Hàm 10h: truy xuất các thanh ghi màu và bảng màu
- Hàm 11h: cài đặt các bảng định nghĩa ký tự mới
- Hàm 12h: đặt cấu hình hệ con video
- Hàm 1Bh: thông tin về trạng thái và chức năng của BIOS video (chỉ có
ở VGA)
- Hàm 1Ch: trạng thái save/restore của video (chỉ có ở VGA)
Sau đây là chức năng của các hàm và thí dụ sử dụng chúng:
- Hàm 10h, hàm phụ 03h – xoá/đặt thuộc tính
Ví dụ: Xoá thuộc tính nhấp nháy:
Mov ah, 10h ; dùng hàm 10h
Mov al, 03h ; dùng hàm phụ 03h
Mov bl, 00h ; xoá thuộc tính nhấp nháy
Int 10h ; gọi ngắt
- Hàm 12h, hàm phụ 20h – chọn thường trình in màn hình. Dùng hàm
phụ này có thể thay thế thường trình chuẩn cho INT 05h bằng thường
trình có thể dùng cho các độ phân giải mới của EGA/VGA.
Ví dụ: Cho phép thường trình mới in màn hình:
Mov ah, 12h ; dùng hàm 12h
Mov bl, 20h ; dùng hàm phụ 20h
Ấn PRINT hoặc SHIFT+PRINT để gọi thường trình in đã được lắp đặt.
7 6 5 4 3 2 1 0
Res Res Res Res LY3 LY2 LY1 LY0
Để lưu trữ nội dung màn hình cần phải đọc các giá trị bit của 4 lớp khi dùng thanh
ghi chọn bản đồ đọc (read map select register). Nó được định địa chỉ với chỉ số 04h qua
cổng chỉ số 3CEh, và có thể được ghi qua cổng số liệu 3CFh. Cấu trúc của thanh ghi này:
7 6 5 4 3 2 1 0
res res res res res res LY1 LY0
Chú ý rằng 4 bit tại 4 lớp đại diện cho 1 điểm ảnh nên trong kiểu hiện 16 EGA có độ
phân giải cao nhất mỗi dòng cần 80byte (640 điểm ảnh / 8 điểm ảnh trên 1 byte); mỗi trang
màn hình gồm 32 KB. Địa chỉ byte của điểm ảnh ở dòng i, cột j trang k (i=0-349, j=0-639,
k=0-1) là:
Address (i,j,k) = A0000h + 8000h*k + 50h*j + int (i/8).
Với board VGA, các chế độ hiện văn bản từ 0 đến 3 và 7 cũng như các chế độ đồ họa
từ 4 đến 6 và 13 đến 16 của CGA. EGA và MDA đều chạy được trên nó.
Trong chế độ văn bản, mã ký tự được lưu trữ trong lớp nhớ 0 cùng với thuộc tính
trong lớp 1 của RAM video VGA. Quá trình chuyển hóa địa chỉ cũng giống như EGA
nhưng khác ở chổ nó vẫn đảm bảo chế độ văn bản 7 với độ phân giải 720x400, ma trận điểm
ảnh 9x16. Trong chế độ đồ họa 4 ÷ 6 và 13 ÷ 19 , mọi tổ chức, cấu trúc cũng như cách tính
địa chỉ tương tự như CGA và EGA. VGA được tăng cường 3 kiểu hiện hình mới từ 17 đến
19.
Kiểu 17 tương thích với board đồ họa của máy PS/2 kiểu 30 là MCGA (multi colour
graphics array). Các điểm ảnh chỉ gổm 1 bit (2 màu) được định vị chỉ trên lớp 0. Thí dụ,
trong VGA kiểu 17 với 80 byte trên 1 dòng (640 điểm ảnh / 8 điểm ảnh trên 1 byte). Mỗi
trang màn hình gồm 40 KB. Địa chỉ của byte ở dòng i, cột j ( i= 0-479), j=0-639) như sau:
Address (i,j) = A0000h+50h*j+int (i/8)
Kiểu 18, 4 bit của điểm ảnh được phân trong 4 lớp nhớ như ở EGA. Trong kiểu VGA
phân giải cao với 16 màu khác nhau, 80 byte trên 1 dòng (640 điểm ảnh / 8 điểm ảnh trên 1
byte), mỗi trang màn hình gồm 40 KB (A0000h byte); địa chỉ của mỗi byte ở dòng i, cột j
(i=0-479; j = 0-639) bằng:
Address (i,j) = A0000h + 50h*j + int (i/8).
Kiểu 19 với 256 màu cho 1 điểm ảnh thì RAM video lại được tổ chức rất đơn giản
như 1 dãy tuyến tính, trong đó 1 byte tương ứng với 1 điểm ảnh. Giá trị của byte phân định
màu của điểm ảnh. Kiểu này đòi hỏi 320 byte (140h) trên 1 dòng (320 điểm ảnh / 1 điểm
ảnh trên 1 byte). Một trang màn hình gồm 64 KB (10000h) nhưng chỉ có 64000 byte được
sử dụng. Địa chỉ của điểm ảnh trong dòng i, cột j (i = 0-199, j=0-319) là:
Address (i,j) = A0000h + 140h*j + i
.CODE
MAIN PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,0FH ;get current video mode
INT 10H
MOV OLDVIDEO,AL ;save it
MOV AX,0600H ;clear screen
MOV BH,07
MOV CX,0
MOV DX,184FH
INT 10H
MOV AH,00H ;set new video mode
MOV AL,NEWVIDEO
INT 10H
MOV AX,0 ;initialize mouse
INT 33H
MOV AX,01 ;show mouse cursor
INT 33H
CURSOR 2,1
DISPLAY MESSAGE_1
CURSOR 4,1
DISPLAY MESSAGE_2
MOV AH,07 ;wait for key press
INT 21H
MOV AX,05H ;get mouse press count
MOV BX,0 ;check press count for left button
INT 33H
MOV AX,BX ;BX=button press count
MOV BL,10
DIV BL
ADD AX,3030H
MOV P_COUNT,AL ;save the number
MOV P_COUNT+1,AH
CURSOR 10,2
DISPLAY MESSAGE_3
DISPLAY P_COUNT
CURSOR 20,2
DISPLAY MESSAGE_4
MOV AH,07 ;wait for a key press to get out
INT 21H
MOV AH,02 ;hide mouse
INT 33H
MOV AH,0 ;restore original video mode
MOV AL,OLDVIDEO ;load original vide mode
INT 10H
MOV AH,4CH ;go back to DOS
INT 21H
MAIN ENDP
END MAIN
;-----------------------------------------------------
.MODEL SMALL
.STACK 100h
.DATA
mask_mon DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
DB 0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
mask_p DB 80h,0,0E0h,0,0F8h,0,0FEh,0
DB 0D8h,0,0Ch,0,6,0,3,0
DB 0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0
.CODE
main PROC
mov ax,@data
mov ds,ax
mov es,ax
mov ah,0
mov al,6
int 10h
mov ax,0
int 33h
mov ax,1
int 33h
mov ah,08h
int 21h
mov ax,9
mov bx,0
mov cx,0
lea dx,mask_mon
int 33h
mov ah,08h
int 21h
mov ah,4Ch
int 21h
main ENDP
END main
1000000000000000
1110000000000000
1111100000000000
1111111000000000
1101100000000000
0000110000000000
0000011000000000
0000001100000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK
A 1E 9E 9 0A 8A [ 1A 9A
B 30 B0 ` 29 89 INSERT E0,52 E0,D2
C 2E AE - 0C 8C HOME E0,47 E0,97
D 20 A0 = 0D 8D PG UP E0,49 E0,C9
E 12 92 \ 2B AB DELETE E0,53 E0,D3
F 21 A1 BKSP 0E 8E END E0,4F E0,CF
G 22 A2 SPACE 39 B9 PG DN E0,51 E0,D1
H 23 A3 TAB 0F 8F U ARROW E0,48 E0,C8
I 17 97 CAPS 3A BA L ARROW E0,4B E0,CB
J 24 A4 L SHFT 2A AA D ARROW E0,50 E0,D0
K 25 A5 L CTRL 1D 9D R ARROW E0,4D E0,CD
L 26 A6 L GUI E0,5B E0,DB NUM 45 C5
M 32 B2 L ALT 38 B8 KP / E0,35 E0,B5
N 31 B1 R SHFT 36 B6 KP * 37 B7
O 18 98 R CTRL E0,1D E0,9D KP - 4A CA
P 19 99 R GUI E0,5C E0,DC KP + 4E CE
Q 10 19 R ALT E0,38 E0,B8 KP EN E0,1C E0,9C
R 13 93 APPS E0,5D E0,DD KP . 53 D3
S 1F 9F ENTER 1C 9C KP 0 52 D2
T 14 94 ESC 01 81 KP 1 4F CF
U 16 96 F1 3B BB KP 2 50 D0
V 2F AF F2 3C BC KP 3 51 D1
W 11 91 F3 3D BD KP 4 4B CB
X 2D AD F4 3E BE KP 5 4C CC
Y 15 95 F5 3F BF KP 6 4D CD
Z 2C AC F6 40 C0 KP 7 47 C7
0 0B 8B F7 41 C1 KP 8 48 C8
1 02 82 F8 42 C2 KP 9 49 C9
2 03 83 F9 43 C3 ] 1B 9B
3 04 84 F10 44 C4 ; 27 A7
4 05 85 F11 57 D7 ' 28 A8
5 06 86 F12 58 D8 , 33 B3
PRNT E0,2A, E0,B7,
6 07 87 . 34 B4
SCRN E0,37 E0,AA
7 08 88 SCROLL 46 C6 / 35 B5
E1,1D,45
8 09 89 PAUSE -NONE-
E1,9D,C5
KEY MAKE BREAK ----- KEY MAKE BREAK ----- KEY MAKE BREAK
A 1C F0,1C 9 46 F0,46 [ 54 FO,54
B 32 F0,32 ` 0E F0,0E INSERT E0,70 E0,F0,70
C 21 F0,21 - 4E F0,4E HOME E0,6C E0,F0,6C
D 23 F0,23 = 55 FO,55 PG UP E0,7D E0,F0,7D
E 24 F0,24 \ 5D F0,5D DELETE E0,71 E0,F0,71
F 2B F0,2B BKSP 66 F0,66 END E0,69 E0,F0,69
G 34 F0,34 SPACE 29 F0,29 PG DN E0,7A E0,F0,7A
H 33 F0,33 TAB 0D F0,0D U ARROW E0,75 E0,F0,75
I 43 F0,43 CAPS 58 F0,58 L ARROW E0,6B E0,F0,6B
J 3B F0,3B L SHFT 12 FO,12 D ARROW E0,72 E0,F0,72
K 42 F0,42 L CTRL 14 FO,14 R ARROW E0,74 E0,F0,74
L 4B F0,4B L GUI E0,1F E0,F0,1F NUM 77 F0,77
M 3A F0,3A L ALT 11 F0,11 KP / E0,4A E0,F0,4A
N 31 F0,31 R SHFT 59 F0,59 KP * 7C F0,7C
O 44 F0,44 R CTRL E0,14 E0,F0,14 KP - 7B F0,7B
P 4D F0,4D R GUI E0,27 E0,F0,27 KP + 79 F0,79
Q 15 F0,15 R ALT E0,11 E0,F0,11 KP EN E0,5A E0,F0,5A
R 2D F0,2D APPS E0,2F E0,F0,2F KP . 71 F0,71
S 1B F0,1B ENTER 5A F0,5A KP 0 70 F0,70
T 2C F0,2C ESC 76 F0,76 KP 1 69 F0,69
U 3C F0,3C F1 05 F0,05 KP 2 72 F0,72
V 2A F0,2A F2 06 F0,06 KP 3 7A F0,7A
W 1D F0,1D F3 04 F0,04 KP 4 6B F0,6B
Chương 4
GIAO TIẾP CỐNG NỐI TIẾP
1. Cấu trúc cổng nối tiếp
Cổng nối tiếp được sử dụng để truyền dữ liệu hai chiều giữa máy tính và ngoại vi, có
các ưu điểm sau:
- Khoảng cách truyền xa hơn truyền song song.
- Số dây kết nối ít.
- Có thể truyền không dây dùng hồng ngoại.
- Có thể ghép nối với vi điều khiển hay PLC (Programmable Logic Device).
- Cho phép nối mạng.
- Có thể tháo lắp thiết bị trong lúc máy tính đang làm việc.
- Có thể cung cấp nguồn cho các mạch điện đơn giản
Các thiết bị ghép nối chia thành 2 loại: DTE (Data Terminal Equipment) và DCE
(Data Communication Equipment). DCE là các thiết bị trung gian như MODEM còn DTE là
các thiết bị tiếp nhận hay truyền dữ liệu như máy tính, PLC, vi điều khiển, … Việc trao đổi
tín hiệu thông thường qua 2 chân RxD (nhận) và TxD (truyền). Các tín hiệu còn lại có chức
năng hỗ trợ để thiết lập và điều khiển quá trình truyền, được gọi là các tín hiệu bắt tay
(handshake). Ưu điểm của quá trình truyền dùng tín hiệu bắt tay là có thể kiểm soát đường
truyền.
Tín hiệu truyền theo chuẩn RS-232 của EIA (Electronics Industry Associations).
Chuẩn RS-232 quy định mức logic 1 ứng với điện áp từ -3V đến -25V (mark), mức logic 0
ứng với điện áp từ 3V đến 25V (space) và có khả năng cung cấp dòng từ 10 mA đến 20 mA.
Ngoài ra, tất cả các ngõ ra đều có đặc tính chống chập mạch.
Chuẩn RS-232 cho phép truyền tín hiệu với tốc độ đến 20.000 bps nhưng nếu cáp
truyền đủ ngắn có thể lên đến 115.200 bps.
Các phương thức nối giữa DTE và DCE:
- Đơn công (simplex connection): dữ liệu chỉ được truyền theo 1 hướng.
- Bán song công ( half-duplex): dữ liệu truyền theo 2 hướng, nhưng mỗi thời điểm
chỉ được truyền theo 1 hướng.
- Song công (full-duplex): số liệu được truyền đồng thời theo 2 hướng.
Định dạng của khung truyền dữ liệu theo chuẩn RS-232 như sau:
Start D0 D1 D2 D3 D4 D5 D6 D7 P Stop
0 1
Khi không truyền dữ liệu, đường truyền sẽ ở trạng thái mark (điện áp -10V). Khi bắt
đầu truyền, DTE sẽ đưa ra xung Start (space: 10V) và sau đó lần lượt truyền từ D0 đến D7
và Parity, cuối cùng là xung Stop (mark: -10V) để khôi phục trạng thái đường truyền. Dạng
tín hiệu truyền mô tả như sau (truyền ký tự A):
Các tốc độ truyền dữ liệu thông dụng trong cổng nối tiếp là: 1200 bps, 4800 bps,
9600 bps và 19200 bps.
Sơ đồ chân:
Cổng COM có hai dạng: đầu nối DB25 (25 chân) và đầu nối DB9 (9 chân) mô tả như
hình 4.2. Ý nghĩa của các chân mô tả như sau:
Hình 4.3 – Kết nối đơn giản trong truyền thông nối tiếp
Khi thực hiện kết nối như trên, quá trình truyền phải bảo đảm tốc độ ở đầu phát và
thu giống nhau. Khi có dữ liệu đến DTE, dữ liệu này sẽ được đưa vào bộ đệm và tạo ngắt.
Ngoài ra, khi thực hiện kết nối giữa hai DTE, ta còn dùng sơ đồ sau:
TxD TxD
RxD RxD
GND GND
RTS RTS
CTS CTS
DSR DSR
DCD DCD
DTR DTR
DTE1 DTE2
Hình 4.4 – Kết nối trong truyền thông nối tiếp dùng tín hiệu bắt tay
Khi DTE1 cần truyền dữ liệu thì cho DTR tích cực Æ tác động lên DSR của DTE2
cho biết sẵn sàng nhận dữ liệu và cho biết đã nhận được sóng mang của MODEM (ảo). Sau
đó, DTE1 tích cực chân RTS để tác động đến chân CTS của DTE2 cho biết DTE1 có thể
nhận dữ liệu. Khi thực hiện kết nối giữa DTE và DCE, do tốc độ truyền khác nhau nên phải
thực hiện điều khiển lưu lượng. Quá trinh điều khiển này có thể thực hiện bằng phần mềm
hay phần cứng. Quá trình điều khiển bằng phần mềm thực hiện bằng hai ký tự Xon và Xoff.
Ký tự Xon được DCE gởi đi khi rảnh (có thể nhận dữ liệu). Nếu DCE bận thì sẽ gởi ký tự
Xoff. Quá trình điều khiển bằng phần cứng dùng hai chân RTS và CTS. Nếu DTE muốn
truyền dữ liệu thì sẽ gởi RTS để yêu cầu truyền, DCE nếu có khả năng nhận dữ liệu (đang
rảnh) thì gởi lại CTS.
Giao tiếp nối tiếp trong máy tính sử dụng vi mạch UART với các thanh ghi cho trong
bảng sau:
Offset DLAB R/W Tên Chức năng
0 W THR Transmitter Holding Register (đệm truyền)
0 0 R RBR Receiver Buffer Register (đệm thu)
1 R/W BRDL Baud Rate Divisor Latch (số chia byte thấp)
0 R/W IER Interrupt Enable Register (cho phép ngắt)
1
1 R/W BRDH Số chia byte cao
R IIR Interrupt Identification Register (nhận dạng ngắt)
2
W FCR FIFO Control Register
3 R/W LCR Line Control Register (điều khiển đường dây)
4 R/W MCR Modem Control Register (điều khiển MODEM)
5 R LSR Line Status Register (trạng thái đường dây)
6 R MSR Modem Status Register (trạng thái MODEM)
7 R/W Scratch Register (thanh ghi tạm)
Các thanh ghi này có thể truy xuất trực tiếp kết hợp với địa chỉ cổng (ví dụ như thanh
ghi cho phép ngắt của COM1 có địa chỉ là BACOM1 + 1 = 3F9h.
D7 D6 D5 D4 D3 D2 D1 D0
- - POW HBR MODEM LINE TxEMPTY RxRDY
Cho phép kiểu Cho phép khi lỗi Cho phép khi
công suất thấp modem THR rỗng
D7 D6 D5 D4 D3 D2 D1 D0
- - - LOOP OUT2 OUT1 RTS DTR
Mode loopback:
kiểm tra hoạt Điều khiển 2 ngõ ra Điều khiển tín hiệu
đọng của UART OUT1, OUT 2 của RTS và DTR
UART
D7 D6 D5 D4 D3 D2 D1 D0
RLSD RI DSR CTS ΔRLSD ΔRI ΔDSR ΔCTS
Trạng thái của CD, RI, 1: nếu có thay đổi các tín hiệu so với lần đọc trước
DSR và CTS ΔRI: = 1 nếu có xung dương tại RI
D7 D6 D5 D4 D3 D2 D1 D0
FIE TSRE THRE BI FE PE OE RxDR
BI: Break Interrupt (=1 khicó sự gián đoạn khi truyền, nghĩa là tồn tại mức logic 0
trong khoảng thời gian dài hơn khoảng thời gian truyền 1 byte và bị xoá khi CPU đọc LSR)
FE: Frame Error (=1 khi có lỗi khung truyền và bị xoá khi CPU đọc LSR)
PE: Parity Error (=1 khi có lỗi parity và bị xoá khi CPU đọc LSR)
OE: Overrun Error (=1 khi có lỗi thu đè, nghĩa là CPU không đọc kịp dữ liệu làm cho
quá trình ghi chồng lên RBR xảy ra và bị xoá khi CPU đọc LSR)
RxDR: Receiver Data Ready (=1 khi đã nhận 1 ký tự và đưa vào RBR và bị xoá khi
CPU đọc RBR).
LCR (Line Control Register):
D7 D6 D5 D4 D3 D2 D1 D0
DLAB SBCB PS2 PS1 PS0 STB WLS1 WLS0
DLAB (Divisor Latch Access Bit) = 0: truy xuất RBR, THR, IER, = 1 cho phép đặt
bộ chia tần trong UART để cho phép đạt tốc độ truyền mong muốn.
UART dùng dao động thạch anh với tần số 1.8432 MHz đưa qua bộ chia 16 thành tần
số 115,200 Hz. Khi đó, tuỳ theo giá trị trong BRDL và BRDH, ta sẽ có tốc độ mong muốn.
Ví dụ như đường truyền có tốc độ truyền 2,400 bps có giá trị chia 115,200 / 2,400 = 48d =
0030h Æ BRDL = 30h, BRDH = 00h.
Một số giá trị thông dụng xác định tốc độ truyền cho như sau:
SBCB (Set Break Control Bit) =1: cho phép truyền tín hiệu Break (=0) trong khoảng
thời gian lớn hơn một khung
PS (Parity Select):
PS2 PS1 PS0 Mô tả
X X 0 Không kiểm tra
0 0 1 Kiểm tra lẻ
0 1 1 Kiểm tra chẵn
1 0 1 Parity là mark
1 1 1 Parity là space
STB (Stop Bit) = 0: 1 bit stop, =1: 1.5 bit stop (khi dùng 5 bit dữ liệu) hay 2 bit stop
(khi dùng 6, 7, 8 bit dữ liệu).
WLS (Word Length Select):
Một ví dụ khi lập trình trực tiếp trên cổng như sau:
.MODEL SMALL
.STACK 100h
.DATA
Com1 EQU 3F8h
Com_int EQU 08h
Buffer DB 251 DUP(?)
Bufferin DB 0
Bufferout DB 0
Char DB ?
Seg_com DW ? ; Vector ng•t c•
Off_com DW ?
Mask_int DB ?
Msg DB 'Press any key to exit$’
.CODE
Main PROC
MOV AX,@DATA
MOV DS,AX
MOV AH,35h
MOV AL,Com_int
INT 21h
MOV Seg_com,ES ; L•u vector ng•t c•
MOV Off_com,BX
PUSH DS
MOV BX,CS
MOV DS,BX
LEA DX,Com_ISR
MOV AH,35h ;Gán vector ng•t m•i
MOV AL,Com_int
INT 21h
POP DS
MOV AH,4Ch
INT 21h
Main ENDP
Com_ISR PROC
MOV DX,Com1+5 ; ••c n•i dung LSR
IN AL,DX
AND AL,1 ; N•u D0 = 1 thì có d• li•u
JZ exit_ISR
MOV DX,Com1
IN AL,DX
MOV buffer[bufferin],AL
INC bufferin
MOV AL,bufferin
CMP AL,251
JNE Exit_ISR
MOV bufferin,0
Exit_ISR:
MOV AL,20h ; Báo cho PIC k•t thúc ng•t
OUT 20h,AL
IRET
Com_ISR ENDP
END Main
Biểu tượng của MsComm: và các thuộc tính cơ bản mô tả như sau:
Thuộc tính Mô tả
CommPort Số thứ tự cổng truyền thông
Input Nhận ký tự từ bộ đệm
Output Xuất ký tự ra cổng nối tiếp
PortOpen Mở / đóng cổng
Settings Xác định các tham số truyền
MSComm1.InputLen = 0
If MSComm1.InBufferCount <> 0 Then
InputString = MSComm1.Input
End If
Các thuộc tính xuất dữ liệu:
Bao gồm các thuộc tính Output, OutBufferCount và OutBufferSize, chức năng
của các thuộc tính này giống như các thuộc tính nhập.
CDTimeout:
Đặt và xác định khoảng thời gian lớn nhất (tính bằng ms) từ lúc phát hiện sóng mang
cho đến lúc có dữ liệu. Nếu quá khoảng thời gian này mà vẫn chưa có dữ liệu thì sẽ gán
thuộc tính CommEvent là CDTO (Carrier Detect Timeout Error) và tạo sự kiện OnComm.
Cú pháp:
MSComm1.CDTimeout = NumTime
DSRTimeout:
Xác định thời gian chờ tín hiệu DSR trước khi xảy ra sự kiện OnComm.
CTSTimeout:
Đặt và xác định khoảng thời gian lớn nhất (tính bằng ms) đợi tín hiệu CTS trước khi
đặt thuộc tính CommEvent là CTSTO và tạo sự kiện OnComm. Cú pháp:
MSComm1.CTSTimeout = NumTime
CTSHolding:
Xác định đã có tín hiệu CTS hay chưa, tín hiệu này dùng cho quá trình bắt tay bằng
phần cứng (cho biết DCE sẵn sàng nhận dữ liệu), trả về giá trị True hay False.
DSRHolding:
Xác định trạng thái DSR (báo hiệu sự tồn tại của DCE), trả về giá trị True hay False.
CDHolding:
Xác định trạng thái CD, trả về giá trị True hay False.
DTREnable:
Đặt hay xoá tín hiệu DTR để báo sự tồn tại của DTE. Cú pháp:
MSComm1.DTREnable = True | False
RTSEnable:
Đặt hay xoá tín hiệu RTS để yêu cầu truyền dữ liệu đến DTE. Cú pháp:
MSComm1.RTSEnable = True | False
NullDiscard:
Cho phép nhận các ký tự NULL (rỗng) hay không (= True: cấm). Cú pháp:
MSComm1.NullDiscard = True | False
SThreshold:
Số byte trong bộ đệm truyền làm phát sinh sự kiện OnComm. Nếu giá trị này bằng 0
thì sẽ không tạo sự kiện OnComm. Cú pháp:
MSComm1.SThreshold = NumChar
HandShaking:
Chọn giao thức bắt tay khi thực hiện truyền dữ liệu. Cú pháp:
MSComm1.HandShaking = Protocol
Các giao thức truyền bao gồm:
Protocol Giá trị Mô tả
ComNone 0 Không băt tay (mặc định)
ComXon/Xoff 1 Bắt tay phần mềm (Xon/Xoff)
ComRTS 2 Bắt tay phần cứng (RTS/CTS)
ComRTSXon/Xoff 3 Bắt tay phần cứng và phàn mềm
CommEvent:
Trả lại các lỗi truyền thonog hay sự kiện xảy ra tại cổng nối tiếp
Các sự kiện:
Sự kiện Giá trị Mô tả
ComEvSend 1 Đã truyền ký tự
ComEvReceive 2 Khi có ký tự trong bộ đệm nhận
ComEvCTS 3 Có thay đổi trên CTS (Clear To Send)
ComEvDSR 4 Có thay đổi trên DSR (Data Set Ready)
ComEvCD 5 Có thay đổi trên CD (Carrier Detect)
ComEvRing 6 Phát hiện chuông
ComEvEOF 7 Nhận ký tự kết thúc file
Textbox chứa
các ký tự gởi Đối tượng
MSComm
Textbox chứa
các ký tự nhận
_Version = 393216
DTREnable = -1 ‘True
RThreshold = 1
End
Begin VB.Label Label2
Caption = “Receive:”
Height = 375
Left = 240
TabIndex = 2
Top = 1200
Width = 855
End
Begin VB.Label Label1
Caption = “Transmit:”
Height = 375
Left = 240
TabIndex = 1
Top = 240
Width = 975
End
End
Attribute VB_Name = “Form1”
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub cmdExit_Click()
MSComm1.PortOpen = False ‘Đóng cổng
End
End Sub
Private Sub cmdSend_Click()
MSComm1.Output = Trim(txtTransmit.Text)’Gởi dữ liệu
End Sub
Private Sub Form_Load()
MSComm1.CommPort = 1 ‘COM1
MSComm1.Settings = “9600,n,8,1” ‘Tốc độ 9600bps
MSComm1.PortOpen = True ‘ Mở cổng
End Sub
Private Sub MSComm1_OnComm()
If (MSComm1.CommEvent = comEvReceive) Then
txtReceive.Text = txtReceive.Text + MSComm1.Input
End If
End Sub
R2OUT
T2OUT
2 C2+
R2IN
T2IN
V+ 5 C29
C26 C2- 10u
10u
10
9
VCC
C27
10u
Tuy nhiên, khi sử dụng mạch chuyển mức logic dùng các vi mạch thì đòi hỏi phải
dùng chung GND giữa máy tính và vi mạch Æ có khả năng làm hỏng cổng nối tiếp khi xảy
ra hiện tượng chập mạch ở mạch ngoài. Do đó, ta có thể dùng thêm opto 4N35 để cách ly về
điện. Sơ đồ mạch cách ly mô tả như sau: VCC
1K
TxD
6 1
5 VCC
4 2
68K
DTR 4N35
1 4.7K
6
2 RxD_PC
7
3 TxD_PC 1 6
8 5 RxD
4 4.7K
9 2 4
5
4N35
RTS
2.2K
T2IN
10
VCC RST
C27
10u AT89C51
33p
11.059MHz
C31
Chương 4
Trang 77
Tài liệu này được upload & download miễn phí tại website: http://hutonline.net
Tài liệu Lập trình hệ thống Chương 4
Receive:
JNB RI,Transmit ; Có dữ liệu hay không
CLR RI
MOV A,SBUF ; Nếu có thì xuất ra LED
MOV P1,A
Transmit:
JNB TI,Receive ; Đã truyền xong chưa
CLR TI
MOV A,P2 ; Nếu xong thì truyền trạng thái
MOV SBUF,A ; của công tăc SW DIP-8
JMP Receive
TabIndex = 13
Top = 1560
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 2
Left = 1800
TabIndex = 12
Top = 1080
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 1
Left = 1800
TabIndex = 11
Top = 600
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 0
Left = 1800
TabIndex = 10
Top = 120
Width = 1575
End
Begin VB.CommandButton cmdExit
Caption = "Exit"
Height = 495
Left = 1680
TabIndex = 9
Top = 3960
Width = 975
End
Begin MSCommLib.MSComm MSComm1
Left = 3360
Top = 3960
_ExtentX = 1005
_ExtentY = 1005
_Version = 393216
DTREnable = -1 'True
RThreshold = 1
End
Begin VB.CommandButton cmdSend
Caption = "Send"
Height = 495
Left = 240
TabIndex = 8
Top = 3960
Width = 1095
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED7"
Height = 375
Index = 7
Left = 240
TabIndex = 7
Top = 3480
Width = 1095
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED6"
Height = 375
Index = 6
Left = 240
TabIndex = 6
Top = 3000
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED5"
Height = 375
Index = 5
Left = 240
TabIndex = 5
Top = 2520
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED4"
Height = 375
Index = 4
Left = 240
TabIndex = 4
Top = 2040
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED3"
Height = 375
Index = 3
Left = 240
TabIndex = 3
Top = 1560
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED2"
Height = 375
Index = 2
Left = 240
TabIndex = 2
Top = 1080
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED1"
Height = 375
Index = 1
Left = 240
TabIndex = 1
Top = 600
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED0"
Height = 375
Index = 0
Left = 240
TabIndex = 0
Top = 120
Width = 975
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 7
Left = 840
Shape = 3 'Circle
Top = 3480
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 6
Left = 840
Shape = 3 'Circle
Top = 3000
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 5
Left = 840
Shape = 3 'Circle
Top = 2520
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 4
Left = 840
Shape = 3 'Circle
Top = 2040
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 3
Left = 840
Shape = 3 'Circle
Top = 1560
Width = 375
End
Dim t As Integer
Dim i As Integer
t = 0
For i = 0 To 7
t = t + (2 ^ i) * (1 - shpLED(i).FillStyle)
Next i
MSComm1.Output = Chr(t)
End Sub
- Bắt tay phần cứng: máy tính muốn truyền dữ liệu thì cho RTS = 1 và chờ
Modem trả lời bằng tín hiệu CTS. Ngược lại, Modem muốn truyền dữ liệu thì cho
DSR = 1 và chờ tín hiệu DTR từ máy tính.
- Bắt tay phần mềm: dùng ký tự Xon (Ctrl-S) và Xoff (Ctrl-Q) để bắt đầu truyền
hay kết thúc truyền.
Các giao thức truyền dữ liệu trên Modem:
- XModem: chia thành khối 128 byte, mỗi khối chèn thêm CRC 4 byte.
- YModem: khối 1024 byte.
- ZModem: khối có kích thước thay đổi tuỳ theo đường truyền.
Quy tắc truyền lệnh trên Modem:
- Mỗi dòng lệnh của modem bắt đầu bằng ký tự AT, ngoại trừ lệnh A/ và +++.
- Dòng lệnh có thể chứa nhiều lệnh.
- Kết thúc lệnh bằng ký tự Enter (mã ASCII là 13) ngoại trừ lệnh A/ và +++.
- Dòng lệnh cuối cùng được lưu trong modem. Có thể dùng lệnh A/ để thực hiện lại
lệnh này.
- Thông báo kết quả thực hiện lệnh của modem có thể ở dạng từ chữ hay số( giá trị
mặc định là chữ). Có thể sử dụng lệnh V để lựa chọn dạng thông báo là chữ hay
số.
- Để hoạt động đúng, modem cần có các thông số xác định. Nếu không có sự thay
đổi cần thiết, modem hoạt động theo giá trị mặc định(default). Nếu thông số trong
lệnh bị bỏ qua, giá trị thông số mặc định là 0.
Lệnh Mô tả
+++ Chuyển Modem sang chế độ lệnh
A/ Lặp lại lệnh trước
A Cho phép kết nối và phát tín hiệu sóng mang. Modem sẽ báo tín hiệu CONNECT
nếu thu được tín hiêu sóng mang từ modem đầu cuối. Nếu không thu được sóng
mang, modem sẽ gác máy và thông báo NO CARRIER
DPn Quay số điện thoại n dạng xung
DTn Quay số điện thoại n dạng tone
H0 Gác máy
H1 Nhấc máy
O0 Chuyển về chế độ dữ liệu
O1 Chế độ điều chỉnh Modem
Q0 Cho phép Modem gởi thông báo đến DTE (mặc định)
Q1 Cấm Modem gởi thông báo
Q2 Gởi thông báo khi Modem chủ động kết nối, không gởi khi Modem nhận cuộc
gọi
V0 Nhận thông báo dạng số
Thanh ghi S10: xác định thời gian cho phép tín hiệu sóng mang có thể biến mất
trong chốc lát nào đó mà không cắt cuộc nối. Ổn định trong khoảng 100-25500ms, giá trị
mặc nhiên tùy vào khả năng chống nhiễu của từng modem, thường là 700ms.
Thanh ghi S11: xác định tốc độ quay số khi sử dụng phương pháp quay số tone, giá
trị mặc nhiên tùy vào modem, thường vào khoảng 70ms.
Thanh ghi S12: xác định thời gian an toàn khi truy nhập vào ký tự thoát (+++). Nếu
giá trị nhỏ quá có thể nhập không kịp, giá trị lớn quá so với tốc độ nhập cũng không thể
thoát được.
TabIndex = 12
Top = 1320
Width = 3015
End
Begin VB.Timer Timer1
Enabled = 0 'False
Interval = 1000
Left = 4920
Top = 2400
End
Begin VB.CommandButton cmdExit
Caption = "Exit"
Height = 495
Left = 4560
TabIndex = 10
Top = 2880
Width = 975
End
Begin VB.TextBox txtDial
Height = 375
Left = 960
TabIndex = 7
Top = 2400
Width = 2895
End
Begin VB.CommandButton cmdDial
Caption = "Dial"
Height = 495
Left = 1680
TabIndex = 5
Top = 3000
Width = 1095
End
Begin VB.CommandButton cmdSend
Caption = "Send"
Height = 495
Left = 4320
TabIndex = 4
Top = 720
Width = 1095
End
Begin VB.CommandButton cmdOpen
Caption = "Open Port"
Height = 495
Left = 240
TabIndex = 3
Top = 3000
Width = 1215
End
Begin VB.CommandButton cmdBrowse
Caption = "Browse"
Height = 495
Left = 4320
TabIndex = 1
Top = 120
Width = 1095
End
Begin MSComDlg.CommonDialog diagSend
Left = 4200
Top = 3120
_ExtentX = 847
_ExtentY = 847
_Version = 393216
End
Begin VB.TextBox txtSend
Height = 375
Left = 960
TabIndex = 0
Top = 360
Width = 3015
End
Begin MSCommLib.MSComm MSComm1
Left = 5160
Top = 3000
_ExtentX = 1005
_ExtentY = 1005
_Version = 393216
DTREnable = -1 'True
Handshaking = 2
NullDiscard = -1 'True
RThreshold = 1
RTSEnable = -1 'True
End
Begin VB.Label Label3
Caption = "File receive:"
Height = 375
Left = 0
TabIndex = 13
Top = 1320
Width = 855
End
Begin VB.Label lblReceive
Caption = "Receive file !!! Select
file name."
ForeColor = &H000000FF&
Height = 375
Left = 840
TabIndex = 11
Top = 1920
Visible = 0 'False
Width = 2895
End
Begin VB.Label lblStatus
Caption = "Disconnected"
Height = 375
Left = 120
TabIndex = 9
Top = 3720
Width = 5775
End
Begin VB.Label Label2
Caption = "Dial:"
Height = 375
Left = 120
TabIndex = 8
Top = 2400
Width = 735
End
Begin VB.Label Label1
Caption = "File send:"
Height = 375
Left = 120
TabIndex = 6
Top = 360
Width = 735
End
Begin VB.Label lblSize
ForeColor = &H00FF0000&
Height = 375
Left = 960
TabIndex = 2
Top = 840
Width = 1815
End
End
Attribute VB_Name = "frmModem"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Connected As Boolean
End Sub
Buffer = ""
Exit Sub
End If
If InStr(Buffer, "CONNECT") Then
Connected = True
lblStatus.Caption = "Connected"
Exit Sub
End If
If ReceiveFlag Then
Buffer1 = ""
For i = 1 To Len(Buffer)
Buff = Mid$(Buffer, i, 1)
If Buff = Chr$(13) Then
CRFlag = True
Buff = ""
ElseIf Buff = Chr$(10) Then
CRFlag = False
Buff = ""
If Not CRFlag Then
Buffer1 = Buffer1 + Buff
End If
Next i
Print #FileReceive, Buffer1
End If
If InStr(Buffer, "END FILE") Then
Close #FileReceive
Call Form_Load
End If
Case comEvEOF
lblStatus = "Disconnected"
Connected = False
End Select
End Sub
7. Mạng 485
Chuẩn RS232 dùng đường truyền không cân bằng vì các tín hiệu lấy chuẩn là GND
chung nên dễ bị ảnh hưởng của nhiễu làm tốc độ và khoảng cách truyền bị giới hạn. Khi
muốn tăng khoảng cách truyền, môt phương pháp có thể sử dụng là dùng 2 dây truyền vi sai
vì lúc này 2 dây có cùng đặc tính nên sẽ loại trừ được nhiễu chung. Hai chuẩn được sử dụng
là RS422 và RS485 nhưng thông thường sử dụng RS485. Điện áp vi sai yêu cầu phải lớn
hơn 200mV. Nếu VAB > 200 mV thì tương ứng với logic 1 và VAB < -200 mV tương ứng với
logic 0. Chuẩn RS485 sử dụng hai điện trở kết thúc là 120 Ω tại hai đầu xa nhất của đường
truyền và sử dụng dây xoắn đôi.
Đối với chuẩn RS232, khoảng cách truyền không cho phép đi xa nên khi muốn thực
hiện truyền ở khoảng cách xa thì phải chuyển từ RS232 sang chuẩn RS485 để truyền đi và
sau đó chuyển từ RS485 sang RS232 để máy tính có thể nhận dạng được. Sơ đồ mạch
chuyển đổi từ RS232 sang RS485 và ngược lại mô tả như sau:
1
2
3
1 4 6 120 4
6 DI A 7 5
2 13 12 3 B 6
7 R1IN R1OUT VCC 2 DE 1 7
3 14 11 RE RO 8
8 T1OUT T1IN
4 1 MAX485
9 C+ CON8
5 6 MAX232 3
V- C1- 10u
DB9 10u 4 6 4
R2OUT
T2OUT
2 C2+ 7 A DI
R2IN
T2IN
V+ 5 B 3
C2- 10u 1 DE 2 120
10u RO RE
8
10
VCC
MAX485
10u
Chương 5
GIAO TIẾP CỐNG SONG SONG
1. Cấu trúc cổng song song
Cổng song song gồm có 4 đường điều khiển, 5 đường trạng thái và 8 đường dữ liệu
bao gồm 5 chế độ hoạt động:
- Chế độ tương thích (compatibility).
- Chế độ nibble.
- Chế độ byte.
- Chế độ EPP (Enhanced Parallel Port).
- Chế độ ECP (Extended Capabilities Port).
3 chế độ đầu tiên sử dụng port song song chuẩn (SPP – Standard Parallel Port) trong
khi đó chế độ 4, 5 cần thêm phần cứng để cho phép hoạt động ở tốc độ cao hơn. Sơ đồ chân
của máy in như sau:
Cổng song song có ba thanh ghi có thể truyền dữ liệu và điều khiển máy in. Địa chỉ
cơ sở của các thanh ghi cho tất cả cổng LPT (line printer) từ LPT1 đến LPT4 được lưu trữ
trong vùng dữ liệu của BIOS. Thanh ghi dữ liệu được định vị ở offset 00h, thanh ghi trang
thái ở 01h, và thanh ghi điều khiển ở 02h. Thông thường, địa chỉ cơ sở của LPT1 là 378h,
LPT2 là 278h, do đó địa chỉ của thanh ghi trạng thái là 379h hoặc 279h và địa chỉ thanh ghi
điều khiển là 37Ah hoặc 27Ah. Tuy nhiên trong một số trường hợp, địa chỉ của cổng song
song có thể khác do quá trình khởi động của BIOS. BIOS sẽ lưu trữ các địa chỉ này như sau:
Chú ý rằng chân BUSY được nối với cổng đảo trước khi đưa vào thanh ghi trạng
thái, các bit SELECTIN , AUTOFEED và STROBE được đưa qua cổng đảo trước khi đưa
ra các chân của cổng máy in.
Thông thường tốc độ xử lý dữ liệu của các thiết bị ngoại vi như máy in chậm hơn PC
nhiều nên các đường ACK , BUSY và STR được sử dụng cho kỹ thuật bắt tay. Khởi đầu,
PC đặt dữ liệu lên bus sau đó kích hoạt đường STR xuống mức thấp để thông tin cho máy
in biết rằng dữ liệu đã ổn định trên bus. Khi máy in xử lý xong dữ liệu, nó sẽ trả lại tín hiệu
ACK xuống mức thấp để ghi nhận. PC đợi cho đến khi đường BUSY từ máy in xuống thấp
(máy in không bận) thì sẽ đưa tiếp dữ liệu lên bus.
Hình 5.1 - Trao đổi dữ liệu qua cổng song song giữa 2 PC dùng chế độ chuẩn
PC1 PC2
Chức năng Chân Chân Chức năng
D0 2 15 ERROR
D1 3 13 SELECT
D2 4 12 PAPER EMPTY
D3 5 10 ACK
D4 6 11 BUSY
BUSY 11 6 D4
ACK 10 5 D3
PAPER EMPTY 12 4 D2
SELECT 13 3 D1
ERROR 15 2 D0
GND 25 25 GND
Ngoài ra, việc kết nối giữa 2 máy tính sử dụng cổng song song có thể dùng chế độ
mở rộng, chế độ này cho phép giao tiếp với tốc độ cao hơn.
13 13
25 25
12 12
24 24
11 11
23 23
10 10
22 22
9 9
21 21
8 8
20 20
7 7
19 19
6 6
18 18
5 5
17 17
4 4
16 16
3 3
15 15
2 2
14 14
1 1
Hình 5.2 - Trao đổi dữ liệu qua cổng song song giữa 2 PC dùng chế độ mở rộng
PC1 PC2
Chức năng Chân Chân Chức năng
D0 2 2 D0
D1 3 3 D1
D2 4 4 D2
D3 5 5 D3
D4 6 6 D4
D5 7 7 D5
D6 8 8 D6
D7 9 9 D7
SELECT 13 17 SELECTIN
BUSY 11 16 INIT
ACK 10 1 STROBE
SELECTIN 17 13 SELECT
INIT 16 11 BUSY
STROBE 1 10 ACK
74LS06
9 8
1 STROBE
10K1
14
2 3 2 9
15 4 D0 Q0 5 8
3 7 D1 Q1 6 7
16 8 D2 Q2 9 6
4 13 D3 Q3 12 5 VCC
17 14 D4 Q4 15 4
5 17 D5 Q5 16 3
18 18 D6 Q6 19 2 1
6 D7 Q7
19 11
7 CLK
20 1
8 OE
21
9 74LS374
22
10 ACK
23
11 PAPER EMPTY 74LS257 SW0-7
10K
24
12 SELECT 4 2 2 3 9
25 74LS06 7 1Y 1A 5 5 Q0 D0 4 8
13 9 2Y 2A 11 6 Q1 D1 7 7
BUSY 2 1 12 3Y 3A 14 9 Q2 D2 8 6
4Y 4A 12 Q3 D3 13 5 VCC
3 15 Q4 D4 14 4
74LS06 1B 6 16 Q5 D5 17 3
2B 10 19 Q6 D6 18 2 1
AUTO FEED 3 4 3B 13 Q7 D7
4B 11
1 CLK
74LS06 A/B 15 1
G OE
SELECT IN 5 6
74LS374
Hình 5.3 – Mạch giao tiếp đơn giản thông qua cổng máy in
Giao diện:
Hình 5.4 – Giao diện của chưnơg trình giao tiếp với cổng máy in
Chương trình giao tiếp trên VB sử dụng thư viện liên kết động để trao đổi dữ liệu với
cổng máy in. Thư viện IO.DLL bao gồm các hàm sau:
- Hàm PortOut: xuất 1 byte ra cổng
End
Begin VB.CheckBox chkSW
Height = 375
Index = 7
Left = 1800
TabIndex = 17
Top = 3480
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 6
Left = 1800
TabIndex = 16
Top = 3000
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 5
Left = 1800
TabIndex = 15
Top = 2520
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 4
Left = 1800
TabIndex = 14
Top = 2040
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 3
Left = 1800
TabIndex = 13
Top = 1560
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 2
Left = 1800
TabIndex = 12
Top = 1080
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 1
Left = 1800
TabIndex = 11
Top = 600
Width = 1575
End
Begin VB.CheckBox chkSW
Height = 375
Index = 0
Left = 1800
TabIndex = 10
Top = 120
Width = 1575
End
Begin VB.CommandButton cmdExit
Caption = "Exit"
Height = 495
Left = 2400
TabIndex = 9
Top = 3960
Width = 975
End
Begin VB.CommandButton cmdSend
Caption = "Send"
Height = 495
Left = 0
TabIndex = 8
Top = 3960
Width = 1095
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED7"
Height = 375
Index = 7
Left = 240
TabIndex = 7
Top = 3480
Width = 1095
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED6"
Height = 375
Index = 6
Left = 240
TabIndex = 6
Top = 3000
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED5"
Height = 375
Index = 5
Left = 240
TabIndex = 5
Top = 2520
Width = 975
End
Top = 600
Width = 975
End
Begin VB.Label lblLED
BackStyle = 0 'Transparent
Caption = "LED0"
Height = 375
Index = 0
Left = 240
TabIndex = 0
Top = 120
Width = 975
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 7
Left = 840
Shape = 3 'Circle
Top = 3480
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 6
Left = 840
Shape = 3 'Circle
Top = 3000
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 5
Left = 840
Shape = 3 'Circle
Top = 2520
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 4
Left = 840
Shape = 3 'Circle
Top = 2040
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 3
Left = 840
Shape = 3 'Circle
Top = 1560
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 2
Left = 840
Shape = 3 'Circle
Top = 1080
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 1
Left = 840
Shape = 3 'Circle
Top = 600
Width = 375
End
Begin VB.Shape shpLED
BorderColor = &H000000FF&
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 375
Index = 0
Left = 840
Shape = 3 'Circle
Top = 120
Width = 375
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'IO.DLL
Private Declare Sub PortOut Lib "IO.DLL" (ByVal Port
As Integer, ByVal Data As Byte)
Dim s As String
t = 0
For i = 0 To 7
t = t + (2 ^ i) * (1 - shpLED(i).FillStyle)
Next i
PortOut BA_LPT, t
PortOut BA_LPT, 1 'STROBE = 1
PortOut BA_LPT, 0 'STROBE = 0
End Sub