View previous topic :: View next topic |
Author |
Message |
gordon111
Joined: 05 Jul 2007 Posts: 18
|
DS1775 |
Posted: Mon Jul 09, 2007 12:20 pm |
|
|
Hey,
I am trying to save the temprature values by using the i2c bus. I need help, because i am reading the wrong values, will it be wise to re-write the i2c_write and read functions for better functionality or is this not the problem?
Code: |
unsigned int16 read_ext_temp()
{
unsigned char High_byte;
unsigned char Low_byte;
i2c_start();
i2c_tx(0x90); // SRF08 I2C address with R/W bit clear
i2c_tx(0x01); // SRF08 light sensor register address
i2c_start(); // send a restart sequence
i2c_tx(0x91); // SRF08 I2C address with R/W bit set
High_byte = i2c_rx(1); // get the high byte of the range and send acknowledge.
Low_byte = i2c_rx(0); // get low byte of the range - note we don't acknowledge the last byte.
i2c_stop(); // send stop sequence
return (High_byte << 8) | Low_byte;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 09, 2007 12:26 pm |
|
|
You're not using the CCS i2c functions. They're from some other
compiler, or some page on the net, like this one:
http://www.keil.com/forum/docs/thread8186.asp?bhcp=1
If you have the CCS compiler, then use the CCS functions.
Look at sample i2c driver files for examples of how to do this:
Quote: | c:\Program Files\Picc\Drivers |
|
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Mon Jul 09, 2007 1:23 pm |
|
|
Hey,
I understand, but if i use CCS commands i get the wrong values
Code: |
unsigned int16 read_ext_temp()
{
unsigned char High_byte;
unsigned char Low_byte;
i2c_start();
//delay_ms(1);
i2c_write(0x91);
//delay_ms(1);
High_byte = i2c_read(1);
//delay_ms(1);
Low_byte = i2c_read(0);
//delay_ms(1);
i2c_stop();
//delay_ms(1);
return (High_byte << 8) | Low_byte;
}
Will it help if i re-write the routines?
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 09, 2007 1:43 pm |
|
|
Follow the protocol in the ds1775 data sheet. It shows how to read
the temperature. Look at the diagrams on page 11. Look at the
one titled:
Quote: | Read Single Byte from New Pointer Address Register |
You need to do it exactly that way. Notice how they do a re-start.
Also, the ds1775 comes in eight different versions. Each one has
a different i2c slave address. Are you sure of which version you have ?
Make sure you have the pull-up resistors on the SDA and SCL lines. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Mon Jul 09, 2007 1:55 pm |
|
|
Thanks for all the help,
If i may ask, can you maybe tell me way must i not use the read multiple bytes from current pointer location, because that is what i am currently doing |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Mon Jul 09, 2007 2:18 pm |
|
|
So the code will look much like this --->
Code: |
unsigned int16 read_ext_temp()
{
unsigned int16 temp;
i2c_start();
i2c_write(0x90); // write the control byte
i2c_write(0x00); // write the pointer byte
delay_ms(5);
i2c_start(); //repeated start
i2c_write(0x91); //nou read ek
temp = i2c_read(0);
i2c_stop();
delay_ms(5);
return temp;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 09, 2007 2:33 pm |
|
|
The data sheet says the result is 9-bits (by default). That means you
have to read two bytes.
Quote: |
The DS1775 power–up default has the sensor automatically performing
9–bit conversions continuously. |
Also, I don't see anything in the data sheet that says to do 5 ms delays
in the middle of the i2c code. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Tue Jul 10, 2007 10:01 am |
|
|
Hey
I cannot use the single byte read becaues i have to read two bytes, so i will have to use multiple read?
So my first code was correct, but i still get the wrong values.
0x80...
When i read single byte a get values that vary. But only the MSB not the LSB any ideas how i can make that work?
Code: |
#include <16F883.h>
#case
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c (MASTER, sda = 60 , scl= 59 )
#fuses HS,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT,NOWRT
void write_config_reg() //die resolusie van die tempratuur sensor word gestel.
{
i2c_start();
i2c_write(0x90);
i2c_write(0x01);
i2c_write(0x03);
i2c_stop();
delay_ms(5);
}
unsigned char read_config() // lees die register
{
unsigned char config_value;
i2c_start();
i2c_write(0x90);
i2c_write(0x01);
i2c_start();
i2c_write(0x91);
config_value = i2c_read(0);
i2c_stop();
delay_ms(5);
return config_value;
}
unsigned int16 read_ext_temp()
{
unsigned char temp_sensor_low;
unsigned char temp_sensor_high;
unsigned int16 temp_value = 0;
i2c_start();
i2c_write(0x90); //nou read ek
i2c_write(0x00);
i2c_start();
temp_sensor_high = i2c_read(0); //1
//temp_sensor_low = i2c_read(0);
i2c_stop();
delay_ms(5);
//temp_value = (temp_sensor_high << 8) | temp_sensor_low ;
return temp_sensor_high;
}
void main()
{
while(1)
{
unsigned int16 temp = 0;
unsigned int16 config_value = 0;
write_config_reg();
config_value = read_config();
printf("\r\n\----->Configuration value =0x%4X", config_value);
temp = read_ext_temp();
printf("\r\n\-----> Tempratuur_waarde = 0x%4X", temp );
delay_ms(500);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 10, 2007 2:21 pm |
|
|
Quote: |
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
|
If you specify "fast i/o" mode, you must set the TRIS for each port
that you specify. You're not doing this. That's probably the major
reason why your program doesn't work.
Here's a tip:
You don't need to use fast_io mode. The CCS compiler is designed to
to set the correct TRIS automatically. To do this, you must use the
built-in CCS pin i/o functions such as output_low(), output_high(),
input_x(), etc. This is the default mode of the compiler and you don't
have to specify anything with a #use statement to enable it. CCS
designed in this feature to make programming PICs easier to do.
Delete those three lines.
Quote: | #use i2c (MASTER, sda = 60 , scl= 59 ) |
Here you're using magic numbers for the pins. Never do this. Always
use the symbolic names for the pins. Using magic numbers makes the
program hard to understand ("what pins are those ?"), hard to maintain,
and it makes the program be non-portable to the 18F-series PICs.
Put in the symbolic constants. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Wed Jul 11, 2007 7:41 am |
|
|
Hey - thanks again for the reply,
i did setup the tris registers, i just didn't post it in the code. And the magical numbered pins - pure desperation, it is PIN_C4 and PIN_C3.
Still the only value recieved - 0x0080!
It bombs out the minute i read 2 bytes!
Code: |
unsigned int16 read_ext_temp(void)
{
unsigned int16 temp;
i2c_start();
i2c_write(0x91);
temp = i2c_read(1);
temp = (temp << 8) | i2c_read(0);
i2c_stop();
return temp;
}
|
If i read multiple bytes. On page 11 |
|
|
inservi
Joined: 13 May 2007 Posts: 128
|
|
Posted: Wed Jul 11, 2007 8:13 am |
|
|
Hello,
I just found a code with reading two bytes from a DS1629 Code: | i2c_start();
i2c_write(DS1621_I2C_WRITE_ADDRESS);
i2c_write(DS1621_CMD_READ_TEMP);
i2c_start();
i2c_write(DS1621_I2C_READ_ADDRESS);
temp_read = i2c_read(); // Read MSB
temp_read <<= 8;
temp_read |= i2c_read(0); // Read LSB
i2c_stop(); |
The DS1775 is maybe compatible with the DS1629 ?
All code is at http://www.ccsinfo.com/forum/viewtopic.php?t=23359
dro. _________________ in médio virtus |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 11, 2007 11:26 am |
|
|
Quote: | printf("\r\n\----->Configuration value =0x%4X", config_value);
temp = read_ext_temp();
printf("\r\n\-----> Tempratuur_waarde = 0x%4X", temp );
|
To display a 16-bit or 32-bit number with printf in CCS, you must
use "%LX". This is in the manual. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Thu Jul 12, 2007 2:14 am |
|
|
I know that, and then still the same values was returned so i used 4x, but i am trying something new.
Hope it works. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Thu Jul 12, 2007 3:11 am |
|
|
Hey,
Can anybody maybe help me understand what this part of the ds1631 driver does?
Please? I am trying to convert the driver for the ds1775, it seems to respond to this code, but its not that accurate?
Code: |
signed long read_full_temp() { // Returns hundreths of degrees F (-67 to 257)
signed int datah, datal;
signed long data;
i2c_start();
i2c_write(0x90); =============> this i understand totally
i2c_write(0xaa);
i2c_start();
i2c_write(0x91);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();
data=(signed long)datah*100; ===>
data=data+(((datal >> 4 )*(long)50)/16); ===> this is a little bit grey
data=data*9; ===>
data = (data / 5) + 3200; ===>
return(data);
}
|
thanks for all the help its appreciated |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 12, 2007 12:22 pm |
|
|
Read the DS1775 data sheet, and read the DS1629 data sheet.
The DS1629 uses a "command" byte after the i2c address.
The DS1775 uses a "Pointer" byte after the i2c adress.
They're not the same.
You can't make a driver by guessing, or by "cut and try".
You have to read and you have to think. |
|
|
|