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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 5VdirPortD.6In'bin weight 1dirPortD.5In'bin weight 2dirPortD.4In'bin weight 4 ... ...Group=PortDANDb'01110000'IfGroup=32Then
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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......
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 confirmationLocate 2,0 : Print "From Remote: "Locate 3,5 : Print "Address:"Locate 3,13 : Print AddressHSerPrint "Address:" HSerPrint Address10HSerPrint Address1 HSerSend 13HSerSend 10HSerPrint "Total Address:"HSerPrint AddressHSerSend 13HSerSend 10It works gentlemen, same code I have used, but if you do not mask using'& 0x0F'(noquotes)itreturnszero.
Itisnotformetotrytounderstandit-yet.AllIknowisthatitworks.
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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?
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
I will try that but why would you need to declare 2 variables?
Can't change ports unfortunately
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.
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
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?
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.
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......
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.
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
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.
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
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
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
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.
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.
Huh, learn something new everyday, good job!
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.
I agree.
But, reading PORTH without the mask would not return 0x00 when the lower nibble had bit that where high.
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
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.
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
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
It is probably good coding practice to mask off even if there are only 4 bits in the port.
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.
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.