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

I2C Master and Slave, both PIC18F26K22

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



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

I2C Master and Slave, both PIC18F26K22
PostPosted: Wed Feb 05, 2020 10:13 pm     Reply with quote

The programs posted is for I2C Master PIC18F26K22 and Slave PIC18F26K22.
Both PIC works at 64MHz. The I2C setting is for Fast=400000, at Slow=100000 works also.
The Master initiating write/read sequence every 2000 ms, 8 bytes write and 8 bytes read.
Each write all the bytes are incremented by the master so the results can be analysed on a PC terminal, every 2000 ms. The data is sent to the PC as 9 bytes, first byte 0x00h denotes that the message is after I2C write/read
The Master initiating read sequence every 200 ms, 8 bytes read.
The results can be analysed on a PC terminal, every 2000 ms. The data is sent to the PC as 9 bytes, first byte 0xAAh denotes that the message is after I2C read.
The I2C Master and Slave were written with step by step BIG HELP from Ttelmah.
Thanks also for PCM Programmer for helping this project.
In the link bellow can see the development:
https://www.ccsinfo.com/forum/viewtopic.php?t=58095
The programs were tested for hours, no any errors occurred. Both PIC on the same board with 2K7 resistors on SDA and SCL, 5V supply.

Master:
Code:

/////////////////////////////////////////////////////////////////////
//I2C26K22MT project based on Ttelmah CCS forum posts
//The program is for I2C Master PIC18F26K22 and Slave PIC18F26K22
//Program last update,February 6, 2020
/////////////////////////////////////////////////////////////////////
#include <18F26K22.h>
#device ADC=10
#FUSES WDT,WDT4,NOPBADEN,PUT,BROWNOUT,BORV29,HSH,PLLEN,NOIESO,NOFCMEN,NOHFOFST                                       
#FUSES MCLR,STVREN,NOLVP,NOXINST,NODEBUG,NOPROTECT,NOCPD,NOWRT,NOWRTC,NOWRTD
#use delay(clock=64MHz,crystal=16MHz)
#use rs232(baud=9600, UART1, stream=PORT1, errors)
#use I2C(MASTER, FAST=400000, I2C1, STREAM=I2CPORT)
#byte SLRCON = GETENV("SFR:SLRCON")
/////////////////////////////////////////////////////////////////////
#define LED PIN_B5//flashes ones a second
int tx1words,tx1w0,tx1w1,tx1w2,tx1w3,tx1w4,tx1w5,tx1w6,tx1w7,tx1w8;
short I2CwriteF,I2CreadF,I2CwritedoneF,I2CreaddoneF,timer0F;
int flash=0,I2CstartR=20,I2CstartW=0,TXstart=0;
int data0=0x00,data1=0x20,data2=0x40,data3=0x60,data4=0x80,data5=0xA0,data6=0xC0,data7=0xE0;
int rpt0,rpt1,rpt2,rpt3,rpt4,rpt5,rpt6,rpt7;
/////////////////////////////////////////////////////////////////////
#int_TIMER0//Timer0 increments every 20ms
void TIMER0_isr(void)
{
   timer0F=1;
   set_timer0(45536);
}
#int_TBE//TX1 to PC; transmits 9 bytes
void TBE_isr(void)
{
   switch(tx1words)
   {
      case 0:
      {
         fputc(tx1w0,PORT1);   
         tx1words++;   
      }
      break;
      case 1:
      {
         fputc(tx1w1,PORT1);
         tx1words++;         
      }
      break;
      case 2:
      {
         fputc(tx1w2,PORT1);   
         tx1words++;         
      }
      case 3:
      {
         fputc(tx1w3,PORT1);
         tx1words++;         
      }
      break;
      case 4:
      {
         fputc(tx1w4,PORT1);   
         tx1words++;         
      }
      break;
      case 5:
      {
         fputc(tx1w5,PORT1);
         tx1words++;         
      }
      break;
      case 6:
      {
         fputc(tx1w6,PORT1);   
         tx1words++;         
      }
      case 7:
      {
         fputc(tx1w7,PORT1);
         tx1words++;         
      }
      break;
      case 8:
      {
         fputc(tx1w8,PORT1);
         tx1words=0;
         disable_interrupts(INT_TBE);      
      }
      break;
   }   
}
#int_RDA//RX1 not used
void RDA_isr(void)
{
   delay_cycles(1);
}
//FUNCTIONS
void FUNCTIONS(void)
{
   if(timer0F==1)
   {
      timer0F=0;
      flash++;
      I2CstartW++;
      I2CstartR++;
      if(flash>=25)
      {
         flash=0;
         output_toggle(LED);
      }   
   }
   if(I2CstartW==100)//I2C write/read every 2000ms
   {
      I2CstartW=0;
      data0++;//increment for write/read testing
      data1++;//increment for write/read testing   
      data2++;//increment for write/read testing
      data3++;//increment for write/read testing   
      data4++;//increment for write/read testing
      data5++;//increment for write/read testing   
      data6++;//increment for write/read testing
      data7++;//increment for write/read testing   
      I2CwriteF=1;
   }
   if(I2CwritedoneF==1)//after I2C write/read send message to PC
   {
      I2CwritedoneF=0;
      tx1w0=0x00;
      tx1w1=rpt0;
      tx1w2=rpt1;
      tx1w3=rpt2;
      tx1w4=rpt3;
      tx1w5=rpt4;
      tx1w6=rpt5;
      tx1w7=rpt6;
      tx1w8=rpt7;
      enable_interrupts(INT_TBE);
   }
   if(I2CstartR==10)//I2C read every 200ms
   {
      I2CstartR=0;
      TXstart++;
      I2CreadF=1;   
   }
   if(I2CreaddoneF==1)//I2C2 read done
   {
      I2CreaddoneF=0;
      if(TXstart==10)//sends read message to PC every 2000ms
      {
         TXstart=0;
         tx1w0=0xAA;
         tx1w1=rpt0;
         tx1w2=rpt1;
         tx1w3=rpt2;
         tx1w4=rpt3;
         tx1w5=rpt4;
         tx1w6=rpt5;
         tx1w7=rpt6;
         tx1w8=rpt7;
         enable_interrupts(INT_TBE);
      }
   }
}
///////////////////////////////////////////////////////////////////
void I2C (void)//I2C26K22M master write/read starts every 2000ms
{
    if(I2CwriteF==1)
    {
         I2CwriteF=0;
//write data to Slave PIC
        i2c_start();
      delay_us(5);
        i2c_write(0xB0);//Slave address with write
      delay_us(5);
        i2c_write(data0);
      delay_us(5);
        i2c_write(data1);
      delay_us(5);
        i2c_write(data2);
      delay_us(5);
        i2c_write(data3);
      delay_us(5);
        i2c_write(data4);
      delay_us(5);
        i2c_write(data5);
      delay_us(5);
        i2c_write(data6);
      delay_us(5);
        i2c_write(data7);
      delay_us(5);
        i2c_stop();
//read back data from the Slave PIC
        delay_us(1000); //ensure the Slave has had time to complete the write
        i2c_start();
      delay_us(5);
        i2c_write(0xB1);//Slave address with read
      delay_us(5);
        rpt0 = i2c_read();
      delay_us(5);
        rpt1 = i2c_read();
      delay_us(5);
        rpt2 = i2c_read();
      delay_us(5);
        rpt3 = i2c_read();
      delay_us(5);
        rpt4 = i2c_read();
      delay_us(5);
        rpt5 = i2c_read();
      delay_us(5);
        rpt6 = i2c_read();
      delay_us(5);
        rpt7 = i2c_read(0);
      delay_us(5);
        i2c_stop();
      I2CwritedoneF=1; 
   }
//read data from the Slave PIC
   else if(I2CreadF==1)
   {
      I2CreadF=0;
          i2c_start();
      delay_us(5);
        i2c_write(0xB1);//Slave address with read
      delay_us(5);
        rpt0 = i2c_read();
      delay_us(5);
        rpt1 = i2c_read();
      delay_us(5);
        rpt2 = i2c_read();
      delay_us(5);
        rpt3 = i2c_read();
      delay_us(5);
        rpt4 = i2c_read();
      delay_us(5);
        rpt5 = i2c_read();
      delay_us(5);
        rpt6 = i2c_read();
      delay_us(5);
        rpt7 = i2c_read(0);
      delay_us(5);
        i2c_stop();
      I2CreaddoneF=1;
   }
}
///////////////////////////////////////////////////////////////////

