Select case function


+ Reply to Thread
Results 1 to 17 of 17
  1. #1
    Join Date
    Feb 2022
    Posts
    42

    Default Select case function

    Hello everyone,

    I'm looking for some tips, to enhance the code listed here to simplify with less code the "Select case'.

    This code is for a PIC18F25K22 using PortC as a 64 switches matrix scan and PortB as the receiver and decoder and PortA to send the data.

    Thanks for any comments.

    Code:
    ' PIC18F25K22 64 Keys Encoder
    ' File :"D:\PIC\PBP3\18F25K22\64 Keys Encoder\64 Keys Encoder.pbp"
    ' Date : Feb 13 2025
    '
    ' WPUB : p152 PORTB only
    ' PORTA : Flags
    ' PORTB : Row Input
    ' PORTC : Column Out
    ;----[18F25K22 Hardware Configuration]------------------------------------------
    #CONFIG
      CONFIG  FOSC = INTIO67     ; Internal oscillator block
      CONFIG  PLLCFG = ON        ; Oscillator used directly
      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 = ON         ; WDT is always enabled. SWDTEN bit 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    ; MCLR pin enabled, RE3 input pin disabled
      CONFIG  STVREN = ON        ; Stack full/underflow will cause Reset
      CONFIG  LVP = OFF          ; Single-Supply ICSP disabled
      CONFIG  XINST = OFF        ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
      CONFIG  DEBUG = OFF        ; Disabled
      CONFIG  CP0 = OFF          ; Block 0 (000800-001FFFh) not code-protected
      CONFIG  CP1 = OFF          ; Block 1 (002000-003FFFh) not code-protected
      CONFIG  CP2 = OFF          ; Block 2 (004000-005FFFh) not code-protected
      CONFIG  CP3 = OFF          ; Block 3 (006000-007FFFh) not code-protected
      CONFIG  CPB = OFF          ; Boot block (000000-0007FFh) not code-protected
      CONFIG  CPD = OFF          ; Data EEPROM not code-protected
      CONFIG  WRT0 = OFF         ; Block 0 (000800-001FFFh) not write-protected
      CONFIG  WRT1 = OFF         ; Block 1 (002000-003FFFh) not write-protected
      CONFIG  WRT2 = OFF         ; Block 2 (004000-005FFFh) not write-protected
      CONFIG  WRT3 = OFF         ; Block 3 (006000-007FFFh) not write-protected
      CONFIG  WRTC = OFF         ; Configuration registers (300000-3000FFh) not write-protected
      CONFIG  WRTB = OFF         ; Boot Block (000000-0007FFh) not write-protected
      CONFIG  WRTD = OFF         ; Data EEPROM not write-protected
      CONFIG  EBTR0 = OFF        ; Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
      CONFIG  EBTR1 = OFF        ; Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
      CONFIG  EBTR2 = OFF        ; Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
      CONFIG  EBTR3 = OFF        ; Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
      CONFIG  EBTRB = OFF        ; Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
    #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 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
    
    
    Latch1 var byte              ' Latch1 Flag
    Latch1 = 0
    
    
    LRShift VAR BIT              ' Shift Direction Flag
    LRSHIFT = 0
    
    
    TTL VAR WORD                  'Key val
    TTL = 0 
    
    
    TTLadd var word              ' adding to PORTC val
    ttladd = 0 
    
    
    PORTKey var byte             ' Key data
    portkey = 0
    
    
    Baud var word                ' Serout2 Baud Rate
    Baud = 84 
    'Baud =  16468
    
    
    PORTB = 0                    ' PORTB set to 0 Keypad Row
    PAUSE 10
    PORTC = 000001            ' Keypad Column out to Row PORTB
    PORTA.0 = 1                  ' serial port = 1 'avoid random data'
    PORTA.1 = 0                  ' Data Available
    
    
    MAIN:                        ' Main Routine
    
    
    PAUSE 1                     ' needed for PORTC > PORTB Data transfert
    LATB = PORTB                ' Needed to use the value of PORTB
    
    
    ' Output Data to PORTC
    IF PORTB > 0 AND Latch1 = 0 THEN
        Latch1 = 1
        LATC = LATB
        PAUSE 5    
    
    
    ' prevent duplicate
    IF PORTC = 1 THEN
        TTLADD = 0 
    endif
    IF PORTC = 2 THEN
        TTLADD = 128
    endif
    IF PORTC = 4 THEN
        TTLADD = 384
    endif
    IF PORTC = 8 THEN
        TTLADD = 512
    endif
    IF PORTC = 16 THEN
        TTLADD = 640
    endif
    IF PORTC = 32 THEN
        TTLADD = 758
    endif
    IF PORTC = 64 THEN
        TTLADD = 896
    endif
    IF PORTC = 128 THEN
        TTLADD = 1024
    endif
    ' prevent duplicate
    
    
    TTL = TTLADD + PORTB
    
    
    ' Select PORTKkey val
    Select Case ttl
        case 1
        portkey = 1 : goto P
        case 2
        portkey = 2 : goto P
        case 4
        portkey = 3 : goto P
        case 8
        portkey = 4 : goto P
        case 16
        portkey = 5 : goto P
        case 32
        portkey = 6 : goto P
        case 64
        portkey = 7 : goto P
        case 128
        portkey = 8 : goto P
    
    
        case 129
        portkey = 9 : goto P
        case 130
        portkey = 10 : goto P
        case 132
        portkey = 11 : goto P
        case 136
        portkey = 12 : goto P
        case 144
        portkey = 13 : goto P
        case 160
        portkey = 14 : goto P
        case 192
        portkey = 15 : goto P
        case 256
        portkey = 16 : goto P
    
    
        case 385
        portkey = 17 : goto P
        case 386
        portkey = 18 : goto P
        case 388
        portkey = 19 : goto P
        case 392
        portkey = 20 : goto P
        case 400
        portkey = 21 : goto P
        case 416
        portkey = 22 : goto P
        case 448
        portkey = 23 : goto P
        case 512
        portkey = 24 : goto P
    
    
        case 513
        portkey = 25 : goto P
        case 514
        portkey = 26 : goto P
        case 516
        portkey = 27 : goto P
        case 520
        portkey = 28 : goto P
        case 528
        portkey = 29 : goto P
        case 544
        portkey = 30 : goto P
        case 576
        portkey = 31 : goto P
        case 640
        portkey = 32 : goto P
    
    
        case 641
        portkey = 33 : goto P
        case 642
        portkey = 34 : goto P
        case 644
        portkey = 35: goto P
        case 648
        portkey = 36 : goto P
        case 656
        portkey = 37 : goto P
        case 672
        portkey = 38 : goto P
        case 704
        portkey = 39 : goto P
        case 768
        portkey = 40 : goto P
    
    
        case 759
        portkey = 41 : goto P
        case 760
        portkey = 42 : goto P
        case 762
        portkey = 43 : goto P
        case 766
        portkey = 44 : goto P
        case 774
        portkey = 45 : goto P
        case 790
        portkey = 46 : goto P
        case 822
        portkey = 47 : goto P
        case 886
        portkey = 48 : goto P
    
    
        case 897
        portkey = 49 : goto P
        case 898
        portkey = 50 : goto P
        case 900
        portkey = 51 : goto P
        case 904
        portkey = 52 : goto P
        case 912
        portkey = 53 : goto P
        case 928
        portkey = 54 : goto P
        case 960
        portkey = 55 : goto P
        case 1024
        portkey = 56 : goto P
    
    
        case 1025
        portkey = 57 : goto P
        case 1026
        portkey = 58 : goto P
        case 1028
        portkey = 59 : goto P
        case 1032
        portkey = 60 : goto P
        case 1040
        portkey = 61 : goto P
        case 1056
        portkey = 62 : goto P
        case 1088
        portkey = 63 : goto P
        case 1152
        portkey = 64 : goto P
    end select
    ' Select PORTKkey val
    
    
    P:
    pause 10
    PORTA.1 = 1  ' Data Available
    
    
    'SEROUT2 PORTA.0,Baud,[dec3 LATC," PORTC Bin: ", bin8 LATC,13,10]  ' SW PORTC Column to PORTB Row
    'SEROUT2 PORTA.0,Baud,[dec3 LATB," PORTB Bin: ", bin8 LATB," DEC TTL : ",DEC5 TTL," BIN TTL: ",BIN16 TTL,13,10]  '  SW PORTB Row from PORTC Column
    sEROUT2 PORTA.0,Baud,[" PORTB Dec :",dec3 LATB," PORTB Bin: ", bin8 LATB," TTL Dec : ",DEC4 TTL," TTL Bin : ",BIN16 TTL," Port Key: ",dec2 portkey," Port Key Bin : ",bin8 portkey,13,10]  
    
    
    ENDIF
    
    
    ' Wait for Key Release
    WHILE PORTB > 0
    WEND
    
    
    ' Reset Flag
    latch1 = 0                   ' Latch1
    PORTA.1 = 0                  ' Data Available
    LATC = 0                     ' LATC
    TTL = 0 
    pause 50                     ' Debounce pause
    
    
    ' 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
    
    
    goto main                    ' restart loop
    Attachment 0
    Name:  keypad value rpt.jpg
