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 multi byte Master-Slave

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



Joined: 25 Oct 2007
Posts: 7
Location: Puebla Mexico

View user's profile Send private message

I2C multi byte Master-Slave
PostPosted: Thu Oct 25, 2007 12:48 pm     Reply with quote

Hi there, im been using PICS for a time now, but im new using the I2C comunication, im trying now just to send 3 bytes of information from master(18F4550) to the slave(18F4550), then store them in the slave in to a buffer and use that data to display the values in a LCD.

The LCD its working just fine, it reads bytes and so, but the problem is that i cant reade the 3 bytes, i just get 1 right and the ohter apeear as -96
so i have been searching for a post where they use multiple bytes but i didnt find any one, maybe u can help me out guys, ill be very gratful, thanks to all.

Here is the code. i just send to bytes for now,
MASTER
Code:

#include <18F4550.h>                      //PIC utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP           //Configuramos los fuses
#use delay (clock=4000000)                //Oscilador a 4Mhz
#use fast_io(b)                           //Optimizamos E/S del PORTB
#use fast_io(c)                           //Optimizamos E/S del PORTC
#use i2c(master, sda=PIN_B0, scl=PIN_B1) // Configure Device as Master
                     
                     
//Programa principal

void main(void) {

while(true){
i2c_start();
i2c_write(0xA0); //Slave adress
DELAY_MS(100);
i2c_write(0x0A); //first data to be display
DELAY_MS(100);
i2c_write(0x0F); //second data to be display
DELAY_MS(500);
i2c_stop();     
DELAY_MS(200);

}
}



THen the SLAVE, that also displays the data

Code:

#include <18F4550.h>                      //PIC utilizado
#fuses HS,NOWDT,NOPROTECT,NOLVP           //Configuramos los fuses
#use delay (clock=4000000)                //Oscilador a 4Mhz
#use fast_io(b)                           //Optimizamos E/S del PORTB
#use fast_io(c)                           //Optimizamos E/S del PORTC
#use i2c(slave,address=0xa0,sda=PIN_B0, scl=PIN_B1,slow) // Configure Device as Slave
#include "lcd.c"                         //Incluyo LCD.C
BYTE bufferTemp [3],state,incoming;
//char temp=0x05;
//=========interrupcion para I2C======

#INT_SSP
void i2c_interupt (void)
{
   state = i2c_isr_state();
   
    if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte
         bufferTemp[0] = incoming;
      if(state == 2)                     //Second received byte
         bufferTemp[1] = incoming;
     
   }
}


//Meotodo para desplegar tecto y temperatura en LCD
void lcd_desplegar(void) {
   while(TRUE){ //Condicion para que siempre se ejecute el metodo
   printf(lcd_putc,"Temperatura1:%d",buffertemp[0]); //imprime el texto1 junto con el valor de la varibale temp
   delay_ms(1000); //retaro
   lcd_putc( "\f");      //borra display
   printf(lcd_putc,"Temperatura2:%d",buffertemp[1]); //imprime el texto1 junto con el valor de la varibale temp
   delay_ms(1000); //retaro
   lcd_putc( "\f");
   printf(lcd_putc,"Temperatura3:%d",buffertemp[2]); //imprime el texto1 junto con el valor de la varibale temp
   delay_ms(1000); //retaro
   lcd_putc( "\f");
   }
}

//Programa principal

void main(void) {
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);//interruptions
   buffertemp[0]=0x01;
   buffertemp[1]=0x02;
   buffertemp[2]=0x03;
   lcd_init(); //inicialisa el LCD
   lcd_desplegar();//llama al metodo para deslpegar texto en LCD
}


I have already try multiple ways, but no one works, the most i can do its to read succesfully one byte but no more, thanks for your help.
Ttelmah
Guest







PostPosted: Thu Oct 25, 2007 4:00 pm     Reply with quote

Series of things.
First, get rid of the 'slow' declaration in the slave. The slave has _nothing to do with I2C timing_. If you want to use 'slow', this needs to be in the master.
Next, you need to read the byte whenever the I2C_ISR_STATE is below 80. Read the byte, then test the state, to work out where to put it.
Obviously, presumably you do have pull-up resistors on the bus?.
I'd shorten the delays rather massively.
ex_slave.c, shows how to handle an indexed transfer to an address. If you simply reset your counter, then use:
Code:

#INT_SSP
void ssp_interupt ()
{
   //Only have variabled that need to be 'global', global.
   //reduces risk of data getting accidentally corrupted...
   BYTE incoming, state;
   static int address;
   state = i2c_isr_state();

   if(state <0x80>2) address=2; //prevent overrun
      }
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(0);  //Dummy return to ensure I2C doesn't get confused
   }
}


Best Wishes
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Fri Oct 26, 2007 9:36 am     Reply with quote

I've never used the i2c_isr_state() command but perhaps the answer to my question might help AntonioB a bit.

The help file states that a value of 1-0x7F means the Master has written data. Does this value increment starting from 1 with each byte that is written or is it some kind of arbitrary value? Also, a value of 0x81-0xFF means a transmission is finished and ACK'd and a write needs to be performed. Does this value increment just like the first question I posed?

I've always manipulated the registers directly and I'm just curious about this command.

Ronald

If the world were to start spinning faster, would be all start losing weight?
AntonioB



Joined: 25 Oct 2007
Posts: 7
Location: Puebla Mexico

View user's profile Send private message

PostPosted: Mon Oct 29, 2007 5:21 pm     Reply with quote

ok, thanks alot for your answer im going to check that, thanks
Guest








PostPosted: Tue Oct 30, 2007 4:43 pm     Reply with quote

The code now works just right, I just change the state condition, and now I can send and receive data thanks for the help.
Code:

#INT_SSP
void i2c_interupt (void)
{
   state = i2c_isr_state();
   
    if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 0)                     //First received byte
         bufferTemp[0] = incoming;
      if(state == 1)                     //Second received byte
         bufferTemp[1] = incoming;
      if(state== 2)
         bufferTemp[2] = incoming;
      if(state== 3)
         bufferTemp[3] = incoming;
      if(state== 4)
         bufferTemp[4] = incoming;
      if(state== 5)
         bufferTemp[5] = incoming;
      if(state== 6)
         bufferTemp[6] = incoming;
   }
   if (state == 0x80)
   {
      i2c_write(0);
   }
 

}
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