#ZERO_RAM

void main()
{
   SLRCON=0; //Turn off slew rate limit.
   setup_adc_ports(NO_ANALOGS);
   setup_wdt(WDT_16MS);//~16 ms reset   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);//65.536 ms overflow
   enable_interrupts(INT_TIMER0);
   disable_interrupts(INT_RDA);
   disable_interrupts(INT_TBE);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      restart_wdt();
      FUNCTIONS();
      I2C();
   }
}
/////////////////////////////////////////////////////////////////////

Slave:
Code:

/////////////////////////////////////////////////////////////////////
//I2C26K22ST project based on Ttelmah posts
//The program is for Slave I2C PIC18F26K22 communicating with Master PIC18F26K22
//Program last update,February 6, 2020
/////////////////////////////////////////////////////////////////////
#include <18F26K22.h>
#device ADC=10
#FUSES WDT,WDT4,NOPBADEN,PUT,BROWNOUT,BORV29,HSH,PLLEN,NOIESO,NOFCMEN,NOHFOFST                                       
#FUSES MCLR,STVREN,NOLVP,NOXINST,NODEBUG,NOPROTECT,NOCPD,NOWRT,NOWRTC,NOWRTD
#use delay(clock=64MHz,crystal=16MHz)
#use i2c(Slave,Address=0xB0,I2C1)//I2C1 module, automatically hardware
#byte SLRCON = GETENV("SFR:SLRCON")
/////////////////////////////////////////////////////////////////////
#define LED PIN_C5//flashes ones a second
int flash=0;
int state,value;
int data0,data1,data2,data3,data4,data5,data6,data7;
#int_TIMER0
void TIMER0_isr(void)
{
   flash++;
   if(flash>=25)//500ms
   {
      flash=0;
      output_toggle(LED);
   }
   set_timer0(45536);
}
/////////////////////////////////////////////////////////////////////
//The core I2C slave code.   
//Now states < 0x80, are read states. The master is sending us data
//However state 0x0, is where the master sends up the address itself
//so we need to use state-1 as the array index to write data
//State 0x80 is where the master sends the address for the write. On this
//we must read, and then write the byte for the reply.
/////////////////////////////////////////////////////////////////////
#INT_SSP
void I2C_isr (void)
{
   state=i2c_isr_state();
   if (state<=0x80)
   {
      switch(state)
      {
           case 0x80:     
            value=i2c_read(0x02);//here we need to read, and not release the clock
         break;   
           case 0:
            value=i2c_read();//throw away address read
         break; 
           case 1:
            data0=i2c_read();
         break;
           case 2:
            data1=i2c_read();
         break;
           case 3:
            data2=i2c_read();
         break;
           case 4:
            data3=i2c_read();
         break; 
           case 5:
            data4=i2c_read();
         break;
           case 6:
            data5=i2c_read();
         break; 
           case 7:
            data6=i2c_read();
         break;
           case 8:
            data7=i2c_read();
         break;
      }
   }
   switch(state) 
   {
      case 0x80:
         i2c_write(data0);
      break;
      case 0x81:
         i2c_write(data1);
      break;
       case 0x82:
         i2c_write(data2);
      break;
      case 0x83:
         i2c_write(data3);
      break;
       case 0x84:
         i2c_write(data4);
      break;
      case 0x85:
         i2c_write(data5);
      break; 
       case 0x86:
         i2c_write(data6);
      break;
      case 0x87:
         i2c_write(data7);
      break;                             
   }
}
/////////////////////////////////////////////////////////////////////

#ZERO_RAM

void main()
{
   SLRCON=0; //Turn off slew rate limit.
   setup_adc_ports(NO_ANALOGS);
   setup_wdt(WDT_16MS);//~16 ms reset      
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);//65.536 ms overflow
   enable_interrupts(INT_TIMER0);
    enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   while(TRUE)
   {
      restart_wdt();
   }
}
/////////////////////////////////////////////////////////////////////

Apologizing for my clumsy rs232. Can change it as anyone wish
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