Views: 1501
Size:  175.0 KB

    Attachment 0
    Name:  64 keys circuit diagram.jpg
Views: 1497
Size:  112.1 KB

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,641


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    just need to keep ONE GoTo P @ the end of your Select case's after the End Select

    your syntax is " not so good "

    Code:
    ' prevent duplicate
    
    IF PORTC = 1 THEN
        TTLADD = 0 
    endif
    
    IF PORTC = 2 THEN 
       TTLADD = 128
    endif
    
    IF PORTC = 4 THEN 
       TTLADD = 384
    endif
    
    One more good reason to use " select case " ...

    I think you should read carefully the select case page of your Holy Manual ... ( not a C Compiler manual ... )
    Last edited by Acetronics2; - 14th February 2025 at 21:00.
    ************************************************** ***********************
    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 " !!!
    *****************************************

  3. #3
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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 21:17.

  4. #4
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,641


    0 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: Select case function

    Quote Originally Posted by jackberg1 View Post
    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
    I think you should read carefully the select case page of your Holy Manual
    ************************************************** ***********************
    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 " !!!
    *****************************************

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,623


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: Select case function

    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

  6. #6
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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.

    Name:  same val.jpg
Views: 1493
Size:  46.3 KB

  7. #7
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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 17:05.

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,598


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: Select case function

    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
    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.

    /Henrik.

  9. #9
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    Thank you HenrikOlsson

    This is a very usefull solution since I got on hand a logic analyzer + scope.



  10. #10
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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.





  11. #11
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,641


    0 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: Select case function

    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
    the PBP soft way : https://dt.picbasic.co.uk/CODEX/CodeTimer
    ************************************************** ***********************
    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 " !!!
    *****************************************

  12. #12
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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

  13. #13
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,098


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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 10:36.

  14. #14
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    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

  15. #15
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function Last update (Benchmark : PortKey 1~64: 3.988us ~ 6.25us)

    This is the lasted update, some changes the 'Select case' as been move down

    this alone is reducing the response time from 11us to 6us to the data available.

    While the propagation time at the D/A of the MM74C922 is 60ns ~ 150ns max.

    It will be hard to even get close to 500ns with the PIC18F25K22 unless someone has an idea to share.

    I searched the internet for an affordable / alternative solution is to get into the CPLD or FPGA but it's not cost effective + VHDL learning process.

    Any constructive comments is welcome.


    Name:  Key Sheet.jpg
