Page 2 of 2
Re: [NXC] Adressing I2C-Device
Posted: 16 Feb 2013, 09:47
by rk-at-kkos
sure.
This is the message array for the I2C-device. First element ist the 8 bit device address.
So I don't have to build the message array every time, I only set the following element(s) containing the actual message (initially 0).
In my case it is just one control byte:
Code: Select all
Max127msg[1] = 0x80 | (channel << 4);
which consists of a leading 1, 3 bits adressing the channel (of 8) to convert and 4 Bits encoding measuring range (here: 00 encoding 0..5V) and power modes (here: 00 for power on).
The channel bits are shifted into place (<<4), so that I can number the channels from 0..7 rather than having to compute the right numbers every time because of them sticking somewhere in the middle of the byte.
The operator "|" is a bitwise "OR" to put control and channel byte together. I prefer or-ing to adding when bit-juggling because it's easier for the students to see what's being done.
HTH
Re: [NXC] Adressing I2C-Device
Posted: 16 Feb 2013, 10:02
by HaWe
thank you for your reply!
Now it's a little more clear to me -
but still 3 questions are left:
1) in your Arduino code you use 0x28, now you use 0x50 - why is this so?
2) what do you mean by "channel bits are shifted into place (<<4)" ? What is the complete bit-or byte-structure like?
edit:
3) what is your adc reading format so that you must shiift it to <<4 and "or it" by >>4 ? (which >> and << does what ?)
(those kinds of bit manipulating stuffs are really not my world!)
Re: [NXC] Adressing I2C-Device
Posted: 16 Feb 2013, 13:35
by rk-at-kkos
1. Address
For reasons that I have not looked up yet, the Wire library for Arduino uses the upper 7 bit of the 8 bit device address. So that makes 0x50 = 0101 0000 shifted right once to 0010 1000 = 0x28.
2. Control byte format
The control byte has of 8 bits which are: start bit, 3 channel bits and 4 control bits. Start bit and control bits are the same for every operation:
1 ? ? ? 0 0 0 0
The ??? are the channel bits. Assuming them to be zero, this yields 0x80.
Now if I wanted, say, channel 5 to be read, I would have to send 0xD0. How do I see that "D" means channel 5?
The decimal (channel) number 5 in binary is 0000 0101. Doing 4 left-shifts results in 0101 0000 = 0x50 (= 80 decimal) with the channel bits in the right place.
The only thing left is to add the rest of the control byte: 0x80 | 0x50 = 0xD0. Since OR-ing means just adding without carries, the result is the same for there are no carries here.
So I can pass the channel number indepentently from it's position within the control byte and don't have to remember that "0x90" means channel 1.
3. Result value
The device is a 12-bit-ADC, so the result effectively has 12 bits. These 12 bits come in 2 bytes, the first containing 8, the second 4 bits of the result.
The first byte (say: a) is put into an integer (16 bits):
0000 0000 aaaa aaaa
and shifted left 4 times. This operation puts byte a in the middle of the integer:
0000 aaaa aaaa 0000.
Now the second byte (b) to be read contains 4 bits from the conversion followed by 4 trailing zeros. Shifting them right 4 times eliminates these zeros:
0000 0000 0000 bbbb.
The OR-ing just puts them together into one integer:
0000 aaaa aaaa bbbb,
which is the result of the conversion operation.
None of this would have been necessary with an 8 bit converter, for the result would have fit in 1 byte.
HTH
Ralf
[Edit] So this is all about bit manipulating stuff.
Re: [NXC] Adressing I2C-Device
Posted: 16 Feb 2013, 17:38
by HaWe
now having read this a few times very closely I think that I now finally understood it.
A very good explanation, again thanks a lot!
Helmut
ps: also your shortened maxim127 i2c code is very handy and now easily understandable!
https://sourceforge.net/apps/phpbb/mind ... ea3#p15834