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

I2C PIC to ADS1112 Beginner Issues

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



Joined: 21 Apr 2010
Posts: 3
Location: Stevenage Herts UK

View user's profile Send private message

I2C PIC to ADS1112 Beginner Issues
PostPosted: Wed Apr 21, 2010 3:44 pm     Reply with quote

Hi,

I have been playing with the PIC and I2C to an ADS1112 and can not seem to make it work. Can anybody review my code and provide any pointers as it is my first attempt at I2C programming.
Code:

#ifndef ADS1112_SDA
#define ADS1112_SDA  PIN_C4
#define ADS1112_SCL  PIN_C3
#endif

#use i2c(master, sda=ADS1112_SDA, scl=ADS1112_SCL)

#define ADS1112_ID_W    0b10010000           // write address + 8 bit 0 = write
#define ADS1112_ID_R    0b10010001           // read address + 8 bit 1 = read
#define ADS1112_Config  0b00001100           // Configuration

// Configuration bits
//bit 7 = st/!DRDY; 1 = conversion, 0 = no effect
//bit 6-5 = analogue input 00 = Ain0 and Ain1, 01 => Ain2 and Ain3
//bit 4 = SC  Single conversion mode = 1, continuous conversion = 0
//bit 3-2 = DR data rate 15sps = 11 for 16 bits
//bit 1-0 = PGA gain control 00 = gain 1

int8 count;
int16 ADC_Data;
int16 CNT_1;
byte buffer[4];

/////////////////////////////////////////////////////////////////////////
// I2C Initialise
void ADS1112_INT(){

i2c_start();
i2c_write(0b00000000);  // general call and respond to second byte
i2c_write(0b00000110);  // latch status of address pins and reset internal registers
i2c_stop();
printf ("\r\nInitialised I2C");
} // end subroutine

/////////////////////////////////////////////////////////////////////////
// I2C Write
void ADS1112_Send(){

i2c_start();            // Start condition

i2c_write(ADS1112_ID_W);    // Device address

i2c_write(ADS1112_Config);  // Low byte of command set up continous mode

                        // i2c_write(0x8c>>8);// High byte of command  / not used

i2c_stop();             // Stop condition
printf ("\r\nwritten config to ads1112");
} // end of write


//////////////////////////////////////////////////////////////////////////
// I2C READ
void ADS1112_Read(){

i2c_start();            // Start condition
i2c_write(ADS1112_ID_R);     // Device address/Read

 buffer[0] = i2c_read(1); // read 1
 buffer[1] = i2c_read(1); // read 2
 buffer[2] = i2c_read(1); // read 3
 buffer[3] = i2c_read(1); // read 3
 
 i2c_stop();             // Stop condition

   // ADC_DATA = Buffer[0] + Buffer[1]>>8;
    CNT_1++;
    if (CNT_1 >= 999) CNT_1 = 0;
   
}

void main()
{
   CNT_1 = 0;
   buffer[0]=0x00;
   buffer[1]=0x00;
   buffer[2]=0x00;
   buffer[3]=0x00;
 
  ADS1112_INT();
   delay_ms(500);
   ADS1112_Send();
   printf ("\r\nPower Up");
   delay_ms(500);

do    {

         ADS1112_Read();
         printf ("\r\nValue_1 = %x", buffer[0]);
         printf ("\r\nValue_2 = %x", buffer[1]);
         printf ("\r\nValue_3 = %x", buffer[2]);
         printf ("\r\nValue_4 = %x", buffer[3]);
         
         
         printf ("\r\nCounter = %Lu", CNT_1);
         delay_ms (5000);

      } while(true);
}

Your help would be great.
Cheers
MAC
Confused
_________________
Every day above ground is a great day!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 21, 2010 11:42 pm     Reply with quote

Your read routine doesn't look correct. The data sheet shows the read
operation in Figure 2 on page 12:
http://focus.ti.com/lit/ds/symlink/ads1112.pdf
It shows only 3 bytes that may be read from the ADS1112. The last one
of those 3 is optional. So only 2 bytes really need to be read. See my
proposed routine below. It reads the two bytes, combines them into a
16-bit word, and then returns the word. It does not return the A/D result
in global variables. The proper way to return a result from a function
is with a 'return' statement.

Also, this being a Burr-Brown data sheet for i2c, it doesn't show a NACK
on the last i2c read. But, doing a NACK on the last read is the standard
for i2c operations, as described in the i2c spec.

The ADS1112 data sheet says this, regarding the first byte which was read:
Quote:

Similarly, when a master has finished reading a byte,
it pulls SDA LOW to acknowledge this to the slave.

They're referring to doing an ACK on the first i2c_read() operation.
Fair enough.

Then they say this (bottom right on page 8):
Quote:

A not-acknowledge is performed by simply leaving SDA
HIGH during an acknowledge cycle.

However, the context is not clear. Are they referring to the slave
(ADS1112) or the master (the PIC) ?

However, I think you should at least initially, try it with a NACK on the
last i2c read. That's done as indicated below, with a 0x00 parameter
for the i2c_read() function.
Code:

int16 ADS1112_Read(void)
{
int8 lsb, msb;
int16 retval;

i2c_start();
i2c_write(ADS1112_ID_R);

msb  = i2c_read();
lsb = i2c_read(0);   // Do a NACK on the last read
i2c_stop();   

retval = make16(msb, lsb);

return(retval);
}


Then you would call the read routine in a loop in main() and display
the ADC value that was read. In the code below, 'result' must be
declared as an 'int16' at the start of main(). And of course you
need to call your config routine before entering this loop.
Code:

while(1)
  {
   result = ADS1112_Read();
   printf("%lu \n\r", result);
   delay_ms(500);
  }
MAC



Joined: 21 Apr 2010
Posts: 3
Location: Stevenage Herts UK

View user's profile Send private message

I2C PIC to Device Beginner Issues
PostPosted: Thu Apr 22, 2010 2:31 am     Reply with quote

Thank you for the response,
I will try out the this method and get back tonight.
MAC
_________________
Every day above ground is a great day!
MAC



Joined: 21 Apr 2010
Posts: 3
Location: Stevenage Herts UK

View user's profile Send private message

i2c pic16f876 to ads1112
PostPosted: Thu Apr 22, 2010 12:32 pm     Reply with quote

Hi PCM programmer

Thank you for your pointers, it certainly helps.

The device is continuously sending FFFF so maybe the device has blown. Need to get a new device.

Cheers
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Apr 22, 2010 12:51 pm     Reply with quote

Run this program and see if finds the ADS1112 chip. This program will
report any i2c chips that are on the bus, if they're alive (within the slave
address range of 0x10 to 0xEF). If it doesn't find it make sure that pins
A0 and A1 are connected to ground on the ADS1112.

Also, make sure you have pull-up resistors on the SDA and SCL lines.
You can use 4.7K ohm resistors.
Code:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK".   This function returns TRUE if an
// ACK was found.  Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;

i2c_start();
status = i2c_write(address);  // Status = 0 if got an ACK
i2c_stop();

if(status == 0)
   return(TRUE);
else
   return(FALSE);
}


//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;

printf("Start:\n\r");

delay_ms(1000);

// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
   {
    status = get_ack_status(i);
    if(status == TRUE)
      { 
       printf("ACK addr: %X", i);
       count++;
       delay_ms(2000);
      }
   }

if(count == 0)
   printf("\n\rNothing Found");
else
   printf("\n\rFound %u chips", count);

while(1);
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