Saving 2 Bytes, received from I2C????

Started by sleidiman June 20, 2005
Hello!

I want to use I2C for communication with a DS1721 (temperature sensor).
I finished the init-protcol, but now i have problems to save the
received two bytes.
Here is my code-example:

....
volatile signed short temp,*reg;
temp=0x0000;
reg=&IBDR;
....

IBCR=0xA0; /*BusEnable, MasterMode(Start), Rx*/
/*IBEN & Master = 1*/
if((IBSR&0x80)==0x00) /*wait transfer complete*/
{
temp+=*reg;
temp++;
}
IBCR=0xA8; /*BusEnable, MasterMode(Start), Rx, NoACK*/
/*IBEN & Master & TXAK = 1*/
if((IBSR&0x80)==0x00) /*wait transfer complete*/
{
temp+=*reg;
}
IBCR=0x90; /*BusEnable, SlaveMode(Stop), Tx*/
/*IBEN & Transmit = 1*/
}

I dont know, whether the 2-bytes stored in the variable "temp"?!?!
Or have i do something else to store the 2 bytes?!?!
When I want to convert the 2-Bytes (received in twos complement) into
decimal output, I have to convert the Hex in double and the divede by
256 [i.e.((double)temp)/256], right?!?

I hope, you can help me
Regards


I'm not familiar with I2C, but I do have a comment or
2 on the code. When you read the first byte why are
you incrementing 'temp' after the read. 'temp' is not
a pointer so you will be incrementing the value you
just read, not the location where the next byte is
going. Then when you read the second byte you are
just adding it to the first that has been incremented. So for example:

assume reg = 128 (0x80)

temp = *reg; // now temp == 128
temp++; // now temp == 129
if()
{
temp += *reg; // if reg = 64 (0x40)
// temp is now 193 (0xC1)
// is this what you want??
}

Also if you are wanting to wait for your transfers to
be complete you would not want to use an if(); The
if() statements will not wait until the transfer is
complete. If the transfer is not complete they will
just keep going. You might want to switch them to
something like:

while(IBSR & 0x80) {}

That while() loop will spin until the data transfer is
complete. Just another thought on why the code is not
working.

Again I those were just my first thoughts after
looking over the code. Hope you get it working.

Cheers

Jason M Liszewski
Embedded Systems Engineer
Syn-Tech Systems, Inc. --- sleidiman <sleidiman@slei...> wrote:

> Hello!
>
> I want to use I2C for communication with a DS1721
> (temperature sensor).
> I finished the init-protcol, but now i have problems
> to save the
> received two bytes.
> Here is my code-example:
>
> ....
> volatile signed short temp,*reg;
> temp=0x0000;
> reg=&IBDR;
> ....
>
> IBCR=0xA0; /*BusEnable,
> MasterMode(Start), Rx*/
> /*IBEN & Master = 1*/
> if((IBSR&0x80)==0x00) /*wait transfer
> complete*/
> {
> temp+=*reg;
> temp++;
> }
> IBCR=0xA8; /*BusEnable,
> MasterMode(Start), Rx, NoACK*/
> /*IBEN & Master & TXAK =
> 1*/
> if((IBSR&0x80)==0x00) /*wait transfer
> complete*/
> {
> temp+=*reg;
> }
> IBCR=0x90; /*BusEnable,
> SlaveMode(Stop), Tx*/
> /*IBEN & Transmit = 1*/
>
> }
>
> I dont know, whether the 2-bytes stored in the
> variable "temp"?!?!
> Or have i do something else to store the 2 bytes?!?!
> When I want to convert the 2-Bytes (received in
> twos complement) into
> decimal output, I have to convert the Hex in double
> and the divede by
> 256 [i.e.((double)temp)/256], right?!?
>
> I hope, you can help me
> Regards >


__________________________________________________




Hello!
> I'm not familiar with I2C, but I do have a comment or
> 2 on the code.

Thank you for your comment. Im not very experienced in programming in
C. Thats why Im very appreciative about every statement.

> // is this what you want??

No, I dont want this. :-)

> You might want to switch them to something like:
> while(IBSR & 0x80) {}

Okay, I have to increment the adress of temp and use while() loops.
Next example:

...
volatile signed short temp, *p_temp, *reg;
p_temp=&temp;
temp=0x0000;
reg=&IBDR;
...
IBCR=0xA0; /*IBEN & Master = 1*/
while((IBSR&0x80)==0x00); /*wait Transfer complete*/
temp+=*reg;
p_temp++;
while((IBSR&0x80)==0x00); /*wait Transfer complete*/
temp+=*reg;
IBCR=0xA8; /*IBEN & Master & TXAK = 1*/

Does it work in this way?

Cheers! :-)



Ok this is the way I would write this section of code. ....
volatile signed short temp=0;
....
IBCR = 0xA0;
while(!(IBSR & 0x80)) {}
temp = *IBDR;
temp <<= 8;
IBCR = 0xA0;
while(!(IBSR & 0x80)) {}
temp |= *IBDR;
IBCR = 0xA8;

