CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem reading data TC74-I2C

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
soko



Joined: 05 Jun 2011
Posts: 9

View user's profile Send private message

Problem reading data TC74-I2C
PostPosted: Mon Jul 18, 2011 1:34 am     Reply with quote

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: 19538

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 2:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 3:56 am     Reply with quote

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: 19538

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 4:16 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 4:47 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 12:39 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 18, 2011 3:48 pm     Reply with quote

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: 19538

View user's profile Send private message

PostPosted: Tue Jul 19, 2011 2:18 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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