Searching \ for '[PIC] question for C experts' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=c
Search entire site for: 'question for C experts'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] question for C experts'
2009\01\30@012921 by Vanzo Stefano

flavicon
face
Ok, I have to "and" and "or" with some PORT.
With 8bit models I just take my char variable and use it

With 16bit models can I do:

DATA_PORT |= data8bit & 0x00f0;

or do I have to:

int data16bit = 0x0000;
data16bit += data8bit;
DATA_PORT |= data16bit & 0x00f0;

The question: can I "and" a char with a int ending up with the char in
the first two nibbles?

Thanks to all

Stefano Vanzo

2009\01\30@015724 by solarwind

picon face
On Fri, Jan 30, 2009 at 1:29 AM, Vanzo Stefano <spam_OUTpicsTakeThisOuTspamvanzo.it> wrote:
> Ok, I have to "and" and "or" with some PORT.
> With 8bit models I just take my char variable and use it
>
> With 16bit models can I do:
>
> DATA_PORT |= data8bit & 0x00f0;
>
> or do I have to:
>
> int data16bit = 0x0000;
> data16bit += data8bit;
> DATA_PORT |= data16bit & 0x00f0;
>
> The question: can I "and" a char with a int ending up with the char in
> the first two nibbles?
>
> Thanks to all
>
> Stefano Vanzo

Yes.

If you do this:

byte b = byte c & int i;

b will be = c & the lower byte of i.

You will lose the upper bits of i though...


--
solarwind

2009\01\30@020113 by solarwind

picon face
For example, if you do this:


#include <stdio.h>
#include <stdlib.h>

typedef unsigned char byte;

int main() {
   byte b = 0;
   int i = 300;
   byte c = 0xF0;
   b = c & (byte)i;
   printf("0x%X", b);

   return 0;
}



You will get

0x20


makes sense because


b = 00000000
i = 100101100
c = 11110000




i = 100101100
c = x11110000

result of & = 00100000  = 0x20

2009\01\30@024858 by Stefano Vanzo

flavicon
face
solarwind ha scritto:
{Quote hidden}

I have two 16bits because DATA_PORT is 16 bit. I want to know if
data8bit ends up in the lowwer part of DATA_PORT and does not effect the
two high nibbles.

DATA_PORT |= data8bit & 0x00f0;

--
Regards

Stephen

2009\01\30@031008 by Tamas Rudnai

face picon face
> I have two 16bits because DATA_PORT is 16 bit. I want to know if
> data8bit ends up in the lowwer part of DATA_PORT and does not effect the
> two high nibbles.

Look for 'auto casting' and 'integer promotion' on your C reference.

Tamas



On Fri, Jan 30, 2009 at 7:48 AM, Stefano Vanzo <picsspamKILLspamvanzo.it> wrote:

{Quote hidden}

> -

2009\01\30@040658 by Jan van Wijk

flavicon
face
Hello Stefano,

On Fri, 30 Jan 2009 08:48:31 +0100, Stefano Vanzo wrote:

>>> With 16bit models can I do:
>>>
>>> DATA_PORT |= data8bit & 0x00f0;

Yes, allthough I do not understand why you 'and' with 0x00f0.
That will ZERO the four lowest bits from your data8bit value.
But that is probably part of yor application logic :-)


>>>
>>> or do I have to:
>>>
>>> int data16bit = 0x0000;
>>> data16bit += data8bit;
>>> DATA_PORT |= data16bit & 0x00f0;

No, that has the same effect as the above ...
The 8-bit value is automatically promoted to 16 bit.

>>> The question: can I "and" a char with a int ending up with the char in
>>> the first two nibbles?

Yes

<snip>
>I have two 16bits because DATA_PORT is 16 bit. I want to know if
>data8bit ends up in the lowwer part of DATA_PORT and does not effect the
>two high nibbles.

Well, it DOES affect the high nibbles in principle, but since your operation
is an OR, and the two high-nibbles in your argument are ZERO, no change
will take place. (the |= causes a 16-bit read-modify-write)

Your 8-bit value is promoted to a 16-bit value before that operation,
in this case by adding two zero nibbles.
>
>DATA_PORT |= data8bit & 0x00f0;

For readability, I would add parentheses on the 'and' clause:

DATA_PORT |= (data8bit & 0x00f0);

