Combine 2 different 8bit ports into 1 word Var and set/reset a specific bit

Started by Ecoli-557, Jan 27, 2025, 04:28 PM

Previous topic - Next topic

Ecoli-557

I have read with some understanding vars and do understand 8 bit ports and how to set/reset bits in the port.
My new question is how do you combine two 8-bit ports which are NOT consecutive into 1 word variable and how to then set a specific bit in the word variable which will be then visible at the physical port?
I get ClearBit OutputState, PortBit (thanks to folks here helping to make that clear), but how do you combine PORTA and PortD for example into the Word var OutputState?
Is it:
Dim OutputState as Word
Symbol OutputState.Highbyte = PORTA
Symbol OutputState.Lowbyte = PORTD
Because this gives me an error with either Symbol or Dim to set the ports equal to a High or Low byte on the Word OutputState.
I realize my old PBP Pro mindset is still creeping in..........

RGV250

Hi,
I have not tried it but I would just put this after the OutputState is written to.
PORTA = OutputState.HighByte
PORTD = OutputState.LowByte

Bob

Ecoli-557

Thanks RGV250, but that gives me a Invalid Cast for this type of variable.... which was the 2nd Port = var
Seems like this should be an easy thing?

Ecoli-557

RGV250, I just had a thought and changed it to this:
                    ClearBit OutputState, PortNum        '0 =  ON, 1 = OFF
                    PORTF = OutputState.LowByte
                    PORTA = OutputState.HightByte
But the compiler errors at the 2nd PORT statement - in this case the PORTA statement.
Thanks for the input however.

Ecoli-557

RGV250, I noticed the 2nd PORT statement was not in BOLD.  Page 442 reading (again) I susbstituted Byte0 and Byte1 for the statements and they are now Bold and no errors, but it does not perform as I want - so there is something else wrong somewhere.

RGV250

Hi,
This is probably why it did not compile.
QuoteHightByte
note the t

When you say it does not perform as you want, what exactly are you trying to do. If writing to a display or something like that I doubt it would as there will be a very slight delay between the 2 writes. Unless it has a strobe bit?

Bob

trastikata

Hello Ecoli,

I think what you are looking for is this:

QuoteDevice = 18F67K22
Declare  Xtal = 4

Dim MyPort As PORTB
Dim MyPortH As PORTD
Dim wPortData As MyPort.Word

Dim wTemp As Word

Main:
wPortData = 0x0102
wTemp = wPortData

I've put the important part in bold. This will create a Word sized variable wPortData who's Low Byte is aliased to PORTB and the High Byte is aliased to PORTD by using a virtual variable MyPort.

Any reads and writes to wPortData will be actually effected on PORTB and PORTD.

Ecoli-557

RGV250, I am attempting to set/reset a bit or bits in 2 output ports that are not contiguous in memory.  I want to use a variable to set/reset that specific bit.  Easy to do if it is just one 8-bit port, more difficult (unless I am just too tired of thinking about it) if you have two ports that are not contiguous.

trastikata, I like this approach and I read about using the lower case 'w' in front of the Var but it did not seem like it has to be but I will try what you have suggested.

I have two 8-bit Ports which yields 16 bits but to address the correct bit in the 2 ports only needs one 8 bit variable;
BitSel as Byte -> selects one (or more) output bits in the two output ports. '0' selects the 1st bit in PORTB, '3' selects the 4th bit in PORTB, and '7' selects the 8th bit in PORTB, 'A' selects the 2nd bit in PORTD, etc.

That is what I am trying to figure out.

RGV250

Hi,
I am not exactly sure what you need but can you not do it with a simple if/then so if the value is less than 7 (PortA) and if greater or equal to (PortD)?

Bob

Ecoli-557

