|
|
View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
TC74 problem |
Posted: Mon Apr 19, 2004 3:06 pm |
|
|
Hello!
I use a TC74A0 i2c temparature IC from Microchip. My problem is that reading temparature gives me different results altough the remparature should be relatively constant between two readings (2 seconds). This is my code so far:
Code: |
#ifndef I2C_SDA
#define I2C_SDA PIN_C4
#define I2C_SCL PIN_C3
#endif
#use i2c(master, slow, sda=I2C_SDA, scl=I2C_SCL)
#include "..\mytypes.h"
// TC74 COMMANDS
#define TC74_CMD_R_TEMP 0x00 //read temp
#define TC74_CMD_RW_CFG 0x01 //read/write config
// TC74 CONFIG REGISTER BITS
#define TC74_CFG_SET_STANDBY 0x80 //read/write 1=standby, 0=normal
#define TC74_CFG_DTAREADY 0x40 //read only 1=ready, 0=not ready
#define TC74_I2C_ADDRESS 0x00
#define TC74_I2C_BASEADDR 0x9E
#define TC74_I2C_MINADDR 0x90 //smallest i2c address for tc74
#define TC74_I2C_MAXADDR 0x9E //largest i2c address for tc74
// 3.3V 5V
// ADDR ADDR Part Nbr Device Device
// (binary) (hex) Marking Marking
// --------- -- ------ ---- ----
// 1001 0000 90 TC74A0 V0xx U0xx
// 1001 0010 92 TC74A1 V1xx U1xx
// 1001 0100 94 TC74A2 V2xx U2xx
// 1001 0110 96 TC74A3 V3xx U3xx
// 1001 1000 98 TC74A4 V4xx U4xx
// 1001 1010 9A TC74A5 V5xx U5xx
// 1001 1100 9C TC74A6 V6xx U6xx
// 1001 1110 9E TC74A7 V7xx U7xx
void tc74_i2cWrite(byte addr, byte cmd, byte value);
byte tc74_i2cRead(byte addr, byte cmd);
void tc74_i2cSearch();
void tc74_setStandby(byte addr, bool onoff);
void tc74_init();
byte tc74_getTemp(byte addr);
float tc74_rawTemp2Float(byte w);
void tc74_printTemp(byte addr);
void tc74_i2cWrite(byte addr, byte cmd, byte value) {
i2c_start(); //Start condition
i2c_write(addr | I2C_DOWRITE); //write
i2c_write(cmd); //Low byte of command
i2c_write(value); //high byte
i2c_stop(); //Stop condition
}
byte tc74_i2cRead(byte addr, byte cmd) {
byte res=0x00;
i2c_start();
i2c_write(addr | I2C_DOWRITE); //write
i2c_write(cmd); //Low byte of command
i2c_start();
i2c_write(addr | I2C_DOREAD); //read
res = i2c_read(0); //0 indicates do not ack.
i2c_stop();
return res;
}
void tc74_i2cSearch() {
byte b1,b2;
printf("\n\rI2C device-search:");
for(b1=TC74_I2C_MINADDR; b1<=TC74_I2C_MAXADDR; b1+=2) {
i2c_start(); // Start condition
b2 = i2c_write(b1); // Device address
i2c_stop(); // Stop condition
if (!b2)
printf("\n\rfound dev. addr.: 0x%X", b1);
}
}
void tc74_setStandby(byte addr, bool onoff) {
if (onoff)
tc74_i2cWrite(addr, TC74_CMD_RW_CFG, TC74_CFG_SET_STANDBY);
else
tc74_i2cWrite(addr, TC74_CMD_RW_CFG, 0);
// printf("\n\rset tc74 standby to %d: %x", onoff, tc74_i2cRead(addr, TC74_CMD_RW_CFG));
}
void tc74_init() {
byte b1,b2;
for(b1=TC74_I2C_MINADDR; b1<=TC74_I2C_MAXADDR; b1+=2) {
i2c_start(); // Start condition
b2 = i2c_write(b1); // Device address
i2c_stop(); // Stop condition
if (!b2) {
printf("\n\rfound TC74 dev. @ addr.: 0x%X", b1);
tc74_setStandby(b1, false);
}
}
}
byte tc74_getTemp(byte addr) {
byte b;
// tc74_setStandby(0x90, false);
do {
delay_ms(1);
b = tc74_i2cRead(addr, TC74_CMD_RW_CFG);
} while (!(b & TC74_CFG_DTAREADY));
delay_ms(1);
b = tc74_i2cRead(addr, TC74_CMD_R_TEMP);
// tc74_setStandby(0x90, true);
return b;
}
float tc74_rawTemp2Float(byte w) { //convert the RAW temp (2's compl.) value to float �C
byte tmp, temp_lsb,temp_msb;
float ftemp = +1;
if (w >= 80) { //negative
w = (~w)+1; //2s complement
ftemp = -1;
}
ftemp *= w; // + (temp_lsb & 0x0F) * 0.0625;
return ftemp;
}
//(TC74_I2C_BASEADDR | (TC74_I2C_ADDRESS & 0x03))
void tc74_printTemp(byte addr) {
byte b;
b = tc74_getTemp(addr);
printf("\n\ri2cRawTemp=0x%x", b);
printf("\n\rrawTemp2float=%3.0f", tc74_rawTemp2Float(b));
}
|
The output (after 1x'i' and 5x't') is:
======================
* TC74 0.30 *
i - init
t - printTemp
1 - standbyMode
2 - normalMode
>
found TC74 dev. @ addr.: 0x90
>
i2cRawTemp=0x25
rawTemp2float=36
>
i2cRawTemp=0x25
rawTemp2float=36
>
i2cRawTemp=0x1c
rawTemp2float=27
>
i2cRawTemp=0x20
rawTemp2float=31
>
i2cRawTemp=0x24
rawTemp2float=35
>
I don't know where the problem is. Hardware should be OK (the IC is recognized on the i2c bus).
Who can help me? |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Mon Apr 19, 2004 3:35 pm |
|
|
This worked for me
Code: | /**********************************************************/
/* Read Temp on a TC74 */
/**********************************************************/
void Read_Temperature(void)
{ int16 Temperature;
if(Get_Temp)
{ Get_Temp=0;
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011010); // Address and Write Flag
i2c_Write(0x00); // Temperature Register
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011011); // Address and Read Flag
Temperature = i2c_Read(); // Read Teperature
i2c_stop();
if(Temperature<128)
{ Temperature+=273; // Make it a kelvin reading
}
else
{ Temperature+=273+0xFF00; // Make it a kelvin reading
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 19, 2004 3:59 pm |
|
|
I would try a more simple test program. Here is one that I made
for the TCN75, which is a similar chip. It displays this output:
Start
Reading Temperature
Temp = 26
Temp = 28
Temp = 28
Temp = 27
Temp = 27
Temp = 28
Temp = 27
Temp = 26
Temp = 26
Temp = 27
Temp = 27
Temp = 27
Temp = 27
Temp = 27
It's not perfect, but it doesn't jump around as much as your
output does. (I have a heater running near the board. That's
why it's so warm).
Code: | #include <18F458.H>
#fuses XT, NOPROTECT, PUT, NOBROWNOUT, NOWDT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors)
#define TCN75_SDA PIN_C0
#define TCN75_SCL PIN_C1
#use i2c(Master, SDA=TCN75_SDA, SCL=TCN75_SCL) // Software i2c
//------------------------------------------------------------------------
// DEFINES
// TCN75 i2c addresses
#define TCN75_I2C_WRITE_ADDR 0x90
#define TCN75_I2C_READ_ADDR 0x91
// TCN75 register addresses
#define TCN75_TEMP_REG_ADDR 0
#define TCN75_CONFIG_REG_ADDR 1
#define TCN75_THYST_REG_ADDR 2
#define TCN75_TSET_REG_ADDR 3
#define TCN75_CONFIG_VALUE 0x1A // From Microchip TB052 appnote
//---------------------------------------------------------------------------
// FUNCTION PROTOTYPES
void TCN75_init(void);
char TCN75_read_temperature(void);
//=========================================
void main()
{
char result;
printf("Start\n\r");
TCN75_init();
printf("Reading Temperature\n\r");
while(1)
{
result = TCN75_read_temperature();
printf("Temp = %d \n\r", result);
delay_ms(1000);
}
}
//=======================================
void TCN75_init(void)
{
output_float(TCN75_SDA);
output_float(TCN75_SCL);
i2c_start();
i2c_write(TCN75_I2C_WRITE_ADDR);
i2c_write(TCN75_CONFIG_REG_ADDR);
i2c_write(TCN75_CONFIG_VALUE);
i2c_stop();
}
//-----------------------------------------
// Read the temperature and return the integer
// portion as a char. The "1/2 degree" portion
// of the result is discarded and not returned.
// We don't need that level of precision.
char TCN75_read_temperature(void)
{
char msb;
char lsb;
i2c_start();
i2c_write(TCN75_I2C_WRITE_ADDR);
i2c_write(TCN75_TEMP_REG_ADDR);
i2c_start();
i2c_write(TCN75_I2C_READ_ADDR);
msb = i2c_read();
lsb = i2c_read(0);
i2c_stop();
return(msb);
}
// end of program |
|
|
|
Guest Guest
|
reply |
Posted: Mon Apr 19, 2004 5:45 pm |
|
|
thanks for your code. but the temp still jumps. Also if i use different chips. (also different address class)
what i2c pullups do you use? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 19, 2004 5:53 pm |
|
|
Quote: | what i2c pullups do you use? |
I'm using 3.3K pullups, going to +3.3v.
(Vdd = +3.3v on this board). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|