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

No ACK from slave when sending data with I2C
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

No ACK from slave when sending data with I2C
PostPosted: Tue May 09, 2006 12:49 pm     Reply with quote

Hi!

I´m using the code below to send two bytes of data from one master-PIC to a slave-PIC. As you might have guessed...it doesn´t work. When I measure the signal with an oscilloscope I can see that there´s no ACK from the slave after the address have been sent. Nor after the two following data-bytes... The result is that the slave of course never enters the ISR, which sucks... :-)
Can someone please give me a reason why this problem occurs?!!

MASTER-CODE
==========
Code:
#include <i2c_test.H>
#fuses NOWDT
#use i2c(master,sda=PIN_C4,scl=PIN_C3,FORCE_HW)

void send_to_slave() //I2C-funktion
{

      i2c_start();
      if(i2c_write(0x00)) //address to slave
      {
         i2c_write(0x51);    //data1
         i2c_write(0x1B);    //data2
      }
      i2c_stop();

}


main()
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   setup_port_a(NO_ANALOGS);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);

   set_tris_c(0x00);

   while(1) //test-loop
   {
      delay_ms(1000);
      send_to_slave();
   }
}


SLAVE-CODE
=========
Code:
#include <i2c_test.H>
#fuses NOWDT
#use i2c(slave,sda=PIN_C4,scl=PIN_C3,address=0x00,force_hw)

int16 temp;
byte received;

typedef enum {FIRST_READ, LAST_READ} I2C_STATE;
I2C_STATE i2c_status=FIRST_READ;

#int_ssp
receive_isr()
{
   port_d ^= 1; //indicator (reaching ISR?)

   if(i2c_poll())
   {
      if(i2c_status==FIRST_READ)
      {
         received=i2c_read();
         temp=received;
         i2c_status=LAST_READ;
      }
      else if(i2c_status==LAST_READ)
      {
         received=i2c_read();
         temp=(temp<<8)&0xFF00;
         temp=temp+received;
         i2c_status=FIRST_READ;
      }
   }
}

main()
{
   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
   setup_port_a(NO_ANALOGS);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);

   set_tris_d(0x00);  // PORT-D: all output
   set_tris_c(0xFF);  // PORT-C: all input

   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
}
Ttelmah
Guest







PostPosted: Tue May 09, 2006 2:27 pm     Reply with quote

You send an address of '0x51'. This has the low bit set, which means that the master is expecting to _read_ data. You then write data. The I2C_ISR_STATE variable, will be 0x80 after the first transaction (since the read bit is set), and your handler will therefore never call the read function to access the address, hence there is no acknowledge...

Best Wishes
ckielstra



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

View user's profile Send private message

PostPosted: Tue May 09, 2006 2:33 pm     Reply with quote

In your slave add an endless loop at the end of main(). Now it will execute the sleep instruction that CCS puts there and then stop.

Tip: In the SSP interrupt routines you don't have to call i2c_poll(). You will only enter the interrupt when a character was received so calling the i2c_poll function will always return TRUE.
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

wrong...
PostPosted: Tue May 09, 2006 3:06 pm     Reply with quote

The adress that I send is not 0x51, but 0x00. 0x51 is the first byte that I´m sending...
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

and...
PostPosted: Tue May 09, 2006 3:08 pm     Reply with quote

...I forgot the endless loop. But it doesn´t make any difference. There´s still no ack from the slave...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 09, 2006 3:29 pm     Reply with quote

You're using the General Call address of 0x00. Support for this
address has to be specifically enabled by setting the GCEN bit
This is a special address and is not normally used.

From the 16F877 data sheet:
Quote:

The general call address is recognized when the General Call
Enable bit (GCEN) is enabled (SSPCON2<7>).


My suggestion is to use the CCS example file for an i2c slave:
EX_SLAVE.C

You can find this file in: c:\Program Files\PICC\Examples
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

...still not working
PostPosted: Wed May 10, 2006 3:21 am     Reply with quote

Hi again!

Changed to address 0x6C and the slave still doesn´t pull down to data-connection (ACK)....and yes, I´ve modeled the slave code after the "ex_slave.c" code-example...

/David
Ttelmah
Guest







PostPosted: Wed May 10, 2006 3:37 am     Reply with quote

Remember, that you still have to read the address. You are sending an address, then two data bytes, but only have two read functions. As I originally said (though for the wrong reason :-), part of the problem is that your reads, and writes don't match up. If GCEN is enabled, there will then be a second problem from this...

Best Wishes
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

but....
PostPosted: Wed May 10, 2006 3:43 am     Reply with quote

ok, good point......but still, the fact remains that the slave-PIC doesn´t even enter the ISR.... I tried putting the i2c_read()-function in the enternal while-loop in the main-program, but that did not make any difference att all....
Ttelmah
Guest







PostPosted: Wed May 10, 2006 4:11 am     Reply with quote

Which is then probably the general call problem.
The general call address, is _permanently_ decoded by the PIC. It is always 'special'. The GCEN bit, determines whether the PIC will respond to this address. Assuming that the general call 'logic', has a higher priority than the normal address decode logic, then if a general call address is seen, and GCEN is not enabled, the chip will not interrupt...
The GCEN detect logic, is not shown in MicroChip's data sheet, but I'd always avoid this address, unless you are enabling GCEN yourself, and have a modified handler to deal with it.

Best Wishes
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

ok...
PostPosted: Wed May 10, 2006 4:39 am     Reply with quote

...but as I said, right now I´m using the address 0x6C. This seems like a quite "normal" address, right? And the GCEN-bit is cleared right now...

If I´ve understood everything, the hardware will automatically acknowledge each byte sent....but it just doesn´t. I´m watching the data-pin with an oscilloscope and I can see that the slave doesn´t pull down the signal after the address-byte has been sent, which means there´s no ACK...

Thank you so far by the way :-)
Ttelmah
Guest







PostPosted: Wed May 10, 2006 6:28 am     Reply with quote

What is 'true' in C?.
You test I2C_WRITE, before sending the following bytes. What logic does I2C_Write use?.

Best Wishes
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

0=ACK
PostPosted: Wed May 10, 2006 6:53 am     Reply with quote

...so once again you´ve made a pretty good point. Since the SLAVE does´t ACK the address-write (which is the same as the test-write), the i2c_write()-function returns TRUE=1 and sends the two data-bytes.
But this does not change the fact that the i2c-hardware in the SLAVE-pic doesn´t ACK the address-write at all....
Ttelmah
Guest







PostPosted: Wed May 10, 2006 7:37 am     Reply with quote

What is the slave doing when it runs?. Hint: Unlike on a PC, there is no 'OS' for the chip to drop back to, when it exits the 'main' routine.

Best Wishes
davey



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

I know the while(1); statment is missing in the slave-code..
PostPosted: Wed May 10, 2006 8:24 am     Reply with quote

...I inserted it after I posted the message on this forum. But the problem still remained....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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