Hmmm RGV250, let me see if I can describe this better and simpler:
Ports: two 8-bit ports, call them PortA for the low byte and PORTB for the high byte for a total of 16 output bits.
BitSel: a variable (Byte) that selects the output bits in the ports desired.
Example:
BitSel = 0, selects bit0 of PORTA to either be high or low
BitSel = 3, selects bit3 of PORTA to either be high or low
BitSel = 7, selects bit7 of PORTA to either be high or low
BitSel = 8, selects bit0 of PORTB to either be high or low
BitSel = C, selects bit4 of PORTB to either be high or low
BitSel = F, selects bit7 of PORTB to either be high or low

BitSel A = 0 'Bit 2 of PORTB is LOW
Nutz, I just realized this is not going to work like it is in my head!

Does this help you who are helping me?

trastikata

Check the manual for SetBit and ClearBit and combine it with the aliasing example I posted earlier.

RGV250

Hi,
Earlier in the post you mentioned "selects one (or more) output bits", I can see how it could work for one bit but cannot see how you would set 2 or more bits at the same time?

Regards,
Bob

Ecoli-557

OK trastikata-
thanks for helping, this is what I have:
     Dim OutputState As PORTF
     Dim OutputStateH As PORTA
     Dim wOutputStateData As OutputState.Word                 'All 16 bits of 2, 8 bit ports 
     Dim PortNum As Byte 'Selected Port Bit

there is some code to determine which port bit to set or reset

ClearBit wOutputStateData, PortNum 'Resets Port bit held in PortNum

or

SetBit wOutputStateData, PortNum 'Sets Port bit help in PortNum

I think I understand what you have suggested, but it does not work yet and it may be in my logic.
To understand your suggestion I will write a simple code fragment with just your suggestion.

Will let you know when I get it coded.
Regards.


Ecoli-557

RGV250, thanks for the response.
If BitSel = 5, that would be Bits 3&4 of PORTA.

I am going to write a code fragment that just sets up the chip, and my serial debug and try to get this compiler's finer details of bit and port manipulation - I should have done that a while ago.
Thanks to all, I will update later when smaller code fragment is written........

trastikata

Don't forget to set both ports to outputs and disable any analog functions at the top of your program.

RGV250

Hi,
QuoteIf BitSel = 5, that would be Bits 3&4 of PORTA.
How do you differentiate that from just bit 6 on PORTA?

Ecoli-557

trastikata - yes I will ensure that as well - I had it before.

RGV250 - that is where I get stuck; a Byte index to two 8-bit ports.......

RGV250

Hi,
Are you overthinking it, what is wrong with just doing
OutputState.0 = 0
OutputState.1 = 1
OutputState.2 = 1
/////
OutputState.14 = 0
OutputState.15 = 1

and then use
PORTA = OutputState.highbyte
PORTD = OutputState.lowbyte

Bob

Ecoli-557

Would this work?
Dim PortNum As Byte    'Port Pin r'eqd
Dim PortFunc As Byte   '0 = Port Pin is LOW, 1 = Port Pin is HIGH


      CaseSelection:   
      Select Case PortNum
             Case0: Case 0x0 
                If PortFunc = 1 Then SetBit, PortNum
                If PortFunc = 0 Then ClearBit, PortNum
             Case1: Case 0x1 
                If PortFunc = 1 Then SetBit, PortNum
                If PortFunc = 0 Then ClearBit, PortNum
             Case2: Case 0x2 
                If PortFunc = 1 Then SetBit, PortNum
                If PortFunc = 0 Then ClearBit, PortNum
             Case3: Case 0x3 
                If PortFunc = 1 Then SetBit, PortNum
                If PortFunc = 0 Then ClearBit, PortNum
      EndSelect

Long and verbose however.....

Ecoli-557

RGV250, My Wife says I overthink everything! <grin>.
I posted as you just did, I wanted to 'automate' what I needed to do with the ports because there may be the need for more than 1 'selected' at a time - which is why I thought about using SelectCase.
This is for an ethernet-based I/O board that I plan to let others use.
Funny thing, I have the ethernet stuff working - just this simple I/O port bit selection is driving me nutz.
When all said and done, I will release the code to this group..... when I get the port bits worked out.