PDA

View Full Version : I need to play with Nibbles, am i on the right track?



OldMarty
- 5th July 2016, 08:07
Hi All,

I have some code that works around using 4bit(nibbles) to process the code.

Since there's no 'Nibble" option when configuring the VAR varaiables i wonder how i go about accessing 1/2 ports easily????

Here's the basic idea i have so far:



TRISB = 000000 ;set PortB as all OUTputs

;assign some variable names
LO_nibble var byte ;(i wish this could become a 'nibble' option someday)
HI_nibble var byte ;(i wish this could become a 'nibble' option someday)

LO_nibble = PORTB & 001111 ;set "LO_nibble" to access the LSB 4 bits of PortB
HI_nibble = PORTB & 110000 ;set "HI_nibble" to access the MSB 4 bits of PortB

LO_nibble = 11 ; this should set the LSB 4 bits of PortB to whatever value chosen?
HI_nibble = 11 ; this should set the MSB 4 bits of PortB to whatever value chosen?



I know i can isolate/mask bits to only READ 4 bits into a variable, but what do i do to only ensure 4bits are WRITTEN to the 1/2-port??
I know i'm sort of close lol ;-)
Am i to do something like isolating the variable name to eliminate 4 bits?

If i want to write a 4 bit nibble to the LSB/MSB 1/2 of a port, is it going to write an entire byte to the port instead?
Basically the port (PortB in my example) needs to be treated as 2 independent halves.
So, if i'm updating either nibble with new data, i cannot allow it to overwitre the other nibbles contents on the port.

Maybe a few people will find this handy (once fully solved), i hope it helps.


Thanx in advance.
Marty.

OldMarty
- 5th July 2016, 08:16
oh, i may have answered my own question now.....

Since working with 8bit bytes etc, maybe is should just isolate my variables?
something like

LO_nibble = PortB & %00001111, for READING LSB data into LO_nibble
or,
HI_nibble = PortB & %11110000, for READING MSB data into HI_nibble


and then

PortB = LO_nibble & %00001111, for WRITING LSB data to PortB (output pins)
or,
PortB = LO_nibble & %11110000, for WRITING MSB data to PortB (output pins)


Sorry, i haven't wired this idea up yet, so i can't prove my theory until i put something together on the bench.

Regards,
Marty.

pedja089
- 5th July 2016, 10:12
This line
PortB = LO_nibble & %00001111, for WRITING LSB data to PortB (output pins)
Will set bits 4-7 to 0. So it will corrupt high nibble.
You can use this
PORTB=(PORTB & %11110000) | (LO_nibble & %00001111)
But this will cause RMW issue if there is any capacitive load on pins or if slew rate is limited.
There is workaround that, your port is set to output. So there is no need to read state from PORTB.
If you are using 18F then use LATB register.
Or for all PIC declare another variable eg PortBState.
And change state of individual bits in PortBState, and after then write that value to PORTB.
PortBState var byte
PortBState =(PortBState & %11110000) | (LO_nibble & %00001111)
PORTB=PortBState
For high nibble
PortBState =(PortBState & %00001111) | (HI_nibble & %11110000)
PORTB=PortBState

But from your example HI_nibble=11 won't do anything. Because hi nibble of port is reference to high nibble of variable.
If you want to reference hi nibble of port to low nibble of byte then shift value to left.
PortBState =(PortBState & %00001111) | ((HI_nibble<<4) & %11110000)
PORTB=PortBState

OldMarty
- 5th July 2016, 13:02
Hmmm, i'll need to read all that a few times to sink in lol

Basically, i have 4 variables i'm using, but i'm only using data in the LSB of each variable, so the values only range from $00 to $0F, technically i'm only using the LSB value of 0 to F within the code.

I'm currently using(wasting) 4 ports, but only using 1/2 of the port to wire to external LEDs. my code and concept works, but now i'm trying to clean it all up by placing all 4 nibbles across only 2 8bit ports, freeing up the other 2 ports for more I/O pins etc.

At all times, i need to only send info to each 1/2 of a given port WITHOUT corupting or moving bits on the other 1/2 of the port.

Just looking to find a clean way to achieve this.
Marty.

pedja089
- 5th July 2016, 13:32
If that is case, then try this
Create subroutine to set 2 ports like this:
UpdateLed:
PORTB= ((HI_nibbleB<<4) & %11110000) | (LO_nibbleB & %00001111)
PORTC= ((HI_nibbleC<<4) & %11110000) | (LO_nibbleC & %00001111)
RETURN

Do what ever in main loop update variables and then CALL UpdateLed, and that is all.