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 support@ccsinfo.com

16 bits I2C communication between 2 PICs 18F

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



Joined: 25 Feb 2014
Posts: 34
Location: Brazil

View user's profile Send private message

16 bits I2C communication between 2 PICs 18F
PostPosted: Thu Jul 31, 2014 2:51 pm     Reply with quote

This program is to provide 16 bits I2C communication between 2 PICs 18F. The code was done on CCS 5.018, it's commented and working. Tested with PIC18F4520.

Master.c
Code:

#include <18f4520.h>

#fuses HS
#fuses PUT
#fuses NOWDT                    //No Watch Dog Timer
#fuses NOBROWNOUT               //No brownout reset
#fuses NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) //+++ up baud rate?
#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)

/* Bit defines */
#define EEPROM_SCL PIN_C3
#define EEPROM_SDA PIN_C4
#define SLAVE_ADDRESS 0x20 // addr=2 reserved, note address masking.
#define I2C_DELAY_US           16 // worked 20 //Worked 32 //75 //100
#define I2C_INTERBYTE_DELAY_US 60 // worked 80
#byte PIC_SSPCON2  = 0xfc5

void initI2C (void);
void writeI2C (int16 word, unsigned int slave_addr);
int16 readI2C (unsigned int slave_addr);
int16 mainI2C ();

void initI2C (void)
{
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);
}

void writeI2C (int16 word, unsigned int slave_addr)
{
   i2c_start();
   delay_us(I2C_DELAY_US);
   i2c_write(slave_addr);  /* Device Address */
   delay_us(I2C_DELAY_US);
   i2c_write(word & 0x00ff);            //LSB first
   delay_us(I2C_DELAY_US);
   i2c_write((word & 0xff00) >> 8);     //MSB second
   delay_us(I2C_DELAY_US);
   i2c_stop();
   delay_us(I2C_DELAY_US);
}

int16 readI2C (unsigned int slave_addr)
{
   int8 b1=0, b2=0;
   i2c_start();   // restart condition
   delay_us(I2C_DELAY_US);
   i2c_write(slave_addr + 1);
   delay_us(I2C_INTERBYTE_DELAY_US);
   b1 = i2c_read(1);
   delay_us(I2C_INTERBYTE_DELAY_US);
   b2 = i2c_read(0);
   delay_us(I2C_DELAY_US);
   i2c_stop(); 
   return make16(b2, b1);
}

void main(){
int16 data_to_send=18099;
int16 data_received;

initI2C();
delay_ms(10);

  // Write
  writeI2C(data_to_send, SLAVE_ADDRESS);
  printf("Message sent successfully from the Master to the Slave: %ld\n",data_to_send);

  // Read
  data_received = readI2C(SLAVE_ADDRESS);
  printf("Answer received successfully from the Slave to the Master: %ld\n",data_received);
  printf("\n");
}


Slave.c
Code:

#include <18f4520.h>

#fuses HS
#fuses PUT
#fuses NOWDT                    //No Watch Dog Timer
#fuses NOBROWNOUT               //No brownout reset
#fuses NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#fuses NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Slave, Slow, sda=PIN_C4, scl=PIN_C3, force_hw, address=0x20)

/* PIC Registers */
#byte SSPBUF   = 0xfc9
#byte SSPADD   = 0xfc8
#byte SSPSTAT  = 0xfc7
#byte SSPCON1  = 0xfc6
#byte SSPCON2  = 0xfc5
#byte PIE1     = 0xf9d
#byte TRISC    = 0xf94

int16 data_to_send=18100; //In the next step of the code development this data is going to change every loop (sensor data)
int16 data_sent;
int16 data_received;

#int_SSP
void i2c_interrupt() {
   //Get state
   int state;
   int writeBuffer[2];
   int readBuffer[2];

state = i2c_isr_state();

if(state==0) //Address match received with R/W bit clear, perform i2c_read( ) to read the I2C address.
i2c_read();

else if (state==0x80) //Address match received with R/W bit set; perform i2c_read( ) to read the I2C address, and use i2c_write( ) to pre-load the transmit buffer for the next transaction (next I2C read performed by master will read this byte).
i2c_read(2);

if (state>=0x80) //Master is waiting for data
{
writeBuffer[0] = (data_to_send & 0xFF); //LSB first
writeBuffer[1] = ((data_to_send & 0xFF00)>>8);  //MSB secound

i2c_write(writeBuffer[state - 0x80]); //Write appropriate byte, based on how many have already been written
if ((state-0x80)==2){
data_sent=make16(writeBuffer[1],writeBuffer[0]);
printf("\nFull data sent: %ld\n",data_sent);
}
}

else if(state>0) //Master has sent data; read.
{
readBuffer[state - 1] = i2c_read(); //LSB first and MSB secound
if (state==2){
data_received=make16(readBuffer[1],readBuffer[0]);
printf("\nFull data received: %ld\n",data_received);
}
}
}

void main() {
   enable_interrupts(INT_SSP); //Enable interrupts
   enable_interrupts(GLOBAL);
 
   i2c_slaveAddr(0x20);
   
   while (TRUE)
   delay_us(10);
   
}
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