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

10-bit I2C Communication

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Seaborgium



Joined: 23 Jul 2012
Posts: 14

View user's profile Send private message

10-bit I2C Communication
PostPosted: Thu Jul 26, 2012 2:06 pm     Reply with quote

I have successful 10-bit I2C communication between a 16LF1503 master and 16F886 slave. I've included the relevant portions here.

Master.c:
Code:
#include <Master.h>

#use i2c(Master, Slow, sda=PIN_C3, scl=PIN_C4, force_sw, stream=module)

//Communicates with a certain 10-bit slave address by delivering a certain
//data address, then returns the received data.
//Addresses are even, like 7-bit addresses: the form is 0x??????????0.
int16 requestData(int16 slaveAddress, unsigned int dataAddress) {
   int16 data;
   int slaveHigh; //High byte of slave address
   int slaveLow; //Low byte of slave address
   
   //Split slave address into low and high byte
   slaveHigh = (slaveAddress>>8)&0xFE; //Shift over first 3 bits; clear R/W bit
   slaveHigh = slaveHigh|0xF0; //"11110XXX" signifies 10-bit address; add this.
   slaveLow = (slaveAddress>>1)&0xFF; //Get lower 8 bits, without R/W bit
   
   //Instruct slave that you wish to write
   i2c_start(module);
   i2c_write(module, slaveHigh); //High byte
   i2c_write(module, slaveLow); //Low byte
   
   //Give data address
   i2c_write(module, dataAddress);
   
   //Restart; instruct slave that you wish to read
   i2c_start(module);
   i2c_write(module, slaveHigh|1); //High byte with R/W set
   
   //Receive data and finish
   data=i2c_read(module, 1)<<8; //Read high byte and ACK
   data+=i2c_read(module, 0); //Read low byte and end transmission
   i2c_stop(module);
   
   return data;
}

void main() {
   setup_comparator(NC_NC_NC_NC); // This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   
   while(TRUE);
}


Master.h:
Code:
#include <16LF1503.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(int=16000000)


Slave.c:
Code:
#include <Slave.h>

//10-bit addressing bits
#BYTE SSPCON=0x14
#BIT SSPM0=SSPCON.0
#BYTE SSPSTAT=0x94
#BIT UPDATEADDR=SSPSTAT.1
#BIT RW=SSPSTAT.2

//Change # of sensors per module to correct number in sensorVals

int writeBuffer [2]; //Holds data to write through i2c

//10-bit addressing stuff
int1 firstByte; //Records whether first byte of 10-bit address has been received
int16 addrHigh; //High byte of address
int16 addrLow; //Low byte of address

#int_SSP
void i2c_interrupt() {
   if (UPDATEADDR) { //Just received one of two start bytes
      if (!firstByte) { //Just received first byte
         firstByte=TRUE;
         i2c_slaveAddr(addrLow); //Set low byte
      }
      else { //Just received second byte
         firstByte=FALSE;
         i2c_slaveAddr(addrHigh); //Set high byte
      }
      i2c_read();
      return;
   }
   
   //Get state
   int state;
   //Clear R/W bit; CCS compiler sometimes gives incorrect value.
   state = i2c_isr_state()&0b01111111;
   if (RW==TRUE) //Manually retrieve R/W bit.
      state+=0x80;
     
   if (state==0||state==0x80) //Master has issued start command
      i2c_read(); //Clear address from read buffer.
   
   if (state>=0x80) //Master is waiting for data
      i2c_write(writeBuffer[state - 0x80]); //Write appropriate byte, based on how many have already been written
   
   else if(state>0) { //Master has sent data; read.
      unsigned int message;
      message=i2c_read();
      //Master requests sensor data.
      int16 toSend;
      toSend=0b10101010;
      writeBuffer[0] = toSend>>8;
      writeBuffer[1] = toSend&0xFF;
   }
}

void main() {
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_SSP); //Enable interrupts
   enable_interrupts(GLOBAL);
   
   GCEN=TRUE; //Allow general calls
   SSPM0=TRUE; //10-bit addressing
   
   firstByte=FALSE;
   
   int16 slaveAddress=0x1E;
   addrHigh=(slaveAddress>>8)&0xFE; //Calculate high/low bytes of address
   addrHigh=addrHigh|0xF0;
   addrLow=(slaveAddress>>1)&0xFF;
   i2c_slaveAddr(addrHigh); //Set address to high byte
   
   while (true);
}


Slave.h:
Code:
#include <16F886.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOPROTECT                //No read protection
#FUSES NOWRT                    //No write protection

#use delay(int=8000000)

#use i2c(Slave, Slow, sda=PIN_C4, scl=PIN_C3, force_hw, address=0xa0)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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