Views: 498
Size:  115.5 KB
    Last edited by jackberg1; - 19th February 2025 at 18:58.

  16. #16
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    Here's the updated code (when using the '#" Wrap code, if I edit my post and save it, after the '%' or other characters are remove from the listing)

    ' PIC18F25K22 64 Keys Encoder V3
    ' File : "D:\PIC\PBP3\18F25K22\64 Keys Encoder\64 Keys Encoder V3.pbp"
    ' Date : Feb 19 2025
    ' Benchmark : PortKey 1~64: 3.988us ~ 6.25us
    ' Used : 621 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


    NCDC VAR BYTE ' PORTC Bit Position 1~8
    PORTKey var byte ' Key# data
    portkey = 0


    Baud var word ' Serout2 Baud Rate
    Baud = 84


    PORTA.0 = 1 ' Avoid random char on serial


    PAUSE 100
    PORTC = %00000001 ' Keypad Scan Column out to PORTB
    PORTA.7 = 0 ' Data available / Benchmark
    PORTB = %00000000 ' PORTB Keypad Row


    MAIN: ' Main Routine


    IF PORTB > 0 AND Latch1 = 0 THEN ' Detect Press Switch and Latch
    Latch1 = 1


    ' PORTA.7 = 1 ' Benchmark Start


    PORTKey = NCDC + NCD PORTB ' add bit position 1~8
    'PORTA = PORTKEY ' Set PORTA / Disable for SEROUT2


    ' PORTA.7 = 0 ' Benchmark End


    PAUSE 5 ' pause before D/A PORTA.7
    PORTA.7 = 1 ' Data available / Disable for Benchmark


    SEROUT2 PORTA.0,Baud,[" PORTB NCD: ",dec1 NCD PORTB," PORTC NCD:",DEC1 NCD PORTC," D/A 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 after Key release
    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
    PAUSEUS 20 ' pauseus wait for Shift to set


    SELECT CASE NCD PORTC ' Assign new value for PORTC Column
    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


    goto main ' restart loop
    Last edited by jackberg1; - 19th February 2025 at 19:15.

  17. #17
    Join Date
    Feb 2022
    Posts
    42


    Did you find this post helpful? Yes | No

    Default Re: Select case function

    While trying to correct my previous listing the 'Administrator is preventing me to edit after 30 minutes'

    Dear Administrator read my previous post about the characters missing or changes after uploading to your site.

    thank you

    \ (when using the '#" Wrap code, if I edit my post and save it, after the '%' or other characters are remove from the listing

    even some characters are show in lower case instead of upper case
    )\



Similar Threads

  1. Select Case Weirdness
    By rocket_troy in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 19th June 2014, 01:33
  2. Changing from If..Then to Select Case
    By BobK in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 27th March 2013, 12:06
  3. About Select Case
    By polymer52 in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 28th February 2010, 12:54
  4. Select case...Just wondering....
    By muddy0409 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 30th December 2006, 00:23
  5. Select Case
    By Srigopal007 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 20th June 2005, 20:18

Members who have read this thread : 13

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts