does the Select function case has to read every case before end select , or it's getting out when found the right one
the Goto P it's there so when a case is match then Goto P, to avoid reading all the case
does the Select function case has to read every case before end select , or it's getting out when found the right one
the Goto P it's there so when a case is match then Goto P, to avoid reading all the case
Last edited by jackberg1; - 14th February 2025 at 20:17.
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
for a 8x8 keypad there are 64 possible results
that's an extraordinary convoluted way to get a result
why not
Code:key var byte ; high nibble column low nibble row if portb then 'look for a 1 key = ncd portb 'row look for a 1 key = key + (ncd portc )<<4 PORTA.1 = 1 ' Data Available WHILE PORTB >0 :wend endif
Warning I'm not a teacher
Thank you richard
the reason I had to add a value to the portc, was the fact in the 64 key matrix some code were duplicate.
so 2 different key had the same value.
I'll have to test this code.
![]()
Hello Richard
by inverting portb / portc I found no duplicate
If I may ask, how to know the time it took from the start to end of a for/next loop or select case in a program
Many thanks for your support.
Code:key = ncd portb 'row look for a 1 key = key + (ncd portc )<<4
Last edited by jackberg1; - 15th February 2025 at 16:05.
Depends on what's available. I usually just set a pin high at the start and low again at the end of the routine I want to measure and then look at the pin using a scope or logic analyzer. Another option is to use one of the hardware timers and send the result to the PC using whatever serial connection is available (DEBUG, SEROUT, HSEROUT) but for longer routines one has to be little bit careful as to not overflow the timer and therefor get misleading values.If I may ask, how to know the time it took from the start to end of a for/next loop or select case in a program
/Henrik.
Thank you HenrikOlsson
This is a very usefull solution since I got on hand a logic analyzer + scope.
Hello HenrikOlsson,
I did some timing test for the 'Select case' for key # 1 ~ key # 64
case # 1 : 3.48us and the last of the case key # 64 : 134.9us
Thanks again for this clever trick.
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
With these errors, I think it cannot work...
Have marked with red the errors.
You should use percent character followed by binary values.
Ioannis
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
Last edited by Ioannis; - 18th February 2025 at 09:36.
Thanks Ioannis for pointing this, the % are in fact on my program.
when uploading to the site something I select 'Courrier New' font append, and it's look they just vannish.
here's the upload.
'2nd upload seem to work fine this time'
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 = %00000000 ' PORTA Key Data available output TRISB = %11111111 ' PORTB Intput Keypad Rows in TRISC = %00000000 ' PORTC Output Keypad Column out TRISE = %00001000 ' 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 PORTA.0 = 1 ' Avoid garbage on serial PAUSE 100 PORTC = %00000001 ' Keypad Column out to Row PORTB PORTA.7 = 0 ' Data Available PORTB = %00000000 ' 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 8 NCDC = 56 CASE 2 NCDC = 8 CASE 7 NCDC = 48 CASE 3 NCDC = 16 CASE 6 NCDC = 40 CASE 4 NCDC = 24 CASE 5 NCDC = 32 END SELECT PORTKey = NCDC + NCDB ' Key# Data 1~64 'PORTA = PORTKEY ' Data output 'PORTA.1 = 0 ' Benchmark pause 2 ' 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 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