Ok here's what's happening. First you only need 1
variable 'temp'. The while() loops spin while the MSB
of IBSR is '0'. I use the Image Craft C compiler and
that while loop actually comiles to 1 or 2 fewer
instructions than while((IBSR & 0x80) == 0) {}. Once
the while() fails you read IBDR into the lower byte of
temp. Then you shift the lower byte into the upper
byte of temp.

So for example IBDR = 0x33.
temp = *IBDR; // temp = 0x0033
temp <<= 8; // temp = 0x3300

You then will spin again waiting for the next byte,
then you'll read the data into the lower byte of temp,
and that should be all you need.

Cheers,

Jason M. Liszewski
Embedded Systems Engineer
Syn-Tech Systems, Inc. --- sleidiman <sleidiman@slei...> wrote:

> Hello!
> > I'm not familiar with I2C, but I do have a comment
> or
> > 2 on the code.
>
> Thank you for your comment. Im not very experienced
> in programming in
> C. Thats why Im very appreciative about every
> statement.
>
> > // is this what you want??
>
> No, I dont want this. :-)
>
> > You might want to switch them to something like:
> > while(IBSR & 0x80) {}
>
> Okay, I have to increment the adress of temp and use
> while() loops.
> Next example:
>
> ...
> volatile signed short temp, *p_temp, *reg;
> p_temp=&temp;
> temp=0x0000;
> reg=&IBDR;
> ...
> IBCR=0xA0; /*IBEN & Master =
> 1*/
> while((IBSR&0x80)==0x00); /*wait Transfer
> complete*/
> temp+=*reg;
> p_temp++;
> while((IBSR&0x80)==0x00); /*wait Transfer
> complete*/
> temp+=*reg;
> IBCR=0xA8; /*IBEN & Master &
> TXAK = 1*/
>
> Does it work in this way?
>
> Cheers! :-) >
>

____________________________________________________
Yahoo! Sports
Rekindle the Rivalries. Sign up for Fantasy Football
http://football.fantasysports.yahoo.com



I forgot to address the 2's complement part. To
convert a number to 2's complement you do the
following:

1) Bit invert the number (0->1, 1->0)
2) Add 1

So 0x34 (0011 0100)b

0xCB (1100 1011)b
+ 1 (0000 0001)b
-------
0xCC (1100 1100)b

So to convert you number from 2's complement just do
the reverse: subtract 1 then binary inversion.

0xCC (1100 1100)b
- 1 (0000 0001)b
------
0xCB (1100 1011)b
0x34 (0011 0100)b

in C you'll just need 2 lines of code (or just 1 if
you like to cram)

temp--;
temp = ~temp;

or all on 1 line

temp = ~(--temp); Again Cheers. --- sleidiman <sleidiman@slei...> wrote:

> Hello!
> > I'm not familiar with I2C, but I do have a comment
> or
> > 2 on the code.
>
> Thank you for your comment. Im not very experienced
> in programming in
> C. Thats why Im very appreciative about every
> statement.
>
> > // is this what you want??
>
> No, I dont want this. :-)
>
> > You might want to switch them to something like:
> > while(IBSR & 0x80) {}
>
> Okay, I have to increment the adress of temp and use
> while() loops.
> Next example:
>
> ...
> volatile signed short temp, *p_temp, *reg;
> p_temp=&temp;
> temp=0x0000;
> reg=&IBDR;
> ...
> IBCR=0xA0; /*IBEN & Master =
> 1*/
> while((IBSR&0x80)==0x00); /*wait Transfer
> complete*/
> temp+=*reg;
> p_temp++;
> while((IBSR&0x80)==0x00); /*wait Transfer
> complete*/
> temp+=*reg;
> IBCR=0xA8; /*IBEN & Master &
> TXAK = 1*/
>
> Does it work in this way?
>
> Cheers! :-) >
>

__________________________________



> ....
> volatile signed short temp=0;
> ....
> IBCR = 0xA0;
> while(!(IBSR & 0x80)) {}
> temp = *IBDR;
> temp <<= 8;
> IBCR = 0xA0;
> while(!(IBSR & 0x80)) {}
> temp |= *IBDR;
> IBCR = 0xA8;

Waow, it looks very simple. Thank you very, very much.

> I use the Image Craft C compiler and
> that while loop actually comiles to 1 or 2 fewer
> instructions than while((IBSR & 0x80) == 0) {}.

Oh, it is good to know, that i can save dispensable instructions. I
think, in my program there are many possibilities to save needless
commands. My code is presumably to complicated. However I hope by and
by I can improve my program.
By the way, I use the ICC12, too.

> Then you shift the lower byte into the upper byte of temp.

The bit-shifting-idea is great. Thank you once again!!!!
Best regards

sleidiman