View Full Version : KEYPAD nhờ giúp đở....
phamthanhkhuyen
12-06-2007, 12:53 PM
dưới đây là trích trong Tutorial 9.1 - Nigel Goodwin 2003
tôi ghi chú lại nhưng tôi thấy trong đoạn Chk_Keys ở dòng lệnh thứ 6 hình như viết sai thì phải mong các bạn chỉ giúp
;KEYPAD16
;trich trong Tutorial 9.1 - Nigel Goodwin 2003
;Keypad reading with LCD display
;chu thich lai boi PHAM THANH KHUYEN
;ngay 11/06/2207
LIST p=16F628A ;tell assembler what chip we are using
include "P16F628A.inc" ;include the deFaults For the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__conFig 0x3D18 ;sets the conFiguration settings (oscillator type etc.)
;................................................. ..................
cblock 0x20 ;start oF general purpose registers
;cac bien cua Delay
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
;cac bien cua Keypad
key
rows
endc
;................................................. ................
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used For keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3
;................................................. ....................
;GHI CHU : sau khi thuc hien xong doan chuong trinh Chk_Keys
;ta duoc gia tri cua phim nhan nam o trong W va trong bien Key
;Keypad subroutine
Chk_Keys movlw 0x00 ;wait until no key pressed (doi cho den khi khong co phim nhan)
movwF KEY_PORT ;set all output pins low out out out out in in in in = 0000 xxxx
movF KEY_PORT, W ;read port B
andlw 0x0F ;mask oFF high byte (che 4 bit cua byte cao)
sublw 0x0F
; ??????????????????????????????????????
btFsc STATUS, Z ;test iF any key pressed
;thay bang BTFSS STATUS,Z ????
goto Keys ;iF none, read keys
call Delay20 ;
goto Chk_Keys ;else try again
;Cac chan cua port Keypad
; out out out out in in in in
; col1 col2 col3 col4 row1 row2 row3 row4
; RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
Keys call Scan_Keys
movlw .16 ;check For no key pressed 16
subwF key, w ;neu Key=.16 co nghia la khong co phim nao nhan
btFss STATUS, Z
goto Key_Found ;Key <>.16
call Delay20
goto Keys
Key_Found movF key, w
andlw 0x0F
call Key_Table ;lookup key in table
movwF key ;save back in key
return ;key pressed now in W
;................................................. ................
Scan_Keys clrF key
movlw 0xF0 ;set all output lines high
movwF KEY_PORT ;11110000
movlw .4 ;
movwF rows ;set number oF rows
bcF STATUS, C ;put a 0 into carry
Scan rrF KEY_PORT, F ;0111xxxx 1011xxxx 1101xxxx 1110xxxx
bsF STATUS, C ;Follow the zero with ones
;comment out next two lines For 4x3 numeric keypad.
btFss KEY_PORT, Col4 ;Col4 equ 3 cccc1xxx
goto Press ; cccc0xxx
incF key, F ;
btFss KEY_PORT, Col3 ;Col3 equ 2 ccccx1xx
goto Press ; ccccx0xx
incF key, F ;
btFss KEY_PORT, Col2 ;Col2 equ 1 ccccxx1x
goto Press ; ccccxx0x
incF key, F ;
btFss KEY_PORT, Col1 ;Col1 equ 0 ccccxxx1
goto Press ; ccccxxx0
incF key, F ;
decFsz rows, F ;
goto Scan ;
Press return
;khi ket thuc Scan_Keys ta duov 1 gia tri cua Key
;end oF keypad subroutines.
;................................................. ...................
Key_Table ADDWF PCL,F
RETLW 0x43 ;C col1 col2 col3 col4
RETLW 0x42 ;B row4 C D E F
RETLW 0x30 ;0 row3 B 9 6 3
RETLW 0x41 ;A row2 0 8 5 2
RETLW 0x44 ;D row1 A 7 4 1
RETLW 0x39 ;9
RETLW 0x38 ;8
RETLW 0x37 ;7
RETLW 0x45 ;E
RETLW 0x36 ;6
RETLW 0x35 ;5
RETLW 0x34 ;4
RETLW 0x46 ;F
RETLW 0x33 ;3
RETLW 0x32 ;2
RETLW 0x31 ;1
;................................................. ...................
;DEYLAY
Delay255 movlw 0xFF ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwF count1
d1 movlw 0xC7 ;delay 1mS
movwF counta
movlw 0x01
movwF countb
Delay_0
decFsz counta, F
goto $+2
decFsz countb, F
goto Delay_0
decFsz count1 ,F
goto d1
retlw 0x00
end
falleaf
12-06-2007, 01:01 PM
Bạn phải xem là khi Nigel nhấn nút đó, thì nút đó được kéo xuống mass hay là được kéo lên.
Chúc vui
phamthanhkhuyen
12-06-2007, 08:25 PM
đây là sơ đồ phần cứng keypad
http://www.winpicprog.co.uk/pic_tutorial_keypad_board.htm
falleaf
20-06-2007, 02:43 PM
Nút có trở kéo lên. Như vậy khi bấm nút thì nó sẽ kéo xuống. Như vậy nút bấm tương ứng với việc kiểm tra xem nếu bấm xuống, có clear thì dùng BTFSC (nhảy nếu mà bit clear).
Nếu thấy nút bị bấm xuống, thì đoạn của Nigel viết là call delay20, sau đó kiểm tra xem nút đó là nút gì (ChkKeys).
Còn chi tiết thuật toán thì F không rõ vì không có thời gian xem. Nếu không bấm xuống thì nó nhảy vào đoạn hàm Keys.
Nếu đọc theo ghi chú của Nigel thì không thấy có gì sai.
Chúc vui
phamthanhkhuyen
23-06-2007, 09:07 PM
trong đoạn chương trình trên:
khi có phím bấm --> delay20---> Chk_keys
thì chương trình sẽ vào vòng lập cho đến khi nào không có phím nhấn thì nó sẻ vào đoạn hàm Key để đọc xem phím đó là phím gì
Nhưng khổ nổi không có phím nhấn thì lấy gì mà đọc!!!!
còn khi có phím nhấn lạl kiểm tra lại ?
Chunhatonline
24-06-2007, 10:51 AM
delay nhiều thế không bắt nổi phím!
Jerry
08-08-2007, 03:51 PM
Tôi cũng sử dụng chương trình của Nigel để điều khiển keypad nhưng tôi đang phân vân vì không thấy chương trình này có phần xử lý chống nảy phím. Vì vậy tôi rất muốn hỏi các bạn đã từng xử lý bàn phím kiểu này xem kinh nghiệm các bạn làm như thế nào (viết bằng ASM). Rất mong sự phản hồi từ các bạn.
Jerry
09-08-2007, 12:05 PM
Thiết kế của tớ như sau:
- Phần cứng: theo sơ đồ đính kèm
- Phần mềm:
Init_port:
clrf PORTD
movlw 0xF0 ; Row: output (RD0-3), Col: Input (RD4-7)
movwf TRISD
MainProg:
clrwdt
clrf key
call Chk_Keys
movf key, w
call WriteData ; Hiển thị lên LCD
goto MainProg
;Keypad subroutine
Chk_Keys
movlw .0 ;wait until no key pressed
movwf PORTD ;set all output pins (row) low
movf PORTD,0
andlw 0xF0
sublw 0xF0
skpnz ; test if any key pressed
goto Keys ; if none, read keys
movlw 0x14
call Delay1ms ; delay20ms
return
Keys
call Scan_Keys
movlw 0x10 ;check for no key pressed
subwf key, w
btfss STATUS, Z
goto Key_Found
movlw 0x14
call Delay1ms
goto Keys
Key_Found:
movf key,w
andlw 0x0f
movwf temp
call Key_Table ;lookup key in table
movwf key ;save back in key
return ;key pressed now in W
Scan_Keys
movlw 0x0F
movwf PORTD ;set all output lines high
movlw 0x04
movwf rows ;set number of rows
bcf STATUS, C ;put a 0 into carry
Scan
rrf PORTD,1
bsf STATUS, C ;follow the zero with ones
;comment out next two lines for 4x3 numeric keypad.
btfss Col4
return
incf key,1
btfss Col3
return
incf key,1
btfss Col2
return
incf key,1
btfss Col1
return
incf key,1
decfsz rows,1
goto Scan
return
Key_Table
movlw high(Key_Table)
movwf PCLATH
movf temp,0
addwf PCL,1
retlw 'C'
retlw 'B'
retlw '0'
retlw 'A'
retlw 'D'
retlw '9'
retlw '8'
retlw '7'
retlw 'E'
retlw '6'
retlw '5'
retlw '4'
retlw 'F'
retlw '3'
retlw '2'
retlw '1'
Mục đích chương trình của tớ như sau: Khi có phím bất kỳ được ấn thì sẽ hiển thị lên màn hình LCD. Phần điều khiển hiển thị LCD tớ đã làm và chạy tốt. Tuy nhiên phần keypad này thì không chạy đúng với ý tưởng của tớ. Đầu tiên cắm điện thì nó không hiện gì. Bấm 1 nút bất kỳ thì nó hiện khoảng 4 ký tự C, sau đó là khoảng 6 ký tự ô vuông đen xì, sau đó lại 1 loạt ký tự C nữa. Vậy chương trình của tớ sai ở chỗ nào? Cần phải sửa những gì để nó chạy đúng ý tưởng của tớ? Rất mong được các bạn giúp đỡ
Jerry
09-08-2007, 12:08 PM
Xin nhờ mod edit lại giúp tớ vì tớ không biết post code làm sao cho dễ nhìn
namqn: việc này tôi đã từng hướng dẫn bạn trong một post cũ của bạn. Khi bạn viết bài trả lời thì phía trên khung soạn thảo sẽ có 2 hàng nút công cụ, nút có ký hiệu '#' dùng để định dạng code. Bạn chọn đoạn code cần định dạng, sau đó nhấn vào nút đó (thực chất việc làm này chỉ thêm phần tag [code] vào phía đầu và [ /code] vào phía cuối đoạn văn bản được định dạng thành code, tag [ /code] khi viết đúng sẽ không có khoảng trắng giữa hai dấu []).
Jerry
14-08-2007, 10:55 AM
Cảm ơn namqn đã giúp đỡ và mình đã biết là phải làm như vậy. Tuy nhiên trong khung soạn thảo (khung lớn hẳn hoi) mình không tìm thấy ký hiệu "#". Không hiểu tại sao lại như vậy nữa. Nhưng có lẽ mình sẽ làm theo cách thứ 2 mà bạn đã chỉ dẫn là thêm phần tag [code] vào phía đầu và [ /code] vào phía cuối đoạn văn bản được định dạng thành code. Cảm ơn bạn và mình sẽ rút kinh nghiệm lần sau.
david
17-08-2007, 09:35 AM
http://picspirate.com/img123/img54/c8a3c5626d6cc16ffafdb57a2eb4d07a/keypad4x4.jpg (http://picspirate.com)
;================================================= =======
TITLE "KEYPAD_4X4"
PROCESSOR P16F877A
INCLUDE <P16F877A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF & _LVP_OFF
;================================================= =========
;Khai bao bien :
COT EQU 0X20
HANG EQU 0X21
QUET EQU 0X22
DEM EQU 0X23
HANG1 EQU 4
HANG2 EQU 5
HANG3 EQU 6
HANG4 EQU 7
;================================================= ============
;Chuong trinh chinh
;================================================= ============
ORG 0X0000
GOTO MAIN
ORG 0X0005
MAIN
BANKSEL TRISA
CLRF TRISB
CLRF TRISD
BANKSEL PORTA
CLRW
MOVWF PORTB
MOVWF PORTD
MOVWF COT
MOVWF HANG
MOVWF DEM
MOVLW B'00000001'
MOVWF QUET
LOOP
MOVF QUET,0
MOVWF PORTB
BANKSEL TRISA
MOVLW B'11110000'
MOVWF TRISB
BANKSEL PORTB
BTFSC PORTB,HANG1
CALL HANG1_SFR
BTFSC PORTB,HANG2
CALL HANG2_SFR
BTFSC PORTB,HANG3
CALL HANG3_SFR
BTFSC PORTB,HANG4
CALL HANG4_SFR
INCF DEM,1
MOVF DEM,0
XORLW D'4'
BTFSC STATUS,Z
RETLW 0X00
RLF QUET
BANKSEL TRISB
CLRF TRISB
BANKSEL PORTB
GOTO LOOP
HANG1_SFR
MOVF COT,0
CALL TABLE
MOVWF PORTD
RETURN
HANG2_SFR
MOVF COT,0
ADDLW D'4'
CALL TABLE
MOVWF PORTD
RETURN
HANG3_SFR
MOVF COT,0
ADDLW D'8'
CALL TABLE
MOVWF PORTD
RETURN
HANG4_SFR
MOVF COT,0
ADDLW D'12'
CALL TABLE
MOVWF PORTD
RETURN
;-----------------------------------------------------------------
TABLE
ADDWF PCL, F ; bat dau tai 0x80
RETLW b'00111111' ; 0
RETLW b'00000110' ; 1
RETLW b'01011011' ; 2
RETLW b'01001111' ; 3
RETLW b'01100110' ; 4
RETLW b'01101101' ; 5
RETLW b'01111101' ; 6
RETLW b'00000111' ; 7
RETLW b'01111111' ; 8
RETLW b'01101111' ; 9
RETLW b'01110111' ; A
RETLW b'01111100' ; B
RETLW b'00111001' ; C
RETLW b'01011110' ; d
RETLW b'01111001' ; E
RETLW b'01110001' ; F
END
em debug băng MPLABSIM thì thấy đúng như ý tưởng của mình,nhưng kô mô phỏng được,các bác coi dùm nhé
Jerry
29-08-2007, 11:49 AM
Tớ chưa có thời gian đọc chương trình của cậu nhưng tớ thấy đây có thể là 1 lỗi:
- Phần cứng của cậu ko có điện trở treo ở các chân đọc về (input). Trong phần mềm cũng không thấy định nghĩa điện trở pull up của cổng B (RBPU). Cần có điện trở treo ở input để khi ko có phím bấm -> đọc được mức logic 1, khi có phím -> đọc được mức logic 0.
- Chưa có phần trễ chống nảy phím
uydanh
20-10-2007, 01:12 AM
dưới đây là trích trong Tutorial 9.1 - Nigel Goodwin 2003
tôi ghi chú lại nhưng tôi thấy trong đoạn Chk_Keys ở dòng lệnh thứ 6 hình như viết sai thì phải mong các bạn chỉ giúp
;KEYPAD16
;trich trong Tutorial 9.1 - Nigel Goodwin 2003
;Keypad reading with LCD display
;chu thich lai boi PHAM THANH KHUYEN
;ngay 11/06/2207
LIST p=16F628A ;tell assembler what chip we are using
include "P16F628A.inc" ;include the deFaults For the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__conFig 0x3D18 ;sets the conFiguration settings (oscillator type etc.)
;................................................. ..................
cblock 0x20 ;start oF general purpose registers
;cac bien cua Delay
count1 ;used in delay routine
counta ;used in delay routine
countb ;used in delay routine
;cac bien cua Keypad
key
rows
endc
;................................................. ................
KEY_PORT Equ PORTB ;keypad port
KEY_TRIS Equ TRISB
Col1 Equ 0 ;pins used For keypad inputs
Col2 Equ 1
Col3 Equ 2
Col4 Equ 3
;................................................. ....................
;GHI CHU : sau khi thuc hien xong doan chuong trinh Chk_Keys
;ta duoc gia tri cua phim nhan nam o trong W va trong bien Key
;Keypad subroutine
Chk_Keys movlw 0x00 ;wait until no key pressed (doi cho den khi khong co phim nhan)
movwF KEY_PORT ;set all output pins low out out out out in in in in = 0000 xxxx
movF KEY_PORT, W ;read port B
andlw 0x0F ;mask oFF high byte (che 4 bit cua byte cao)
sublw 0x0F
; ??????????????????????????????????????
btFsc STATUS, Z ;test iF any key pressed
;thay bang BTFSS STATUS,Z ????
goto Keys ;iF none, read keys
call Delay20 ;
goto Chk_Keys ;else try again
;Cac chan cua port Keypad
; out out out out in in in in
; col1 col2 col3 col4 row1 row2 row3 row4
; RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
Keys call Scan_Keys
movlw .16 ;check For no key pressed 16
subwF key, w ;neu Key=.16 co nghia la khong co phim nao nhan
btFss STATUS, Z
goto Key_Found ;Key <>.16
call Delay20
goto Keys
Key_Found movF key, w
andlw 0x0F
call Key_Table ;lookup key in table
movwF key ;save back in key
return ;key pressed now in W
;................................................. ................
Scan_Keys clrF key
movlw 0xF0 ;set all output lines high
movwF KEY_PORT ;11110000
movlw .4 ;
movwF rows ;set number oF rows
bcF STATUS, C ;put a 0 into carry
Scan rrF KEY_PORT, F ;0111xxxx 1011xxxx 1101xxxx 1110xxxx
bsF STATUS, C ;Follow the zero with ones
;comment out next two lines For 4x3 numeric keypad.
btFss KEY_PORT, Col4 ;Col4 equ 3 cccc1xxx
goto Press ; cccc0xxx
incF key, F ;
btFss KEY_PORT, Col3 ;Col3 equ 2 ccccx1xx
goto Press ; ccccx0xx
incF key, F ;
btFss KEY_PORT, Col2 ;Col2 equ 1 ccccxx1x
goto Press ; ccccxx0x
incF key, F ;
btFss KEY_PORT, Col1 ;Col1 equ 0 ccccxxx1
goto Press ; ccccxxx0
incF key, F ;
decFsz rows, F ;
goto Scan ;
Press return
;khi ket thuc Scan_Keys ta duov 1 gia tri cua Key
;end oF keypad subroutines.
;................................................. ...................
Key_Table ADDWF PCL,F
RETLW 0x43 ;C col1 col2 col3 col4
RETLW 0x42 ;B row4 C D E F
RETLW 0x30 ;0 row3 B 9 6 3
RETLW 0x41 ;A row2 0 8 5 2
RETLW 0x44 ;D row1 A 7 4 1
RETLW 0x39 ;9
RETLW 0x38 ;8
RETLW 0x37 ;7
RETLW 0x45 ;E
RETLW 0x36 ;6
RETLW 0x35 ;5
RETLW 0x34 ;4
RETLW 0x46 ;F
RETLW 0x33 ;3
RETLW 0x32 ;2
RETLW 0x31 ;1
;................................................. ...................
;DEYLAY
Delay255 movlw 0xFF ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
d0 movwF count1
d1 movlw 0xC7 ;delay 1mS
movwF counta
movlw 0x01
movwF countb
Delay_0
decFsz counta, F
goto $+2
decFsz countb, F
goto Delay_0
decFsz count1 ,F
goto d1
retlw 0x00
end
Tôi cũng nghĩ như bạn phamthanhkhuyen. Lệnh BTFSC status,Z có nghĩa là nếu không có phím được nhấn thì kết quả phép trừ ra 0, cờ Z=1 thì lệnh goto keys được thực hiện. Thật kỳ là, không có phím được nhấn thì vào kiểm tra phím nhấn làm gì???? Rất mong mọi người giải thích để mình có cách hiểu đúng về vấn đề này. XIn cảm ơn.
uydanh
16-11-2007, 11:12 PM
Sau một tháng học PIC và tìm hiểu đoạn code trên của Nigel-đoạn code mà phamthanhkhuyen và mình đều rất không hiểu cái đoạn chk_keys : vì sao lại nhảy vào đoạn chương trình key khi không phát hiện thấy có phím nhấn, và tại sao phát hiện có phím nhấn lại nhảy đi check lại có nhấn phím hay không. Thật khó hiểu phải không các bạn? Chắc các bạn trên diễn đàn đều biết hết rồi, tới hôm nay mình mới hiểu vì sao như vậy. Mình cũng xin post giải thích lên đây luôn, để anh em nào đã từng ở trong vòng luẩn quẩn như mình và phamthanhkhuyen đỡ mất công tìm hiểu lại.
Câu trả lời đơn giản thế này :vì bác Nigel kỹ tính quá, trước khi bắt phím nhấn, bác Nigel lại đi kiểm tra thử trong 16 cái phím của bạn có phím nào bị kẹt không? Nghĩa là có phím nào bị nhấn ngoài mong muốn không? Nếu có thì nó cứ lặp vòng hoài , còn không bị kẹt phím mới nhảy vào đoạn chương trình tiếp theo xem thử phím nào được nhấn.
Phần code còn lại tương đối dễ hiểu. Mình đã thử đoạn code trên, nó chạy rất tốt.
Cảm ơn vì đã đọc chút đóng góp của mình, cũng coi như lời cảm ơn của mình đến diễn đàn PICVN.
Chúc thành công!
Jerry
17-11-2007, 08:18 AM
@uy danh: Bạn có thể post đoạn chương trình mà bạn viết lên đây được không? Coi như tài liệu tham khảo cho những người đi sau.
Bạn có thể post đoạn chương trình mà bạn viết lên đây được không? Coi như tài liệu tham khảo cho những người đi sau.[/QUOTE]
TÀI LIỆU ĐÂY:
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.