Hello Richard,
I rewrote my keypad program with the NCD function that you recomended, that help a lot
I changed the column value to the range from 1 ~ 64 with this I'm able to get an
average of 10~12us for the data available output signal.
The project served as a replacement of the old MM74C922/3.
Thanks again Richard for your great help.
Code:
' PIC18F25K22 64 Keys Encoder
' File : "D:\PIC\PBP3\18F25K22\64 Keys Encoder\64 Keys Encoder V2.pbp"
' Date : Feb 16 2025
' Benchmark : PortKey 1~64:~12us
' Used : 543 bytes
' WPUB : p152 PORTB only
' PORTA : Data Available D/A PORTA.7:High
' PORTB : Row Input
' PORTC : Column Output
'----[18F25K22 Hardware Configuration]------------------------------------------
#CONFIG
CONFIG FOSC = INTIO67 ; Internal oscillator block
CONFIG PLLCFG = ON ; Oscillator multiplied by 4
CONFIG PRICLKEN = OFF ; Primary clock can be disabled by software
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor disabled
CONFIG IESO = OFF ; Oscillator Switchover mode disabled
CONFIG PWRTEN = OFF ; Power up timer disabled
CONFIG BOREN = SBORDIS ; Brown-out Reset enabled in hardware only (SBOREN is disabled)
CONFIG BORV = 190 ; VBOR set to 1.90 V nominal
CONFIG WDTEN = OFF ; Watch dog timer is always disabled. SWDTEN has no effect.
CONFIG WDTPS = 32768 ; 1:32768
CONFIG CCP2MX = PORTC1 ; CCP2 input/output is multiplexed with RC1
CONFIG PBADEN = OFF ; PORTB<5:0> pins are configured as digital I/O on Reset
CONFIG CCP3MX = PORTB5 ; P3A/CCP3 input/output is multiplexed with RB5
CONFIG HFOFST = ON ; HFINTOSC output and ready status are not delayed by the oscillator stable status
CONFIG T3CMX = PORTC0 ; T3CKI is on RC0
CONFIG P2BMX = PORTB5 ; P2B is on RB5
CONFIG MCLRE = INTMCLR ; RE3 input pin enabled; MCLR disabled
CONFIG STVREN = ON ; Stack full/underflow will cause Reset
CONFIG LVP = OFF ; Single-Supply ICSP disabled
#ENDCONFIG
define OSC 64 ' OSC 64Mhz
ANSELA = 0 ' Set all digital
ANSELB = 0 ' Set all digital
ANSELC = 0 ' Set all digital
'WPUB = $FF ' Set Weak PullUP PORTB only
'CMCON0 = 7
TRISA = 000000 ' PORTA Key Data available output
TRISB = 111111 ' PORTB Intput Keypad Rows in
TRISC = 000000 ' PORTC Output Keypad Column out
TRISE = 001000 ' PORTE.3 MCLRE as input '1' other output '0'
OSCCON = $70 ' Internal OSC p:30
OSCTUNE = $40 ' for 64Mhz FOSC p:35
' Var for Key & Port
Latch1 var byte ' Latch1 Flag
Latch1 = 0
LRShift VAR BIT ' Shift Direction Flag
LRSHIFT = 0
NCDB VAR BYTE ' NCD PORTB
NCDC VAR BYTE ' NCD PORTC
PORTKey var byte ' Key# data
portkey = 0
' Serial Terminal
Baud var word ' Serout2 Baud Rate
Baud = 84
'Baud = 16468
PAUSE 100
PORTC = 000001 ' Keypad Column out to Row PORTB
PORTA.7 = 0 ' Data Available
PORTB = 000000 ' PORTB set to 0 Keypad Row
MAIN: ' Main Routine
' Output Data to PORTC
IF PORTB > 0 AND Latch1 = 0 THEN
Latch1 = 1
'PORTA.1 = 1 ' Benchmark
' Get bit position 1~8
NCDB = NCD PORTB ' PORTB Row 'in'
NCDC = NCD PORTC ' PORTC Column 'out'
' Assign new value for PORTC Column
SELECT CASE NCDC
CASE 1
NCDC = 0
CASE 2
NCDC = 8
CASE 3
NCDC = 16
CASE 4
NCDC = 24
CASE 5
NCDC = 32
CASE 6
NCDC = 40
CASE 7
NCDC = 48
CASE 8
NCDC = 56
END SELECT
PORTKey = NCDC + NCDB ' Key# Data 1~64
PORTA = PORTKEY ' Data output
pause 1 ' Mandatory pause > 0 for PORTA to set
PORTA.7 = 1 ' Data available
'sEROUT2 PORTA.0,Baud,[" PORTB NCD: ",dec1 NCDB," PORTC NCD:",DEC1 NCDC," PORTKey :",DEC2 PORTKey,13,10]
ENDIF
' Wait for Key Release
WHILE PORTB > 0
WEND
pause 5 ' Key release debounce
' Reset Flag
latch1 = 0 ' Latch1
PORTA.7 = 0 ' Data available
PORTA.1 = 0 ' Benchmark
PORTKey = 0
' Shift Direction Flag
IF PORTC = 1 THEN
lrshift = 0
endif
IF PORTC = 128 THEN
lrshift = 1
endif
' Shift PORTC
if lrshift = 0 then
PORTC = PORTC << 1 ' Shift Left
endif
if lrshift = 1 then
PORTC = PORTC >> 1 ' Shift Right
ENDIF
PAUSE 1 ' Mandatory pause > 0 wait for Shift to set
goto main ' restart loop
Bookmarks