|
|
View previous topic :: View next topic |
Author |
Message |
soko
Joined: 05 Jun 2011 Posts: 9
|
Problem reading data TC74-I2C |
Posted: Mon Jul 18, 2011 1:34 am |
|
|
Hello,
First apologize for my English because I am not native.
I'm trying to read the temperature of a TC74, based on the examples on this website, but I can not get it.
I use Proteus for the simulation, the direction of TC74 is A5 (default) and use a 16F88. Also use pull-up resistors.
Thank you very much.
Code: |
#include <16f88.h> //pic a utilizar
#fuses NOWDT // SIN WATCH DOG TIMER
#fuses INTRC_IO // OSCILADOR INTERNO SIN CLKOUT
#fuses NOCPD // NO EE PROTECTION
#fuses NOPROTECT // NO SE PUEDE LEER EL CODIGO DEL PIC
#fuses NOMCLR // PIN_A3 USADA PARA ENTRADA Y NO PARA RESET
#fuses NOPUT // SIN POWER UP TIMER
#fuses NOBROWNOUT // SIN BROWNOUT RESET
#fuses NOFCMEN
#fuses NOIESO
#use delay (clock=8000000) //Fosc=8Mhz
#include <LCD_PORT_A_sin_W.c> //libreria manejo lcd
#use i2c(master,sda=PIN_B1, scl=PIN_B4,FORCE_HW,slow)
void main() {
lcd_init(); // Inicializamos el LCD.
while (1) {
long ret;
/*i2c_start();
i2c_write(0x93);
i2c_write(0x00);
i2c_start();
i2c_write(0x94);
ret = i2c_read(0);
i2c_stop();*/
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011010); // Address and Write Flag
i2c_Write(0x00); // Temperature Register
i2c_stop();
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011011); // Address and Read Flag
ret = i2c_Read(0); // Read Teperature
i2c_stop();
//----------------------------------------------------------
lcd_gotoxy(1,1);
printf(lcd_putc,"Temp=>%06lu ",ret);
delay_ms(100); //Actualizamos cada 50 milisegundos.
}
} |
Attach files for simulation and code.
http://www.megaupload.com/?d=TRGGTFEQ |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Jul 18, 2011 2:26 am |
|
|
Something is wrong with your device address.
A _write_ command always has the least significant bit as '0', so the write address of a device is always even. The read address will then be odd.
A5, corresponds to a write address of 0x9A, and a read address 0f 0x9B.
0b10011010 //for write
0b10011011 //for read
Best Wishes |
|
|
soko
Joined: 05 Jun 2011 Posts: 9
|
|
Posted: Mon Jul 18, 2011 3:56 am |
|
|
Thanks for the reply Ttelmah.
In the datasheet, (http://ww1.microchip.com/downloads/en/devicedoc/21462c.pdf) these data are:
SOT-23 (V)---------------Address
3.3VCT TC74A5---------1001 101 *
If I use like your comment the address to write 0x9A, 0x9B and address to read, the code still does not work. I always read zero.
Thank you.
Code: | #include <16F88.h>
#FUSES NOWDT,INTRC_IO,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,IESO,FCMEN,NOLVP,NODEBUG,NOWRT
#use delay(clock=8000000) // AJUSTE CLOCK INTERNO
#include <LCD_PORT_A_sin_W.c> //libreria manejo lcd
#use i2c(master,sda=PIN_B1, scl=PIN_B4,FORCE_HW,slow)
void main() {
setup_oscillator(OSC_8MHZ|OSC_INTRC); // ACTIVAMOS OSCILADOR INTERNO
lcd_init();
while (1) {
int ret;
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0x9A); // Address and Write Flag 9A
i2c_Write(0x00); // Temperature Register
i2c_stop();
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0x9B); // Address and Read Flag 9B
ret = i2c_Read(0); // Read Teperature
i2c_stop();
//----------------------------------------------------------
lcd_gotoxy(1,1);
printf(lcd_putc,"T=>%03d",ret);
delay_ms(20); //Actualizamos cada 50 milisegundos.
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Jul 18, 2011 4:16 am |
|
|
Your data sheet values, agree with what I have said.
There is one remaining fault.
A read transaction, involves:
1) Send start
2) Send address, with read bit clear
3) Write register number
4) Send start
5) Send address with the read bit set
6) Read data
7) Stop
Key point is that you don't _stop_ after sending the register number. You perform a 'restart'. On many chips, if you send a 'stop' the register number drops back to a default initial condition, so you must 'restart', rather than 'stop/start'.
This may be the remaining problem.
However one other thing worries me. Your code is for a 16F88. This is specified for 4v minimum operation. For 3.3v operation you need the 16LF88. However the part number you are giving for the sensor, is a 3.3v part. Now the 3.3v part will operate OK to 5v, but with degraded accuracy. If you are running the part off 3.3v, the output will not go high enough to be seen as a '1' by the I2C input.
Best Wishes |
|
|
soko
Joined: 05 Jun 2011 Posts: 9
|
|
Posted: Mon Jul 18, 2011 4:47 am |
|
|
Thank you very much for your time.
I have corrected the problem of sending the stop and reset the data.
The device I use is to TC74 but 5 volts, not 3.3, it tells you forgive me wrong, the datasheet is common and just wanted to confirm you the address of the device.
the problem persists, then I always get the value 000, however, if I put the wrong address, I get the value -01, this indicates that the problem is not the direction.
Do not understand how simple code can fail so much.
Thank you.
Code: | #include <16F88.h>
#FUSES NOWDT,INTRC_IO,PUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,IESO,FCMEN,NOLVP,NODEBUG,NOWRT
#use delay(clock=8000000) // AJUSTE CLOCK INTERNO
#include <LCD_PORT_A_sin_W.c> //libreria manejo lcd
#use i2c(master,sda=PIN_B1, scl=PIN_B4,FORCE_HW,slow)
void main() {
setup_oscillator(OSC_8MHZ|OSC_INTRC); // ACTIVAMOS OSCILADOR INTERNO
lcd_init();
while (1) {
int ret;
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011010); // Address and Write Flag 9A
i2c_Write(0x00); // Temperature Register
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011011); // Address and Read Flag 9B
ret = i2c_Read(0); // Read Teperature
i2c_stop();
//----------------------------------------------------------
lcd_gotoxy(1,1);
printf(lcd_putc,"T=>%03d",ret);
delay_ms(20); //Actualizamos cada 50 milisegundos.
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 18, 2011 12:39 pm |
|
|
Quote: | #include <16F88.h>
#use i2c(master,sda=PIN_B1, scl=PIN_B4,FORCE_HW,slow) |
16F88 only has an SSP module. It can only do a hardware i2c slave,
not a master. To do an i2c master in hardware, the PIC must have
an MSSP module. But the 16F88 does not. Remove the FORCE_HW
parameter and re-compile. It will probably now work.
Are you running the 16F88 at +5v and the TC74 at +3.3v ? If so, you
can use 3.3K pull-up resistors on SDA and SCL, and connect them to
+3.3v. Because you are using a software i2c master on Port B, the i/o
pins (B1 and B4) use 5v TTL logic levels. 3.3v pull-ups will work just fine
with those pins.
It would be nice if CCS would issue a warning message (or an error) if
you try to use the SSP module with FORCE_HW, but they don't. |
|
|
soko
Joined: 05 Jun 2011 Posts: 9
|
|
Posted: Mon Jul 18, 2011 3:48 pm |
|
|
I can not believe. After two days crazy, says the solution is as PCM programmer, I have taken instruction FORCE_HW and work perfectly.
Many thanks to both, you have helped me a lot.
Regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Jul 19, 2011 2:18 am |
|
|
Yes, once the address was right, the code should have worked. Didn't look at the chip, and make the 'leap', to realising this didn't have the MSSP. I remember (now), threads about this in the past. What happens, is that CCS, doesn't realise this isn't an MSSP, but actually an SSP, and with force hardware selected, just writes to, and reads from the registers it expects to be there, and doesn't work.....
Glad it is working now.
Best Wishes |
|
|
|
|
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
|