Chống rung cho phím

Một phần của tài liệu HƯỚNG DẪN SỬ DỤNG KIT 8051 (Trang 47 - 51)

Mục đích:

Nắm vững kĩ thuật chống rung cho phím.

Yêu cầu:

Viết chương trình xuất số đếm ra led 7 đoạn với giá trị khởi tạo là 0. Khi nhấn nút 1 (được nối với P3.0) thì giá trị này tăng lên 1, tăng đến 9 thì quay trở lại 0.

6.1 Nguyên lý chống rung

Hình trên minh hoạ mức điện áp của 1 phím nhấn tích cực mức 0, ở trạng thái bình thường, điện áp vi điều khiển nhận vào là 5V còn khi nhấn là 0V. Tuy nhiên, do độ rung cơ học của phím, tại thời điểm vừa nhấn xuống, điện áp sẽ không ổn định trong 1 khoảng thời gian, trước khi ổn định ở mức 0V. Hiệu tượng này gọi là rung phím.

Mặc dù khoảng thời gian điện áp ở mức 0 trong giai đoạn rung phím là nhỏ nhưng cũng đủ để vi điều khiển nhận được. Vì vậy khi ta xét nếu điện áp là 0 thì gọi hàm func() thì hàm này sẽ được gọi rất nhiều lần, là điều mà ta không mong muốn. Để khác phục hiện tượng rung phím, có 2 hướng giải quyết : dùng phần cứng và phần mềm.

Về giải pháp phần cứng : thay vì mắc đơn giản như kit thí nghiệm này (xem lại sơ

đồ ở Bài 2), ta có thể dùng thêm tụ điện để hạn chế việc thay đổi điện áp đột ngột, sơ đồ nguyên lý như sau:

Ở sơ đồ trên, khi không nhấn là mức 1, khi nhấn là mức 0. Phím nhấn trên tích cực mức 0. Mạch ở trên cịn gọi là mạch RC.

Nếu nút nhấn có 2 cực (3 chân), ta có thể chọn giải pháp dùng mạch RS flip flop, đây là mạch phần cứng chống rung tốt nhất, sơ đồ nguyên lý như sau:

Về giải pháp phần mềm : Ta sẽ định kì đọc tín hiệu từ nút nhấn, cho đến khi nào chúng trùng nhau n lần thì mới xử lý. Hình dưới đây minh hoạ trong trường hợp 2 lần là 0 thì mới xác nhận là phím được nhấn và mới xử lý tác vụ mà ta mong muốn.

Khoảng thời gian giữa 2 lần đọc là khoảng 10ms, ta sẽ hiện thực hàm đọc này và gọi nó trong timer. Giải thuật đơn giản để xử lý chống rung có thể hiện thực như sau:

previous_key = current_key; current_key = Port_key;

If(previous_key == current_key) effective_key = current_key;

Trong đó :

previous_key : biến lưu giá trị phím trước đó. current_key : biến lưu giá trị phím hiện tại.

Port_key : Port của vi điều khiển kết nối với phím.

effective_key : giá trị phím hợp lệ (giá trị trong giai đoạn ổn định)

Để tăng tính chính xác, ta có thể dùng nhiều biến previous_key để lưu lại các giá trị và so sánh nhiều lần. Đoạn code trên chỉ so sánh trùng nhau 2 lần.

6.2 Kết nối phần cứng

BKIT HARDWARE CLUB www.bkit4u.com 49 Phím nhấn này tính cực mức 0, được kết nối khá đơn giản, nên ta sẽ dùng phần mềm để chống rung. Ta sẽ dùng 3 biến để so sánh 2 lần trùng nhau, 2 lần liên tiếp cách nhau 10ms.

Trong trường hợp nhấn đè 1 phím, ta sẽ dùng biến TimeOutForKeyPress để xác định thời gian tích cực tiếp theo. Biến này sẽ quan trọng trong trường hợp ta viết 1 ứng dụng chẳng hạn như soạn thảo văn bản. Nếu khơng có biến này để quản lý, nếu ta đè thì trong 1s có tới 100 lần tích cực. Trong ví dụ của Bài 6, thời gian TimeOutForKeyPress =

100 tương ứng với 1s (100*10 = 1000ms = 1s). 6.3 Viết chương trình

Module này có 2 hàm như sau :

void initKey() : Khởi động các thông số ban đầu

void getKey() : Hàm này được gọi trong timer0, dùng để quét phím.

void SubKeyProcess() : Hàm này hiện thực tác vụ bạn cần thực hiện khi

nhấn phím.

Ở kit thí nghiệm này, các nút nhấn được nối với port 3, nên ta có định nghĩa sau ở đầu file key.c :

#define KEY_PORT P3 6.3.1 Hàm initKey() void initKey() { KeyReg0 = 0x00; KeyReg1 = 0x00; KeyReg2 = 0x00; KeyReg3 = 0x00; }

Trong đó KeyReg0, KeyReg1, KeyReg2 dùng để lưu 3 lần liên tiếp. Khi 3 biến này bằng nhau, biến KeyReg3 mới được cập nhật. Biến KeyReg3 là giá trị hợp lệ của phím nhấn.

6.3.2 Hàm getKey()

Hàm này được chia làm 2 phần, phần đầu là để chống rung phím dùng 2 lần so sánh trùng nhau. Phần thứ 2 xử lý khi 1 phím được đè, phải sau 1 khoảng thời gian TimeOutForKeyPress mới được tính cực.

void getKey() {

KeyReg2 = KeyReg1; KeyReg1 = KeyReg0;

KeyReg0 = KEY_PORT;// Cho phep nut nhan nao duoc tich cuc. if ((KeyReg1 == KeyReg0) && (KeyReg1 == KeyReg2))

{ TimeOutForKeyPress --; if (TimeOutForKeyPress == 0) { KeyReg3 = 0x00; } if (KeyReg2 != KeyReg3) { KeyReg3 = KeyReg2;

if (FlagFirstTimeKeyPress == 1)// Day la lan dau phim duoc nhan. { TimeOutForKeyPress = 100; SubKeyProcess(); FlagFirstTimeKeyPress = 0; } else { if (KeyReg2 == 0x00) FlagFirstTimeKeyPress = 1; else { TimeOutForKeyPress = 100; SubKeyProcess(); } } } } }

BKIT HARDWARE CLUB www.bkit4u.com 51

Một phần của tài liệu HƯỚNG DẪN SỬ DỤNG KIT 8051 (Trang 47 - 51)