Menu

Looking for a GCBasic cool way to read BCD rotary switches

2023-09-07
2023-09-12
<< < 1 2 (Page 2 of 2)
  • Anobium

    Anobium - 2023-09-10

    Would you add some debug to the program.

    After each read show the assigned value to the serial terminal. What are those values?

    Please try with the mask and without the mask.

    Thanks

     
  • Steve Scott

    Steve Scott - 2023-09-10

    Evan-
    Code here:
    'Gets address
    BCD1 = 1 'Sets the units digit of BCD switch common Address HIGH
    Address1 = PORTH ' & 0x0F 'Gets the units digit of the Address and strips off high nibble
    HSerPrint "Address Units:"
    HSerPrint Address1
    HSerSend 13
    HSerSend 10
    BCD1 = 0 'Resets the units BCD common back to LOW
    wait 100 us 'Wait just a bit
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    Address10 = PORTH ' & 0x0F 'Gets the tens digit of Address and strips off high nibble
    HSerPrint "Address Tens:"
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

    Notice the ' before the & above in the non-masking lines
    

    Copied from the serial console:
    Address Units:0
    Address Tens:0


    Code that works:
    'Gets address
    BCD1 = 1 'Sets the units digit of BCD switch common Address HIGH
    Address1 = PORTH & 0x0F 'Gets the units digit of the Address and strips off high nibble
    HSerPrint "Address Units:"
    HSerPrint Address1
    HSerSend 13
    HSerSend 10
    BCD1 = 0 'Resets the units BCD common back to LOW
    wait 100 us 'Wait just a bit
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    Address10 = PORTH & 0x0F 'Gets the tens digit of Address and strips off high nibble
    HSerPrint "Address Tens:"
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

    Copied from serial console:
    

    Address Units:5
    Address Tens:3
    Address:35

     
    • Anobium

      Anobium - 2023-09-10

      Ok. That ain't right... should be the same.
      Can you send me the source and ASM for both tests. Thank you

       
  • Anobium

    Anobium - 2023-09-11

    I should have spotted this one days ago. Sorry.

    Address1 = PORTH should be Address1 = LATTH and Address10 = PORTH should be Address10 = LATTH

    The debugger shows the operation as correct, MPLAB-X


    The reason for the mask working is the extra cycles to complete the mask meant PORTH was settled.


    I would recommend use of LATH and I am happy. :-)

     

    Last edit: Anobium 2023-09-11
  • Jerry Messina

    Jerry Messina - 2023-09-11

    If PORTH is an input port then how would reading the LAT register read the state of the pins?
    It would just read the setting of the LAT register, not the PORT pin values.

     
    • Anobium

      Anobium - 2023-09-11

      I am sharing what I see in the simulator. Steve can try on real silicon.

       
  • Anobium

    Anobium - 2023-09-11

    This is a read-modity issue on BCD1 not PORTH

    I have tested on silicon.

    Test code.

    BCD1 = 0
    BCD1 = 1  - this is connected for this test to porth.0
    Address1 = PORTH
    
    CLS
    Print Address1
    
    Frequency Address1 result
    16 1
    24 1
    32 0
    64 0

    Test code with a NOP added. just like the masking operation with 0X0F.

    BCD1 = 0
    BCD1 = 1  - this is connected for this test to porth.0
    NOP
    Address1 = PORTH
    
    CLS
    Print Address1
    
    Frequency Address1 result
    16 1
    24 1
    32 1
    64 1
     
  • Steve Scott

    Steve Scott - 2023-09-11

    This did NOT work BTW, gave ZERO:
    'Gets address
    BCD1 = 1 'Sets the units digit of BCD switch common Address HIGH
    Address1 = PORTH '& 0x0F 'Gets the units digit of the Address and strips off high nibble
    NOP
    HSerPrint "Address Units:"
    HSerPrint Address1
    HSerSend 13
    HSerSend 10
    BCD1 = 0 'Resets the units BCD common back to LOW
    wait 100 us 'Wait just a bit
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    Address10 = PORTH '& 0x0F 'Gets the tens digit of Address and strips off high nibble
    NOP
    HSerPrint "Address Tens:"
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

     
    • Anobium

      Anobium - 2023-09-11

      The NOP would be after setting the BCD line to 1.

       
  • Steve Scott

    Steve Scott - 2023-09-11

    This also did NOT work, using LATH:
    'Gets address
    BCD1 = 1 'Sets the units digit of BCD switch common Address HIGH
    ' Address1 = PORTH '& 0x0F 'Gets the units digit of the Address and strips off high nibble
    Address1 = LATH 'Gets the units digit of the Address and strips off high nibble
    HSerPrint "Address Units:"
    HSerPrint Address1
    HSerSend 13
    HSerSend 10
    BCD1 = 0 'Resets the units BCD common back to LOW
    wait 100 us 'Wait just a bit
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    ' Address10 = PORTH 'Gets the tens digit of Address and strips off high nibble
    Address10 = LATH 'Gets the tens digit of the Address and strips off high nibble
    HSerPrint "Address Tens:"
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

     
    • Anobium

      Anobium - 2023-09-11

      Agree. the LAT will not resolve. The NOP may.

       
  • Steve Scott

    Steve Scott - 2023-09-11

    Evan-
    see post before my last, NOPdid not work.
    At least one NOP did not.

     
  • Anobium

    Anobium - 2023-09-12

    That NOP was in the wrong place.

    'Gets address
    BCD1 = 1 'Sets the units digit of BCD switch common Address HIGH
    NOP
    Address1 = PORTH 'Gets the units digit of the Address and strips off high nibble

    ...
    ...
    ...

    BCD1 = 0 'Resets the units BCD common back to LOW
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    NOP
    Address10 = PORTH 'Gets the tens digit of Address and strips off high nibble

    ....
    ....
    ....

    You are adding the NOP after setting the port.pin high ( as this port.pin is the source of the input for the next read). See about.

    See if this works,

     
  • Jerry Messina

    Jerry Messina - 2023-09-12

    I think I see what's likely going on here...

    The 18F67K40 has IO slew rate control for the port pins, and it defaults to slow mode (SLRCONx registers default to 0xFF).

    If you have this:

    BCD1 = 1 'Sets the units digit of Address HIGH
    Address1 = PORTH 'Gets the units digit of the Address
    

    PORTH is read on the next cycle right after setting the pin high, so it may not have time to slew (slow mode).

    When you add code to mask the upper unused nibble:

    BCD1 = 1 'Sets the units digit of Address HIGH
    Address1 = PORTH & 0x0F  'mask upper nibble (adds one cycle)
    

    an additional instruction cycle gets added before PORTH is read, so it has time to settle.
    That has the same timing as:

    BCD1 = 1 'Sets the units digit of Address HIGH
    nop
    Address1 = PORTH
    

    You can set the IO slew rate for PORTG to normal using SLRCONG = 0, but it might be a good idea to add a 'nop' after setting PORTG outputs anyway, and mask the unused bits of PORTH.

    #define BCD1 PORTG.4
    #define BCD10 PORTG.6
    
    Dir PORTG.4 Out
    Dir PORTG.6 Out
    Dir PORTH In
    
    Dim Address1 as Byte
    Dim Address10 as Byte
    
    ' set output slew rate for PORTG to normal (fast)
    SLRCONG = 0
    
    'Gets address
    BCD1 = 1 'Sets the units digit of Address HIGH
    nop              ' add 1 cycle for IO delay
    Address1 = PORTH 'Gets the units digit of the Address
    'Address1 = PORTH & 0x0F   'mask unused (adds extra cycle)
    BCD1 = 0
    nop
    
    BCD10 = 1 'Sets the tens digit of Address HIGH
    nop              ' add 1 cycle for IO delay
    Address10 = PORTH 'Gets the tens digit of Address
    'Address10 = PORTH & 0x0F 'mask unused (adds extra cycle)
    BCD10 = 0
    nop
    
     

    Last edit: Jerry Messina 2023-09-12
    • Anobium

      Anobium - 2023-09-12

      Jerry, yep. That was my working theory. A great explanation.

       
  • Steve Scott

    Steve Scott - 2023-09-12

    Thanks Jerry - I overlooked that register.
    Will also add the NOP just to try everything.
    This did NOT work:

    config SLRCONH = 0 'Sets SLEW to max rate

    config SLRCONG = 0 'Sets SLEW to max rate

    'Gets address
    BCD1 = 1                        'Sets the units digit of BCD switch common Address HIGH
    Address1 = PORTH                '& 0x0F  'Gets the units digit of the Address and strips off high nibble
    HSerPrint "Address Units:" 
    HSerPrint Address1   
    HSerSend 13
    HSerSend 10
    BCD1 = 0                        'Resets the units BCD common back to LOW
    wait 100 us                     'Wait just a bit
    BCD10 = 1                       'Sets the tens digit of BCD switch common Address HIGH
    Address10 = PORTH               'Gets the tens digit of Address and strips off high nibble
    HSerPrint "Address Tens:" 
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0                       'Resets the tens BCD common back to LOW
    Address =  (Address10 * 10) + Address1   'Creates the board address
    
     
  • Steve Scott

    Steve Scott - 2023-09-12

    Gentlemen-
    The code now works WITHOUT using the masking line.
    Code for address here:

    config SLRCONH = 0 'Sets SLEW to max rate

    config SLRCONG = 0 'Sets SLEW to max rate

    'Gets address
    BCD1 = 1                        'Sets the units digit of BCD switch common Address HIGH
    NOP                             'Wait a cycle
    Address1 = PORTH                '& 0x0F  'Gets the units digit of the Address and strips off high nibble
    HSerPrint "Address Units:" 
    HSerPrint Address1   
    HSerSend 13
    HSerSend 10
    BCD1 = 0                        'Resets the units BCD common back to LOW
    NOP                             'Wait a cycle
    

    ' wait 100 us 'Wait just a bit
    BCD10 = 1 'Sets the tens digit of BCD switch common Address HIGH
    NOP 'Wait a cycle
    Address10 = PORTH 'Gets the tens digit of Address and strips off high nibble
    HSerPrint "Address Tens:"
    HSerPrint Address10
    HSerSend 13
    HSerSend 10
    BCD10 = 0 'Resets the tens BCD common back to LOW
    NOP 'Wait a cycle
    Address = (Address10 * 10) + Address1 'Creates the board address

    What I have learned - go back and re-read ALL about ALL port registers <grin>.
    It has been an illuminating journey, Thanks to All who helped in this.
    Regards, and a hoist of an Adult Beverage in your honor later this evening!
    -Steve</grin>

     
    • Anobium

      Anobium - 2023-09-12

      Good to hear!

      Learning all time here!

       
<< < 1 2 (Page 2 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.