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 slave routine doesn't work (ex_slave.c)

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



Joined: 11 May 2009
Posts: 22

View user's profile Send private message

[I2C] pic slave routine doesn't work (ex_slave.c)
PostPosted: Wed Oct 06, 2010 7:05 am     Reply with quote

I'm trying to implement a communication between two pic using the I2C protocol. I'm using the routine of ccs ex_slave.c but i can't read and write in to the slave pic.

the master code:
Code:
#include <30F3013.h>
#include "master.h"
#use rs232(UART2,baud=115200,parity=N,bits=8,xmit=PIN_F5,rcv=PIN_F4,TIMEOUT=1000)
#use i2c(Master,Fast,sda=PIN_F2,scl=PIN_F3,I2C1, FORCE_SW)
#zero_ram


void write_ext_eeprom(BYTE address, BYTE data);
BYTE read_ext_eeprom(BYTE address);
   
void main()

   int8 a, i, lettura;
   setup_timer2(TMR_DISABLED);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_wdt(WDT_on);
   setup_timer1(TMR_DISABLED);
   printf("inizalizzazione in corso..\n\r");
   
   while(1)
   {
   output_bit(LED_OK,0);
 
   for (i=0;i<=10;i++)
      {
      printf("scrivo %u valore\n\r" i);
      write_ext_eeprom(i, i);
      delay_ms(10);
      }
   
   for(i=0;i<=10;i++)
      {
      lettura=read_ext_eeprom(i);
      printf("valore %u: %u\n\r" i, lettura);
      delay_ms(5);
      }
   
   delay_ms (2000);
   output_bit(LED_OK,1);
   delay_ms(400);
   }
}


void write_ext_eeprom(BYTE address, BYTE data) {
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
}


BYTE read_ext_eeprom(BYTE address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}

master pic read from slave always the value 66.

the slave code:
Code:

#include <18F8722.h>
#include <slave.h>
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,force_hw,address=0xa0)
#use rs232(baud=115200, xmit=PIN_c6,rcv=PIN_c7)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();
   printf("stato: %u\n\r" state);
   if(state <= 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      printf("lettura %u\n\r" incoming);
      if(state == 1)                     //First received byte is address
         address = incoming;
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)                     //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
}


void main()
{
   int i;
   setup_adc_ports(AN0|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_16|ADC_TAD_MUL_4);
   setup_psp(PSP_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_tris_d(0x00); //port d sono  uscite
   set_tris_c(0xff); //port c sono  ingressi
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while(1)
   {
   for(i=0;i<=10;i++)
      {
      printf("valore %u: %u\n\r" i, buffer[i]);
      }
      delay_ms (3000);
   }
}

the i2c_isr_state() return always 0, and the i2c_read() return always 0xA0 (slave adress).
Anyone can help me?
Thanks.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Oct 06, 2010 7:16 am     Reply with quote

What is your compiler version number?
blo



Joined: 11 May 2009
Posts: 22

View user's profile Send private message

PostPosted: Wed Oct 06, 2010 7:19 am     Reply with quote

I've got the PCWHD V4.096
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Oct 06, 2010 9:52 am     Reply with quote

One quick look and I can see that your slave code has printf() statements in the ISR routines, which will take up HUGE amounts of time. All while your master code is just plugging along at top speed, sending each command one after another. Odds are, your slave is still printing after the master is finished sending commands. If you need some kind of visual confirmation that a certain section of your code is being excecuted then just turning on an LED would work. Keep printf() and delays out of interrupts. Also, make sure your master is not sending commands faster than your slave can process each command.

Specifying Fast in your slave #use line does nothing. It's the master that controls the speed of the bus. Setting the tris has no effect without fast_io being specified, as well. I would not set the tris, manually, but allow the compiler control it.

Ronald
blo



Joined: 11 May 2009
Posts: 22

View user's profile Send private message

PostPosted: Thu Oct 07, 2010 5:56 am     Reply with quote

i've rebuild the project and now the master can write in to the slave, but when the master call the slave for reading, the slave always respond with 0x42.
the new interrupt handler is:
Code:
#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();
   
   if(state <= 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;
      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)                     //Master is requesting data
   {
      output_high(led_4);
//i2c_write(buffer[address]);
      i2c_write(0b10101010);
     
   }
}


and the master code:
Code:
void main()
{
int8 data,i;

for (i=0;i<=10;i++)
      {
      printf("scrivo %u valore\n\r" i);
      write_ext_eeprom(i, i);  //writing routine goes well
      delay_ms(20);
      }

// Read from the slave board and display the data.
i2c_start();
i2c_write(0xA0);
i2c_write(0x00);

i2c_start();
i2c_write(0xA1);
data = i2c_read(0);
i2c_stop();
printf("read %u \n\r", data);
     
while(1);     
}     
blo



Joined: 11 May 2009
Posts: 22

View user's profile Send private message

PostPosted: Thu Oct 07, 2010 8:47 am     Reply with quote

I've found the problem:
Code:
 BYTE read_ext_eeprom(BYTE address) {
   BYTE data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   delay_us(10);    //without delay it doesn't work!
   data=i2c_read(0);
   i2c_stop();
   return(data);
}

with the delay it works.
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