Menu

Looking for a GCBasic cool way to read BCD rotary switches

2023-09-07
2023-09-12
1 2 > >> (Page 1 of 2)
  • Steve Scott

    Steve Scott - 2023-09-07

    Hello All (again)-
    I am learning a great deal thanks to all who have submitted info on the discussion forums and to Evan.
    I have looked and may have overlooked this.
    I have 2 BCD switches used for addressing and are tied to PORTH on a 18F67K40 proc.
    PORTH is a nybble only port and the 1, 2, 4, 8 weighted lines go to PORTH.0= 1, PORTH.1=2, PORTH.2=4 and PORTH.3=8.
    I know how test the common lines to the 2 switches by setting them HIGH and run through the 4 bits on PORTH to see which one is HIGH. All switches are diode-isolated and pulled LOW.
    As I am learning, there may be some cool GCBasic command to this more efficiently than FOR/NEXT loops etc.
    Anyone done this using GCBasic and willing to help me learn?
    Regards to All.

     
  • Steve Scott

    Steve Scott - 2023-09-08

    OK Guys, still learning....
    I want to read an entire port, specifically PORTH which is only the low nybble 4 bits on my 18F67K40.
    It looks like I can:
    Dir PORTH In
    I have 4 resistors pulling PORTH.0 - PORTH.3 to ground (low).
    Through my BCD switch I have set a '5' which brings PORTH.0 and PORTH.2 both high. I have set this to be all the time for testing.
    I checked the port with a probe and I have the correct bits set.
    When I read PORTH by:
    Dim Address1 as Byte
    and
    Address1 = PORTH
    And print Address1 to the LCD I get a '0'.
    I can hardset the var Address1 to 5 and it prints '5' on the LCD.
    I have looked in the docs and on this discussion and cannot find why I cannot read the port.
    What am I doing wrong?

     
  • kent_twt4

    kent_twt4 - 2023-09-08

    Declare and add shadow register help?

    dim BCDSW as Byte
    Address1 = PORTH
    BCDSW = Address1
    Print BCDSW

    Or, different port nibble?

     

    Last edit: kent_twt4 2023-09-08
  • Steve Scott

    Steve Scott - 2023-09-08

    I will try that but why would you need to declare 2 variables?

     
  • Steve Scott

    Steve Scott - 2023-09-08

    Can't change ports unfortunately

     
  • kent_twt4

    kent_twt4 - 2023-09-08

    Apologies, I am trying to decipher years old code written for a single pushbutton, 3 input bcd switch (0-7). Com is 5V and 10k pulldowns on input pins. Sounds like a similar or equivalent setup.

    Changing ports may or may not expose dat file register or power on reset(initialization) problems. Default PPS conditions could also be a factor. Of course if PortH already committed to pcb then?

    Not able to follow along in hardware, do not have this device.

    A couple of lines of similar code on the switch, so not seeing a problem there.

    'Binary switch pins with Com as 5V
    dir PortD.6 In   'bin weight 1
    dir PortD.5 In   'bin weight 2
    dir PortD.4 In   'bin weight 4
     ...
     ...
       Group = PortD AND b'01110000'
       If  Group = 32 Then
    
     
  • Steve Scott

    Steve Scott - 2023-09-08

    Kent_twt4-
    This is what I have and I cannot change ports - board already designed and known working with another compiler:
    I just tried:
    'Define BCD

    define BCD1 PORTG.4 'Set HIGH and check for units Address

    Dir PORTG.4 Out

    define BCD10 PORTG.6 'Set HIGH and check for tens Address

    Dir PORTG.6 Out
    Dir PORTH In 'Whole PORTH is Input
    Dim Address1 as Byte
    Dim Address10 as Byte
    'Gets address
    BCD1 = 1 'Sets the units digit of Address HIGH
    Address1 = PORTH 'Gets the units digit of the Address
    BCD1 = 0
    wait 100 us
    BCD10 = 1 'Sets the tens digit of Address HIGH
    Address10 = PORTH 'Gets the tens digit of Address
    BCD10 = 0

    HSerPrint "Address:"
    HSerPrint Address10
    HSerPrint Address1
    HSerSend 13
    HSerSend 10

    And I get two zeroes on the terminal.
    Pic of how I have the two BCD switches connected;
    BCD-1 is PORTH.0
    BCD-2 is PORTH.1
    BCD-4 is PORTH.2
    BCD-8 is PORTH.3
    Bits 4, 5, 6, 7 are brought out from the chip.
    BCD_ONES is PORTG.4
    BCD_TENS is PORTG.6

     
  • kent_twt4

    kent_twt4 - 2023-09-08

    Voltages for PortG and PortH pins look good? Brand and part number for the bcd switch? Not sure if I am going to help further, not having the setup, or much PPS experience if that someway enters into it. Perhaps others have some ideas?

     
  • Anobium

    Anobium - 2023-09-09

    I just checked the datasheet. and the DAT file for PORTH. The register is correct.
    Worth noting that PORTH only has four bits. PORTH.0 to PORTH.3 and these are correctly defined in the DAT file.

    I am with Kent - check the voltages.

     
  • Steve Scott

    Steve Scott - 2023-09-09

    I have checked the voltages and a HIGH = 4v, LOW = 0v.
    I have attached the BCD switches and their connection to the proc as snippets of the schematic.
    I have been told you can read an entire port, so what is the configuration?
    I have tried Variable=PORTH (yes, I know its only 4 bits, other compiler just set high nibble to all zeros) but I get zeroes.
    Thanks for assisting on what would be an easy task......

     
  • kent_twt4

    kent_twt4 - 2023-09-09

    Are the PortH pins brought out to a header?. Then start with the basics by turning on/off leds (or check with DVM/probe) for PortH as output, and let us know the results. Still no go? then attach asm file. It doesn't seem like the PortH is acting correctly.

     
  • Steve Scott

    Steve Scott - 2023-09-09

    Hello-
    I just changed the address port to PORTD and it works just fine.
    Seems to be something with PORTH?
    Dir PORTH In 'Whole PORTH is Input
    Dir PORTD In 'Input to test reading a whole port - not used for main code
    ' Address1 = PORTH 'Gets the units digit of the Address - does NOT work
    ' Address1 = 5 'used to hard code for testing - works
    Address1 = PORTD ' used to test read whole port at once - works

     
  • Steve Scott

    Steve Scott - 2023-09-09

    Just tested this:
    Dir PORTH OUT 'Temporary test as we need INPUT
    PORTH.0 = 1 'test for outputs
    PORTH.1 = 0
    PORTH.2 = 1
    PORTH.3 = 0
    All worked as coded, I also tried all 1's and port reported all 1's.
    With BCD switches enabled - I get what I am supposed to - it just does not seem to get in the proc.

     
  • Steve Scott

    Steve Scott - 2023-09-09

    Put code back to NORMAL and still do not have Address reporting correctly on LCD screen or by serial console.
    Attached ASM and HEX file for your peruse.....
    Thanks,
    Steve

     
  • Steve Scott

    Steve Scott - 2023-09-09

    Out of desperation, I have forced these - to no avail:
    (Did notice #CONFIG messes up the headers.... in the code there is just 1 hash):

    CONFIG FEXTOSC = ECH 'EC (external clock) above 8 MHz; PFM set to high power
    CONFIG RSTOSC = EXTOSC 'EXTOSC operating per FEXTOSC bits (device manufacturing default)
    CONFIG CLKOUTEN = OFF 'CLKOUT function is disabled
    CONFIG CSWEN = ON 'Writing to NOSC and NDIV is allowed
    CONFIG FCMEN = OFF 'Fail-Safe Clock Monitor disnabled
    config MCLR = ON 'Uses the RESET pushbutton
    CONFIG MCLRE = INTMCLR 'If LVP = 0, MCLR pin function is port defined function; If LVP =1, RE3 pin fuction is MCLR
    CONFIG PWRTE = ON 'Power up timer enabled
    CONFIG LPBOREN = OFF 'ULPBOR disabled
    CONFIG BOREN = SBORDIS 'Brown-out Reset enabled , SBOREN bit is ignored
    CONFIG BORV = VBOR_285 'Brown-out Reset Voltage (VBOR) set to 2.85V
    config LVP = OFF 'HV on MCLR/VPP must be used for programming
    config TRISH.0 = 1
    config TRISH.1 = 1
    config TRISH.2 = 1
    config TRISH.3 = 1
    config INLVLH.0 = 0
    config INLVLH.1 = 0
    config INLVLH.2 = 0
    config INLVLH.3 = 0
     
  • Steve Scott

    Steve Scott - 2023-09-09

    I got it!
    Even though there is ONLY 4 bits in PORT H, you still have to strip off the high nibble.
    '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
    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
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

    Woo Hoo!
    
     
    • Anobium

      Anobium - 2023-09-10

      This is good that it is working, but, I do not understand.

      PORTH will only return values for the lower nibble. This is not a GC BASIC thing, but, a silicon thing.

      Proof on real silicon here. You can set the PORTH as input or output, setting the LAT for the complete regsister high ( = 255 ). The PORTH returns the correct value. I have lines high or low and I get the value returned - it is only zero when PORTH0..3 are pulled low.

      DIR PORTH IN
      PORTH = 255
      LOCATE 0 ,0 
      PRINT PORTH
      
      DIR PORTH OUT
      PORTH = 255
      LOCATE 1 ,0 
      PRINT PORTH
      end
      

      I need a bit more proof that the mask of 0x0F is required.

      What is the result with the mask ? and what is the value of Address1 and Address10... in the context that as the point of reading Address1 and Address10 i the state of the input/out is not clear in the code about.
      - Address1 and Address10 set as inputs then setting the state to 1 ( port is being pulled low by the resistors ) what state is expected?
      - Address1 and Address10 set as outputs then setting the state to 1 ( port is being pulled low by the resistors ) what state is expected?
      - What is the state of BCD10 when port.bit when BCD1 is set to 1 and the PORTH read into Address1 ?
      - The is the state of BCD1 when port.bit when BCD10 is read into Address10.. BCD1 is set to 0, BCD10 is set to 1 and then PORTH read into Address1 ?

      The required state of BCD1 and BCD10 is more likely to be the issue. Reading PORTH would read 0x00 as these port.bits in PORTH are pulled low.

       
  • kent_twt4

    kent_twt4 - 2023-09-09

    Huh, learn something new everyday, good job!

     
  • Jerry Messina

    Jerry Messina - 2023-09-10

    PORTH will only return values for the lower nibble.

    I don't see anywhere in the datasheet where they define what the unimplemented PORTH bits (RH7:RH4) would read. Since reading PORTH is going to return 8 bits, it's probably a good idea to mask it with 0x0F just to be sure.

     
    • Anobium

      Anobium - 2023-09-10

      I agree.
      But, reading PORTH without the mask would not return 0x00 when the lower nibble had bit that where high.

       
  • Steve Scott

    Steve Scott - 2023-09-10

    All I can say is that when I finally woke up and stripped off the high nibble - it worked as I intended.
    Code below:
    'Define BCD

    define BCD1 PORTG.4 'Set HIGH and check for units Address

    Dir PORTG.4 Out

    define BCD10 PORTG.6 'Set HIGH and check for tens Address

    Dir PORTG.6 Out
    Dir PORTH In 'Whole PORTH is Input

    Dim Address as word
    Dim Address1 as Byte
    Dim Address10 as Byte

    'INIT any peripherals here
    BCD1 = 0
    BCD10 = 0
    Address = 0
    Address1 = 0
    Address10 = 0

    '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
    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
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

        'Print confirmation
    Locate 2,0 : Print "From Remote:        "
    Locate 3,5 : Print "Address:"
    Locate 3,13 : Print Address
    HSerPrint "Address:" 
    HSerPrint Address10
    HSerPrint Address1   
    HSerSend 13
    HSerSend 10
    HSerPrint "Total Address:"
    HSerPrint Address
    HSerSend 13
    HSerSend 10
    
    It works gentlemen, same code I have used, but if you do not mask using
    '& 0x0F' (no quotes) it returns zero.
    It is not for me to try to understand it - yet.  All I know is that it works.
    

    If you want the entire code, contact me privately and I will share or If desired, I can also share the ASM files with and without the masking.

    Thanks and Regards.

     
    • Anobium

      Anobium - 2023-09-10

      Thanks but I cannot replicate your PCB.

      I recommend remove the masking and test again. I am very interested if this does not work.

       

      Last edit: Anobium 2023-09-10
  • Steve Scott

    Steve Scott - 2023-09-10

    Evan-
    I just did:
    '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
    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
    BCD10 = 0 'Resets the tens BCD common back to LOW
    Address = (Address10 * 10) + Address1 'Creates the board address

    Notice I simply put a ' before the & 0x0F mask.
    Adress both on serial console and on LCD is zero.
    

    It is probably good coding practice to mask off even if there are only 4 bits in the port.

     
    • Anobium

      Anobium - 2023-09-10

      Did the change show the correct result?

      I agree about masking as a best practice but I am trying to figure out that reading PORTH does or does not always read 0x00.

       
  • Steve Scott

    Steve Scott - 2023-09-10

    Evan-
    The ONLY way to get the correct result is by masking off the high nibble - top 4 bits.
    Cannot explain it myself as it shouldnt matter but it does.

     
1 2 > >> (Page 1 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.