Code:
DEFINE OSC 48
ADCON1 = $F 'port A digital
CMCON = 7 'PortA Digital
PortE.7 = 1 'set weak pullups port D
USBBufferSizeMax con 8 ' maximum buffer size
USBBufferSizeTX con 8 ' input
USBBufferSizeRX con 8 ' output
' the USB buffer...
USBBuffer Var Byte[USBBufferSizeMax]
USBBufferCount Var Byte
TrisB = %00000000
TrisD = %11111111
TrisE.0 = 1
TrisE.1 = 1
shift var byte
keyout var byte
keyold var byte
K_Flag Var Bit
Key Var Byte
Debounce Var Bit ' Flag to indicate a keypress.
D_Flag Var Bit ' Debounce flag used by Inkeys.
keysend var byte
D_Flag=0
'*******************************************************************************
' Interrupt definition
' ====================
' USB interrupt used to keep USB connection alive
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler USB_INT, _DoUSBService, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
pause 500
usbinit ' initialise USB...
USBService ' keep connection alive
UIE = $7F
UEIE = $9F
@ INT_ENABLE USB_INT
goto ProgramStart
' This subroutine Scans the 16 button keypad and returns the key pressed in "KEY"
' If no key is pressed the value returned is 128.
' It also returns a Bit-Flag called DEBOUNCE which is 1 if a key is still in use
' And 0 if not. This acts as a debounce for the Keypad.
Keyscan:
Debounce=1 ' Setup the initial value for Debounce
Key=0 ' Clear the variable KEY, prior to scanning
Portb=%11111110 ' Pull the fourth row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=10
Portb=%11111101 ' Pull the third row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=20
Portb=%11111011 ' Pull the second row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=30
Portb=%11110111 ' Pull the first row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=40
Portb=%11101111 ' Pull the fourth row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=50
Portb=%11011111 ' Pull the third row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=60
Portb=%10111111 ' Pull the second row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
key=70
Portb=%01111111 ' Pull the first row line LOW
Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then map it
Portb=%11111111
' key=80
' Porta=%11111011 ' Pull the fourth row line LOW
' Gosub Scancol ' Scan the columns
' If K_Flag=1 then goto Map ' If a key is pressed then map it
' key=90
' Porta=%11110111 ' Pull the third row line LOW
' Gosub Scancol ' Scan the columns
If K_Flag=1 then goto Map ' If a key is pressed then m
D_Flag=0 ' No key pressed, so Reset debounce flag
Debounce=0 ' No key pressed, so Reset key Debounce flag
Goto Exit ' Exit from the subroutine
' Do the following code if a key has been pressed
Map: portb.0 = 0
' if porta.1 = 0 then
' shift = 1
' else
' shift = 0
' endif
If D_Flag=1 then exit ' Already responded to this press, so exit
D_Flag=1 ' Set Debounce flag
Debounce=0 ' Reset key Debounce flag
'Key Code
Exit: Lookup Key,[81,86,88,47,4,84,83,87,82,85,_ '0-9
20,0,21,0,0,0,19,24,17,22,_ '10-19
65,72,69,48,3,68,67,71,66,70,_ '20-29
28,0,29,0,0,0,27,0,25,30,_ '30-39
60,64,61,43,8,0,59,63,36,62,_ '40-49
44,40,37,42,7,0,35,39,41,38,_ '50-59
49,56,53,46,5,52,51,55,50,54,_ '60-69
73,80,77,45,6,76,75,79,74,78,_ '70-79
0,0,0,0,0,0,0,0,0,0,_ '80-89
0,0,0,0,0,0,0,0,0,0],Keyout '90-99 Map of the keypad legends
Return ' Exit from the subroutine
' This subroutine scans the columns
' The bit, K_Flag returns a 1 if a key is pressed, and 0 if no key pressed
' Also, if no key is pressed the variable KEY will return with the value of 16
Scancol:
K_Flag=1 ' Set K_Flag initially to 1
If Portd.0=0 then S_Exit ' Return if a key on the first column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.1=0 then S_Exit ' Return if a key on the second column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.2=0 then S_Exit ' Return if a key on the third column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.3=0 then S_Exit ' Return if a key on the fourth column is pressed
Key=Key+1 ' Else increment KEY, KEY now equals 16
If Portd.4=0 then S_Exit ' Return if a key on the first column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.5=0 then S_Exit ' Return if a key on the second column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.6=0 then S_Exit ' Return if a key on the third column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Portd.7=0 then S_Exit ' Return if a key on the fourth column is pressed
Key=Key+1 ' Else increment KEY, KEY now equals 16
If Porte.0=0 then S_Exit ' Return if a key on the third column is pressed
Key=Key+1 ' Else increment KEY, and try another row
If Porte.1=0 then S_Exit ' Return if a key on the fourth column is pressed
Key=Key+1 ' Else increment KEY, KEY now equals 16
K_Flag=0 ' Set the K_Flag to indicate no key pressed
'key = 0
S_Exit: Return ' And exit the subroutine
' ************************************************************
' * receive data from the USB bus *
' ************************************************************
DoUSBIn:
USBBufferCount = USBBufferSizeRX ' RX buffer size
USBIn 1, USBBuffer, USBBufferCount, DoUSBIn ' read data, if available
return
' ************************************************************
' * wait for USB interface to attach *
' ************************************************************
DoUSBOut:
USBBufferCount = USBBufferSizeTX ' TX buffer size
USBOut 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
return
'###############################################################################
DoUSBService: 'Keeps USB alive
usbservice
@ INT_RETURN
'###############################################################################
ProgramStart:
Again: gosub Keyscan ' Go and scan the keypad
If K_Flag = 0 then ' If no key is pressed then do the following: -
Goto Again ' And look again when woken up.
Endif
'High Strobe ' Enable the Strobe pin
Pause 200 ' Delay for 50ms after strobe pin is set HIGH
if keyold != key then
usbbuffer[0] = Keyout ' Transmit the KEY byte
gosub dousbout
endif
keyold = keyout
Goto again ' Do it all again!
Bookmarks