1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Lập trình bàn phím docx

4 504 2

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 4
Dung lượng 66,5 KB

Nội dung

Ngắt 09h này có nhiệm vụ chuyển đổi mã quét thành mã ASCII và lưu trữ vào bộ đệm bàn phím.. Các chương trình có nhu cầu nhận thông tin từ bàn phím có thể sử dụng các hàm của ngắt 21h hoặ

Trang 1

Bài thực hành số 6

Lập trình bàn phím Mục đích

 Hiểu được cách thức hoạt động của bàn phím

 Biết cách sử dụng một số hàm liên quan đến bàn phím của ngắt 16h (BIOS ) và ngắt 21h (DOS)

Tóm tắt lý thuyết

Nguyên tắc hoạt động của bàn phím

Bàn phím cho máy PC có nhiều loại: 83 phím, 84 phím, 101 phím,… Bên trong mỗi bàn phím là chip điều khiển 8049 và 8042 Khi một phím được nhấn (up-to-down) hay được thả (down-to-up), chip điều khiển ghi nhận phím đó bằng một (hoặc một vài) mã số (gọi là mã quét, scan code) và gửi

mã này ra cổng 60h, đồng thời tạo tín hiệu ngắt IRQ1

Ví dụ:

- Khi phím chữ ‘a’ được nhấn rồi thả ra, ta nhận được 2 mã quét tương ứng là: 1E và 9E Thông thường, mã thả (up-code) bằng mã nhấn (down-code) cộng thêm 80h

- Tương tự, đối với Left-Control, 2 mã quét là 1D và 9D

- Tuy nhiên, với Right-Control, ta nhận được 4 mã quét: 0E 1D (khi nhấn) và 0E 9D (khi thả)

Tín hiệu IRQ1 gây ra ngắt 09h Ngắt 09h này có nhiệm vụ chuyển đổi mã quét thành mã ASCII

và lưu trữ vào bộ đệm bàn phím Các chương trình có nhu cầu nhận thông tin từ bàn phím có thể sử dụng các hàm của ngắt 21h hoặc 16h để đọc bộ đệm này mà không cần quan tâm đến giá trị của mã quét

Ví dụ: một chương trình nào đó chỉ cần dùng ngắt 16h, hàm 01 để kiểm tra xem người sử dụng

có gõ dấu chấm câu (nhấn phím ‘.’) hay không mà không quan tâm đến đó là phím dấu chấm ở phần keypad (scan code = 53) hay là ở phần các phím cơ bản (scan code = 34)

Khi được gọi, trình phục vụ ngắt 09h sẽ đọc cổng 60h để lấy mã quét Nếu phím được nhấn thuộc loại phím thường (ví dụ như các phím chữ a, b,…) mã quét sẽ được dịch ra mã ASCII tương ứng Sau đó, giá trị của mã quét và mã ASCII được lưu vào bộ đệm bàn phím Bộ đệm này có địa chỉ 0040h:001Eh, kích thước 16 word, được tổ chức như một mảng vòng với con trỏ đầu (head) lưu tại địa chỉ 0040h:001Ah, con trỏ cuối (tail) lưu tại địa chỉ 0040h:001Ch Nếu phím được nhấn là loại phím mở rộng (ví dụ như F1, F2,…), trong bộ đệm sẽ lưu giữ số 0 và mã mở rộng của phím đó

Ví dụ: Giả sử NumLock đang là OFF, bộ đệm bàn phím đang trống (head = tail = 0041Eh), khi

lần lượt ấn các phím ‘a’, F10, ‘·’, ‘NumLock’, ‘·’keypad, ‘NumLock’, ‘·’keypad, ‘Delete’ bộ đệm sẽ có

nội dung như sau:

↓ 0041Ch

a F10 · · (kp) · (kp) Delete

61

1E

00

44

2E 34

2E 53

00 53

E0 53 head ↑ tail ↑

Lưu ý rằng, việc nhấn phím NumLock không sinh ra một thông tin nào trong bộ đệm Hai phím dấu chấm cho cùng một mã ASCII là 2Eh Phím Delete cho cùng một mã mở rộng dù được nhấn trong chế độ NumLock là ON hay OFF

Trang 2

Một số hàm của ngắt 16h (BIOS)

AH = 00h Lấy một phím từ bộ đệm bàn phím Nếu bộ đệm trống, sẽ chờ cho đến khi một phím

được nhấn Trả về mã quét trong AH, mã ASCII (hoặc mã mở rộng) trong AL

AH = 01h Kiểm tra bộ đệm bàn phím Nếu trống, bật cờ ZF Nếu không trống, tắt cờ ZF, đọc

phím đầu tiên trong bộ đệm (trỏ đến bởi con trỏ head), trả về mã quét trong AH, mã ASCII (hoặc mã

mở rộng) trong AL Tuy nhiên, phím này không bị lấy ra khỏi bộ đệm

AH = 02h Kiểm tra tình trạng các phím đặc biệt Hàm này trả về byte ở địa chỉ 0040h:0017h.

Các bit (I,C,N,S,A,O,L,R) của byte này, tính từ cao xuống thấp, ứng với các phím:

Phím nào ở trạng thái ON thì bit tương ứng sẽ bật

AH = 03h Thay đổi tốc độ nhận phím AL = 05h, BH = thời gian đợi trước khi lặp, BL = tần số

lặp BH có thể nhận các giá trị từ 0 (250ms) đến 3 (1000 ms) BL có thể nhận các giá trị từ 0 (30 lần/giây) đến 1Fh (2 lần/giây)

AH = 05h Giả lập thao tác nhấn phím CH = mã quét, CL = mã ASCII (hoặc mã mở rộng) Hàm

này ghi giá trị của CH và CL vào bộ đệm bàn phím và trả về AL = 0, nếu bộ đệm còn chỗ trống Trả

về AL = 1 nếu không còn chỗ trống

Một số hàm của ngắt 21h (DOS)

AH = 01h Đợi một phím được nhấn và trả lại mã ASCII của phím đó trong thanh ghi AL, đồng

thời hiển thị kí tự lên màn hình Nếu đây là phím không có mã ASCII mà chỉ có mã mở rộng thì AL trả về 0 Để nhận được mã mở rộng, cần phải gọi hàm này một lần nữa Nếu Ctrl-Break được nhấn thì ngắt 23h sẽ được gọi

AH = 08h Hàm này chỉ khác hàm 01h ở chỗ không thể hiện lên màn hình kí tự ứng với phím

được nhấn

AH = 07h Hàm này khác hàm 08h ở chỗ không kiểm tra Ctrl-Break.

AH = 0Ah Nhập từ bàn phím một xâu kí tự có độ dài không quá N kí tự, kết thúc bởi mã 13h

(phím Enter) Vùng bộ nhớ để lưu trữ xâu kí tự phải được chuẩn bị trước ở địa chỉ DS:DX Byte đầu tiên ở địa chỉ này phải lưu giá trị N Khi trả về, byte thứ hai lưu độ dài xâu nhận được (không kể kí

tự kết thúc 13h, mặc dù kí tự này vẫn được lưu vào vùng nhớ)

AH = 0Ch Xóa sạch bộ đệm bàn phím và gọi một trong các hàm 01h, 07h, 08h, 0Ah Trong AL

lưu số hiệu của hàm cần gọi

Tài liệu tham khảo

1 Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 10, ĐHKHTN, 2002

2 Randal Hyde, The art of assembly language programming – Chapter 20

3 Dan Rollins, TechHelp v.6.0

Bài tập

Bài 1 KeyDetection Sử dụng các hàm liên quan đến bàn phím của ngắt 16h Viết chương trình kiểm tra xem có phím chữ cái nào được nhấn không, nếu có thì dùng chữ đó để in đầy màn hình Nếu không thì tiếp tục in đầy màn hình bằng chữ cái được nhấn ở lần trước Nhấn Esc để kết thúc

Bài 2 Phím gõ tắt Sử dụng các hàm liên quan đến bàn phím của ngắt 21h, viết chương trình cho phép nhập từ bàn phím một xâu kí tự độ dài không quá 79 Trong quá trình nhập, nếu người dùng nhấn phím F1, chương trình sẽ tự động chèn vào cụm từ “DH KHTN Tp.HCM”, nếu nhấn phím F2 chương trình sẽ tự động chèn vào cụm từ “Khoa CNTT – BM MMT&VT” Cho phép dùng BackSpace để sửa lỗi Khi nhập xong, in ra độ dài của xâu kí tự đó

Mở rộng

1 Trong bài tập 1, khi người dùng nhấn một chữ cái nào đó, thì chữ cái đó có lập tức xuất hiện trên màn hình không ? Có thể giải thích như thế nào về khoảng thời gian trễ này ?

2 Trong bài tập 2, làm sao để cho phép ngay sau khi nhấn F1 để thêm cụm từ, có thể nhấn Esc

để bỏ đi cụm từ vừa thêm

3 Để vượt qua giới hạn 79 kí tự trong bài tập 2, cần biết thêm kĩ thuật gì ?

Trang 3

4 Viết một chương trình cho phép xem nội dung của bộ đệm bàn phím Dùng chương trình đó

để quan sát sự thay đổi của bộ đệm khi bấm phím

Hướng dẫn

Bài 1 Dùng hàm 01 của ngắt 16h để kiểm tra bộ đệm Tuy nhiên phải nhớ rằng hàm này không lấy

phím được nhấn ra khỏi bộ đệm bàn phím Vì vậy, sau khi phát hiện có phím được nhấn, có thể gọi hàm 00 để lấy phím ra khỏi bộ đệm

Ví dụ:

NextKey:

;

; trong khi chưa có phím nào được nhấn,

; ta xử lí những việc khác ở đây

;

mov ah,1 ; kiểm tra bộ đệm

int 16h

jz NextKey ; vẫn không có gì, quay lại

mov ah,0

int 16h ; lấy ra khỏi bộ đệm

;

; xử lí phím vừa nhận ở đây

jmp NextKey

Bài 2 Tạo một mảng 80 kí tự Dùng hàm 8 của ngắt 21h để kiểm tra phím nào được nhấn Nếu là

phím có ASCII code khác 0, lưu vào mảng đồng thời in ra màn hình Nếu là phím đặc biệt, gọi hàm

8 lần nữa để lấy mã mở rộng Sau đó kiểm tra F1 hay F2 được nhấn để chèn cụm từ cần thiết vào mảng

Ví dụ: Để xử lí nhập xâu và chèn macro, tham khảo đoạn chương trình sau

mac1 db 'DH KHTN Tp.HCM$'

mac2 db 'Khoa CNTT - BM MMT&VT$'

NextKey:

mov ah,8 ; chờ nhấn phím, không hiển thị

int 21h

cmp al,0

jnz NotSpec ; nếu là phím thường

int 21h

cmp al,3bh

jz InsMac1

cmp al,3ch

jz InsMac2

jmp NextKey

InsMac1:

mov bx,offset mac1

jmp InsMac

InsMac2:

mov bx,offset mac2

jmp InsMac

; thêm các macro khác ở đây

Trang 4

;

InsMac:

call Insert ; chèn macro ở DS:BX vào mảng

jmp NextKey

NotSpec:

;

; lưu kí tự vào mảng

;

Để cho phép sửa chữa bằng Esc, có thể kiểm tra mã ASCII, nếu là 8, viết ra 3 kí tự có mã ASCII lần lượt là 8,32,8 (3 kí tự này có nghĩa là: lùi con trỏ, viết khoảng trắng để xóa, lùi con trỏ lần nữa) Đồng thời phải giảm giá trị của biến lưu trữ độ dài xâu hiện thời

Ví dụ: Để bổ sung tính năng dùng BckSpc, tham khảo đoạn chương trình sau:

BckSpc db 8,32,8,'$'

cmp al,8

jnz InsChar ; nếu không phải BckSpc, lưu

cmp si,0 ; kiểm tra độ dài xâu hiện thời

jz NextKey

mov dx,offset BckSpc ; xóa kí tự trên màn hình

printSt

jmp NextKey

InsChar:

cmp si,maxLen ; dài quá 79 ?

jz NextKey

mov buffer[si],al ; lưu vào mảng

inc si

jmp NextKey

Ví dụ: Để in ra độ dài xâu vừa nhập (<80, là số nguyên có hai chữ số), có thể viết như sau:

printUInt macro

push ax

push bx

push dx

mov bh,10

div bh

mov bx,ax

mov dl,bl

add dl,48

mov ah,2

int 21h

mov dl,bh

add dl,48

mov ah,2

int 21h

pop dx

pop bx

pop ax

endm

Không quên kiểm tra độ dài xâu hiện thời trước mỗi thao tác thêm, bớt kí tự trong mảng !

Ngày đăng: 25/01/2014, 13:20

HÌNH ẢNH LIÊN QUAN

mov dx,offset BckSpc ; xóa kí tự trên màn hình printSt - Tài liệu Lập trình bàn phím docx
mov dx,offset BckSpc ; xóa kí tự trên màn hình printSt (Trang 4)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w