Dennis Crawley says:
The diagram below shows how this can be done, by connecting the row/column lines of the keypad to resistors so that each key (the X's in the diagram below) results in a different resistance value. This resistance is connected, along with a load resistor (the 22K shown below), in a voltage divider between Vcc and ground; each key gives a different voltage, thus a different A/D reading.Observations:
- It requires 1% resistors, but it could be tested with normal 20% tolerance.
- It's very stable with voltage fluctuations.
- Since keyboards come with some resistance 80-100 ohms, and they tend to grow, the soft need some calibration as well as keyboard change over the time,...
Basically, the program transmit each key pressed to a terminal, so the programmer can see the key real value. Once he/she *calibrate* the range the pic is ready to use.
;********************************************** LIST P=PIC16F873,F=INHX8M,R=DEC #INCLUDE P16F873.INC __CONFIG _HS_OSC&_WDT_OFF&_CP_OFF&_PWRTE_ON&_BODEN_ON&_LVP_OFF ERRORLEVEL 1,-302 ;********************************************** ;Fosc 16Mhz ;First commented on PicList by Dave Dilatush ;Sat, 9 Feb 2002 20:43:39 GMT ;Re: [PIC]: CHALLENGE: 4x4 keyboard and LCD with 1 port = 8 bits ; ; X-------X-------X-------X----------+--Vcc ; | | | | | ; | | | | | ; X-------X-------X-------X---4.7K---+ ; | | | | | ; | | | | | ; X-------X-------X-------X---10K----+ ; | | | | | ; | | | | | ; X-------X-------X-------X---15K----+ ; | | | | ; | 1.2K 2.4K 3.6K ; | | | | ; +-------+-------+-------+--> To PIC A/D Input ; | ; 22K ; | ; GND ; CBLOCK 0X070 ; BUFFER ; LOOPS ; LOOPS2 ; NIBBLE1 ; NIBBLE2 ; NIBBLE3 ; FILTER1 ; FILTER2 ; FILTER3 ; VECES ; BUFFERKEY ; ENDC ; ORG 00 ; GOTO INIT ; ; ;Delay. @4Mhz-1ms. RETARDO ; MOVWF LOOPS ; TOP2 MOVLW D'110' ; MOVWF LOOPS2 ; TOP NOP ; NOP ; NOP ; NOP ; NOP ; NOP ; DECFSZ LOOPS2 ; GOTO TOP ; DECFSZ LOOPS ; GOTO TOP2 ; RETURN ; ;ADC CONVER BSF ADCON0,GO ; CONSU BTFSC ADCON0,GO ; GOTO CONSU ; RETURN ; ;Resistors and Keys Resistances ;may vary over the time ;so we established ranges for ;each converted value with: ;addlw 255 - Hi ;addlw (Hi - Lo) + 1 ;for a good explanation go to: ;http://www.piclist.com/techref/microchip/rangechk.htm ;********************************; PARSER ; CLRF BUFFERKEY ;Split de hexa into MOVLW .3 ;two nibbles. Test for XORWF FILTER1,W ;Hi nibble, If = 3 BTFSS STATUS,Z ;Test the low nibble GOTO TWO ;otherwise jump. ;3FC ---> real value got it from TOASCII routine MOVFW FILTER2 ; ADDLW 255 - 0X0FE ; ADDLW (0X0FE - 0X0E8)+1 ; MOVLW "1" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;3C4 MOVFW FILTER2 ; ADDLW 255 - 0X0C8 ; ADDLW (0X0C8 - 0X0BF)+1 ; MOVLW "2" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;39E MOVFW FILTER2 ; ADDLW 255 - 0X0A2 ; ADDLW (0X0A2 - 0X09A)+1 ; MOVLW "3" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;363 MOVFW FILTER2 ; ADDLW 255 - 0X067 ; ADDLW (0X067 - 0X05E)+1 ; MOVLW "S" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;345 MOVFW FILTER2 ; ADDLW 255 - 0X049 ; ADDLW (0X049 - 0X041)+1 ; MOVLW "4" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;31F MOVFW FILTER2 ; ADDLW 255 - 0X023 ; ADDLW (0X023 - 0X01B)+1 ; MOVLW "5" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;305 MOVFW FILTER2 ; ADDLW 255 - 0X09 ; ADDLW (0X009 - 0X01)+1 ; MOVLW "6" ; BTFSC STATUS,C ; GOTO SAVEKEY ; TWO ;Values with hi nibble ;equal to 2 ;2DB MOVFW FILTER2 ; ADDLW 255 - 0X0E1 ; ADDLW (0X0E1 - 0XD7)+1 ; MOVLW "U" ;U for UP BTFSC STATUS,C ; GOTO SAVEKEY ; ;2BE MOVFW FILTER2 ; ADDLW 255 - 0X0C2 ; ADDLW (0X0C2 - 0XBA)+1 ; MOVLW "7" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;2A3 MOVFW FILTER2 ; ADDLW 255 - 0X0A7 ; ADDLW (0X0A7 - 0X9F)+1 ; MOVLW "8" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;28E MOVFW FILTER2 ; ADDLW 255 - 0X092 ; ADDLW (0X092 - 0X8A)+1 ; MOVLW "9" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;271 MOVFW FILTER2 ; ADDLW 255 - 0X075 ; ADDLW (0X075 - 0X06D)+1 ; MOVLW "D" ;D for Down BTFSC STATUS,C ; GOTO SAVEKEY ; ;25C MOVFW FILTER2 ; ADDLW 255 - 0X060 ; ADDLW (0X060 - 0X058)+1 ; MOVLW "P" ;P for Program BTFSC STATUS,C ; GOTO SAVEKEY ; ;248 MOVFW FILTER2 ; ADDLW 255 - 0X04C ; ADDLW (0X04C - 0X044)+1 ; MOVLW "0" ; BTFSC STATUS,C ; GOTO SAVEKEY ; ;238 MOVFW FILTER2 ; ADDLW 255 - 0X03C ; ADDLW (0X03C - 0X34)+1 ; MOVLW "B" ;B for Backspace BTFSC STATUS,C ; GOTO SAVEKEY ; ;222 MOVFW FILTER2 ; ADDLW 255 - 0X026 ; ADDLW (0X026 - 0X1E)+1 ; MOVLW "E" ;E for Enter BTFSC STATUS,C ; GOTO SAVEKEY ; KEYBERROR2 ;If some keys have MOVLW "#" ;changed their values SAVEKEY ;the soft could handled MOVWF BUFFERKEY ;the error RETURN ; ;********************************; TOASCII ;When is active, MOVF FILTER1,W ;this routine take the MOVWF NIBBLE1 ;hex value and convert it MOVLW 30H ;into three ascii values ADDWF NIBBLE1 ;Basically check for ;ABCDEF1234567890 MOVF FILTER2,W ; MOVWF BUFFER ; ANDLW 0FH ; MOVWF NIBBLE3 ; MOVLW 0AH ; SUBWF NIBBLE3,0 ; MOVLW 37H ; BTFSS STATUS,C ; MOVLW 30H ; ADDWF NIBBLE3 ; SWAPF BUFFER,0 ; ANDLW 0FH ; MOVWF NIBBLE2 ; MOVLW 0AH ; SUBWF NIBBLE2,0 ; MOVLW 37H ; BTFSS STATUS,C ; MOVLW 30H ; ADDWF NIBBLE2 ; RETURN ; ;********************************;This routine add FILTRO CLRF FILTER1 ;the converted value CLRF FILTER2 ;into 3 registers. CLRF FILTER3 ;256 times. CLRF VECES ;then divide by 256 REPEAT ;ignoring filter3. CALL CONVER ;ex:for 3FB BSF STATUS,RP0 ;filter1=0x003 MOVF ADRESL,W ;filter2=0x0fb BCF STATUS,RP0 ; ADDWF FILTER3,1 ; BTFSS STATUS,C ; GOTO FILT2 ; MOVLW D'1' ; ADDWF FILTER2,1 ; BTFSS STATUS,C ; GOTO FILT2 ; MOVLW D'1' ; ADDWF FILTER1,1 ; FILT2 ; MOVF ADRESH,W ; ADDWF FILTER2,1 ; BTFSC STATUS,C ; INCF FILTER1 ; DECFSZ VECES,1 ; GOTO REPEAT ; ; RETURN ; ; ; ; TRASMI BTFSS PIR1,TXIF ; GOTO TRASMI ; MOVWF TXREG ; NOP ; TRASMI2 BTFSS PIR1,TXIF ;last bit is sent GOTO TRASMI2 ; RETURN ; ;Main INIT BSF STATUS,RP0 ; MOVLW 0FFH ; MOVWF TRISA ; MOVWF TRISB ; MOVLW B'11111111' ; MOVWF TRISC ; MOVLW B'00100110' ; MOVWF TXSTA ; MOVLW D'103' ;16mhz crystal MOVWF SPBRG ;9600bps. If 4mhz is used, MOVLW B'10000010' ;change spbrg to (dec)25 MOVWF ADCON1 ; BCF STATUS,RP0 ; MOVLW B'10000001' ;Fosc/32 MOVWF ADCON0 ; BSF PIR1,TXIF ; BCF PIR1,RCIF ; MOVLW B'10010000' ; MOVWF RCSTA ; ; MOVLW "T" ;welcom screen on pc CALL TRASMI ; MOVLW "X" ; CALL TRASMI ; MOVLW " " ; CALL TRASMI ; MOVLW "O" ; CALL TRASMI ; MOVLW "K" ; CALL TRASMI ; MOVLW D'13' ; CALL TRASMI ; MOVLW D'10' ; CALL TRASMI ; ; ; CICLO ; CALL FILTRO ;check for pushed keys MOVLW 2 ;> than 2 in filter1 SUBWF FILTER1,W ; BTFSS STATUS,C ; GOTO CICLO ; ; MOVLW .83 ;almost 20 ms. CALL RETARDO ;if 4mhz is used, CLRF VECES ;change to (dec)20 CALL FILTRO ; MOVLW 2 ; SUBWF FILTER1,W ; BTFSS STATUS,C ; GOTO CICLO ; ; CALL TOASCII ;un-comment this to see the CALL PARSER ;key real value, so range can RELEASE ;be adjusted CALL FILTRO ;check if key was released MOVLW 0X02 ; SUBWF FILTER1,W ; BC RELEASE ; ; MOVLW ":" ; CALL TRASMI ; MOVFW BUFFERKEY ; CALL TRASMI ; ; MOVFW NIBBLE1 ;un-comment to send keys ; CALL TRASMI ;values to pc screen ; MOVFW NIBBLE2 ; ; CALL TRASMI ; ; MOVFW NIBBLE3 ; ; CALL TRASMI ; MOVLW D'13' ; CALL TRASMI ; MOVLW D'10' ; CALL TRASMI ; ; GOTO CICLO ; ; ENDSee also:
Comments: