# bit's and ports

Status
Not open for further replies.

#### be80be

##### Well-Known Member
I'm trying to get my head around how to send bit's out a 2 ports. I have 2 ports RB0 and RB1 then RC0 to RC7
Code:
#define BIT8 0x01
#define BIT7 0x02
#define BIT8 0x04
#define BIT7 0x08
#define BIT6 0x10
#define BIT5 0x20
#define BIT4 0x40
#define BIT3 0x80
#define BIT2 0x100
#define BIT1 0x200
char bits[10] = {BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, BIT8, BIT9, BIT10};
// how would I use this here to set it to say 1023

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Hi Burt! Trying to understand what you need???

So a 10 bit number... If I get you correctly... It's the same really as the ADC result... Two bits in low and 8 bits in high.

portc = (unsigned char) (1023 >> 2);
portb = (unsigned char)1023 % 2;

This puts bit 0 and 1 on portb and the rest on portc..

#### be80be

##### Well-Known Member
Yep that's it I was playing with the Bit array thing but your Idea looks better thanks

#### be80be

##### Well-Known Member
Thanks Ian I'm starting to see the light here
Code:
 while (1)
{
uint16_t convertedValue;

__delay_ms(100); // 1 Second Delay
LATC = (unsigned char) (convertedValue >> 2);

LATB = (unsigned char)convertedValue % 2;
}
}
/**
End of File
*/

#### Daniel Wood

##### Member
It looks like you may have already solved the issue, but there is a more efficient way to split a 16-bit value over two ports. Just by using a bit of clever C memory management.

By using a struct inside a union, you can read/write a 16-bit value as a whole. But you can also read/write the exact same value as if it is split into two separate 8-bit integers.
It should look something a little like this...

Code:
union {
uint16_t value;
struct {
uint8_t lsb;
uint8_t msb;
};
} convertedValue;

int main(void) {

convertedValue.value = ADCC_GetSingleConversion(channel_ANA0); //Lets say convertedValue.value == 0xBEEF

LATC = convertedValue.msb; // this value would be 0xBE
LATB = convertedValue.lsb;  // and this value would be 0xEF
}
The beauty about this method is that you can extend the union and access each bit individually if you wanted.

#### be80be

##### Well-Known Member
I seen some samples of using union I'm learning xc8 getting better slowly but thanks you both really helped

#### Mike - K8LH

##### Well-Known Member
Hi Burt! Trying to understand what you need???

So a 10 bit number... If I get you correctly... It's the same really as the ADC result... Two bits in low and 8 bits in high.

portc = (unsigned char) (1023 >> 2);
portb = (unsigned char)1023 % 2;

This puts bit 0 and 1 on portb and the rest on portc..
shouldn't that have been; portb = (unsigned char)1023 % 4 or portb = (unsigned char)1023 & 3 ?

#### be80be

##### Well-Known Member
If you & 3 that shiffs 2 places to the left right?

#### Daniel Wood

##### Member
Be80be, x = y & 3, or in binary, x = y & 0b00000011 is an AND operation, normally called a bit mask in this case. Essentially if x is one of your ports, the maximum you're going to see on the port is pins 1 and 2 turned on.

I agree with mike.. Bitmasking a port with & 2 would allow only pin 2 on the port to flash (0b00000010)

#### be80be

##### Well-Known Member
I was looking at it and im not getting the full 1023 of the adc im one bit off
don't think it was showing the full 10 bits

#### Daniel Wood

##### Member
Personally I think the shift routines mentioned are wrong. The confusion comes from having an 11bit number stored in a 16 bit variable.

The standard 16bit to 8bit split is:
Code:
LATC = (uint8_t) data >> 8;
LATB= (uint8_t) data & 0xFF;
For example, in 16bit binary you get data as:
0b0000 0101 0110 1111

Latc would be shifted to:
0b0000 0000 0000 0101

Latb would be masked off to:
0b0000 0000 0110 1111

Which looks like the correct way to me...

#### be80be

##### Well-Known Member
The is only 10 bit I'm using PORTC 0 to 7 for the first 8 bit's and PORTB 0 to 1 for the last 2

Forum Supporter