EmbeddedRelated.com
Forums

convert 16 bit port to Char

Started by Thomas Magma July 3, 2008
Hello,

I'm programming in C on a dsPIC33F and I'm trying to find the most efficient 
way to save a 8-bit signed value found on the LSByte of PORTD to a CHAR. 
That is, the lower byte of PORTD contains a signed integer that is 8-bits 
wide and I need to save it to a CHAR data type. I don't care what is on the 
upper byte of PORTD.

What would be the most efficient way to do this?

Thanks.

Thomas


"Thomas Magma" wrote:
>... I'm trying to find the most efficient >way to save a 8-bit signed value found on the LSByte of PORTD to a CHAR. >That is, the lower byte of PORTD contains a signed integer that is 8-bits >wide and I need to save it to a CHAR data type. I don't care what is on the >upper byte of PORTD.
Just read the value and assign it to a char variable. Assuming you do not need to do anything special to access the port: #define INT16 [put right type here] INT16 * port_d = [put address of PORTD here]; char c; ... c = *port_d; ... -- Roberto Waltman [ Please reply to the group, return address is invalid ]
Roberto Waltman wrote:

> #define INT16 [put right type here]
You should use typedef instead of #define
> INT16 * port_d = [put address of PORTD here];
You should add a cast to avoid compiler warnings for C compilers: INT16* port_d = (INT16*) [put address of PORTD here]; In C++ not adding a cast would be an error. -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
>>... I'm trying to find the most efficient >>way to save a 8-bit signed value found on the LSByte of PORTD to a CHAR. >>That is, the lower byte of PORTD contains a signed integer that is 8-bits >>wide and I need to save it to a CHAR data type. I don't care what is on >>the >>upper byte of PORTD. > > Just read the value and assign it to a char variable. Assuming you do > not need to do anything special to access the port: > > #define INT16 [put right type here] > > INT16 * port_d = [put address of PORTD here]; > char c; > > ... > c = *port_d; > ...
Thanks Roberto, I guess this would make sense if the data representation of the dsPIC33 using the C30 compiler was stored in little endian format. Do you know if it is for sure? Thomas
Thomas Magma wrote:

> Thanks Roberto, I guess this would make sense if the data representation of > the dsPIC33 using the C30 compiler was stored in little endian format. Do > you know if it is for sure?
This would be a problem, if you access a union or cast the int* to char*, but if you first read the int* and then assign it to an char, endian doesn't matter, the lower 8 bits are used all the time, which is what you asked for. Of course, if you read the 16 bit value from PORTD, endian could be a problem. -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
On Thu, 3 Jul 2008 21:51:39 +0200, Frank Buss <fb@frank-buss.de> wrote
in comp.arch.embedded:

> Roberto Waltman wrote: > > > #define INT16 [put right type here] > > You should use typedef instead of #define > > > INT16 * port_d = [put address of PORTD here]; > > You should add a cast to avoid compiler warnings for C compilers: > > INT16* port_d = (INT16*) [put address of PORTD here]; > > In C++ not adding a cast would be an error.
It would be an error in C as well. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jack Klein wrote:

> On Thu, 3 Jul 2008 21:51:39 +0200, Frank Buss <fb@frank-buss.de> wrote >> >> You should add a cast to avoid compiler warnings for C compilers: >> >> INT16* port_d = (INT16*) [put address of PORTD here]; >> >> In C++ not adding a cast would be an error. > > It would be an error in C as well.
This depends on the compiler. E.g. with GCC 3.4.4 it is a warning, but with ICC08 6.11 it is an error. -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
Thomas Magma wrote:
>>> ... I'm trying to find the most efficient way to save a 8-bit >>> signed value found on the LSByte of PORTD to a CHAR. That is, the >>> lower byte of PORTD contains a signed integer that is 8-bits >>> wide and I need to save it to a CHAR data type. I don't care what >>> is on the upper byte of PORTD. >> >> Just read the value and assign it to a char variable. Assuming you >> do not need to do anything special to access the port: >> >> #define INT16 [put right type here] >> >> INT16 * port_d = [put address of PORTD here]; char c; >> >> ... c = *port_d;
Better still: c = (char) *port_d; It may work, but you may get a warning. Always using a cast sends a hint to the compiler and makes it clear when reading the code what is actually being done. To be absolutely correct you should have a (const *) when loading the absolute address and cast this to the pointer type as well. This is the sort of construct I usually use: volatile U16 *pu16RegisterPtr = (U16 * const) REGISTER_ADDRESS; Got this originally from Harbison & Steele and it seems to be correct. The volatile keyword is telling the compiler that no part of the expression should be changed or optimised in any way, while the const keyword tells the compiler that this is, as expected a fixed value. Chris
>
Jack Klein wrote:
> On Thu, 3 Jul 2008 21:51:39 +0200, Frank Buss <fb@frank-buss.de> wrote
>> INT16* port_d = (INT16*) [put address of PORTD here];
>> In C++ not adding a cast would be an error.
> It would be an error in C as well.
I'll call. Show why exactly this would be an error. And no, examples of compilers that refuse to accept this don't count as evidence.
Hans-Bernhard Br&#4294967295;ker wrote:
> Jack Klein wrote: >> Frank Buss <fb@frank-buss.de> wrote >> >>> INT16* port_d = (INT16*) [put address of PORTD here]; >>> >>> In C++ not adding a cast would be an error. >> >> It would be an error in C as well. > > I'll call. Show why exactly this would be an error. And no, > examples of compilers that refuse to accept this don't count as > evidence.
Because the 'address of PORTD' isn't a valid pointer in standard C. An address or pointer can involve all sorts of things, such as disks, tapes, segments, whatever. If your system has provisions to accept such things and convert them to 'pointers' then that provision is peculiar to that system. It is NOT portable. -- [mail]: Chuck F (cbfalconer at maineline dot net) [page]: <http://cbfalconer.home.att.net> Try the download section.