writing a byte to 16 bit port

Feb 14, 2008 10 Replies

Hi, What is the best (simplest) way to write a byte to a 16 bit port pin with out disrupting the other MSB pins. In my case I'm trying to write a byte to the LSByte programmed in C on a dsPIC.



Something like:



unsigned char temp; temp = 19; PORTB = temp;



Even though the variable 'temp' is only a byte long, I'm pretty sure it will toggle the MSByte in the 16 bit PORTB register.



Any ideas?



Thomas Magma


If you can't do a read-modify-write on the port, something like: temp = 19; foo = ((PORTB & 0xFF00) | temp); PORTB = foo;

then try keeping a shadow register, i.e., *all* changes to PORTB are first done to ShadowB and then ShadowB is written to the port.

Rich Webb Norfolk, VA

It kind of depends on how you C compiler encodes the assembly code, but I am sure they do it right.

Take a look at the dsPIC30F/33F Programmer?s Reference Manual

formatting link

Section 4.4, all will be reveled.

donald

Thanks Rich,

What is the 'foo' for? Couldn't I just: PORTB = ((PORTB & 0xFF00) | temp);

to simplify things?

Thomas

Probably, although [disclaimer: never worked on dsPICs or with that specific compiler] it's likely that PORTB is not a simple object and there could be side effects that I'm not aware of that come into play when PORTB is referenced. Using a throw-away temp should guarantee that bad things won't happen.

Rich Webb Norfolk, VA

Thanks Donald,

I hadn't seen that programming reference manual before, but it only talks about byte addressing in assembly language and not in C. I'm kind of looking for a clean way to do it in C.

Thomas

Not an answer to your question-- I think that is partly in donald's suggestion and partly in the C30 compiler User's Guide if you want to use the byte mode capability-- or use the and/or-- but 99.9% of the time you should NOT be writing to PORTB in the first place-- rather use LATB (or B sorry). Best regards, Spehro Pefhany

"it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com

I did mean LATB. I've already been through that painful LAT vs PORT learning curve, but thanks anyways.

to

ill

Nice one. This is the famous trick to be adapted in this scenario :):)

Karthik Balaguru

Assuming you are using the Microchip C30 compiler include generic.h and use an ugly cast like.

((WORD_VAL*)&LATB)->byte.LB = 0x23;

((WORD_VAL*)&LATB)->byte.HB = 0x45;

or define your own structure to map over LATB like LATBbits is done in the processor header file and add a line to the linker script file to define its address.

Depends on how PORTB is declared in C. If it's declared as a 16 bit memory location, the C compiler will certainly promote the byte value to a 16 bit int and thus write zeros to the MSB. If the MSB and LSB of the port can be addressed as two (8 bit) char locations, you can get away with a simple assignment.

Assumin 16 bit only, I'd go for PORT = (PORT & 0xff00) | new_lsb_value; or the "shadow" method if the port can't be read. The port should probably be declared volatile too.

Anahata

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required