Regards, JvW

Jan van Wijk, author of DFSee; http://www.dfsee.com
-------------------------------------------------------------------------------

2009\01\30@061627 by solarwind

picon face
On Fri, Jan 30, 2009 at 2:48 AM, Stefano Vanzo <EraseMEpicsspam_OUTspamTakeThisOuTvanzo.it> wrote:
> I have two 16bits because DATA_PORT is 16 bit. I want to know if
> data8bit ends up in the lowwer part of DATA_PORT and does not effect the
> two high nibbles.
>
> DATA_PORT |= data8bit & 0x00f0;
>
> --
> Regards
>
> Stephen

Yes, it will end up in the lower part of DATA_PORT. But remember that
if you & anything with 00 (the upper part), the result is always 0.


--
solarwind

2009\01\30@093248 by Stefano Vanzo

flavicon
face
Thanks, I was looking for this.

Stefano


Jan van Wijk ha scritto:
{Quote hidden}

2009\01\30@133545 by Bob Ammerman

picon face
On Fri, Jan 30, 2009 at 2:48 AM, Stefano Vanzo <picsspamspam_OUTvanzo.it> wrote:
>> I have two 16bits because DATA_PORT is 16 bit. I want to know if
>> data8bit ends up in the lowwer part of DATA_PORT and does not effect the
>> two high nibbles.
>>
>> DATA_PORT |= data8bit & 0x00f0;
>>
>> Stephen
>

> Yes, it will end up in the lower part of DATA_PORT. But remember that
> if you & anything with 00 (the upper part), the result is always 0.
> --
> solarwind

Assuming that DATA_PORT is declared as a 16-bit value and data8bit as an
8-bit value**, a 'conforming' C compiler must execute the above AS IF* it
did the following:

DATA_PORT = (int16) ( (int) DATA_PORT | (( (int) data8bit & (int) 0xF0)))

which is to say that it must EFFECTIVELY* promote everything to 'int' (which
would typically be 16 or 32 bits wide), then do the operations and finally
save the result.

*Note the capitalized words. The compiler is free to optimize the expression
as long as the results sure to always be the same as they would be without
the optimization.

(Note we are assuming that data8bit is declared unsigned, or that the
particular compiler does zero extension as opposed to sign extension of 8
bit values. Of course making the latter assumption is a bad idea if you are
trying to write portable code).

So, what does this mean for the current case? Well, since the "|=" is
carried out at least at the precision of DATA_PORT, then the 8 high bits and
4 low bits of DATA_PORT will be unchanged (because we are 'OR'ing them with
zero), the second least significant nibble will be whatever it was before,
or'd with the top four bits of DATA_PORT.

Note that this is probably *not* the intention of the OP. I am guessing they
want to:
   1) Leave the top 8 bits alone.
   2) Set the next four bits to the 4 msbits of data8bit.
   3) Force the 4 low bits to zero.

What they are actually doing is:
   1) Leaving the top 8 bits alone.
   2) Setting the next four bits to the 4 msbits of data8bit.
   3) Leaving the bottom 4 bits alone.

The following is a non-portable way to perhaps get the desired result:

* (unsigned char *) &DATA_PORT = data8bit & 0xF0;

In this ugly messs we first take the address of DATA_PORT (the &), then tell
the compiler that that address is really the address of a byte (the
(unsigned char *)), and then assigning to that byte. This only works on
little-endian architectures like the 16-bit PICs and x86. It breaks horribly
on big-endian machines.

You can also express the above as:

(( unsigned char *) &DATA_PORT)[0] = data8bit & 0xF0;

Then changing this to:

((unsigned char *) &DATA_PORT)[1] = data8bit & 0xF0;

will probably work on a big-endian system.

This last expression would (probably) write to the most-significant byte of
DATA_PORT on a little-endian system.

--- Bob Ammerman
RAm Systems

2009\01\30@140112 by Vanzo Stefano

flavicon
face

> What they are actually doing is:
>     1) Leaving the top 8 bits alone.
>     2) Setting the next four bits to the 4 msbits of data8bit.
>     3) Leaving the bottom 4 bits alone.
>
> --- Bob Ammerman

this is the intention to TRIS, SET and RESET 4 bits of PORTB on a
PIC24HJ128GP502

Thank you
Stephen


More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...