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


Reply With Quote

Bookmarks