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 slave can either send or receive but can not do both

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







i2c slave can either send or receive but can not do both
PostPosted: Wed Jan 02, 2008 11:14 am     Reply with quote

i am using 18f8722 for both master and slave. the master clock is 10mhz and the master code has been written and tested by another guy (using mplab compiler). the clock for the slave is 40mhz. the following code has been tested, and the sending part and the receiving part works well individually (sending or receiving data every 100ms), but when both sending and receiving are enabled in the master program, we saw that the data were sent or received for only one time, not continuously sending and receiving every 100ms.

EX_SLAVE.C has been tried, the result is the same.

can anybody tell me why? first time use i2c.


#include <18F8722.h>
//#device HIGH_INTS = TRUE
#device ICD=TRUE
#device adc=10
#use delay(clock=40000000)

#fuses HS
#fuses FCMEN , NOSTVREN, LVP, IESO, MCLR, BORV45, NOWDT, NOPROTECT, DEBUG


#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xA0)

BYTE address, buffer[0x10];
//int8 start_stop_master;
//int8 vdc_set_master;
//int8 frequency_master = 3; int8 pulse_master=17;
int8 address_temp;

#byte start_stop_master = 0x20
#byte vdc_set_master = 0x21
#byte frequency_master = 0x22
#byte pulse_master = 0x23
#byte cheksum = 0x24
#byte address_temp1 = 0x25
#byte address_temp2 = 0x26
#byte SSP1CON1 = 0xFC6
#BIT CKP = SSP1CON1.4
#BYTE SSP1ADD = 0xFC8

#BYTE SSP1STAT = 0xFC7

long power1 = 0xaaaa;
long power2 =0xbbbb;
long power3 = 0xcccc;
long power4 = 0xdddd;
int8 Hbridge_status = 1;
int8 protection_status = 0;

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



state = i2c_isr_state();
if(state <0x80>>8);
delay_us(100);

i2c_write(power2);
delay_us(100);
i2c_write(power2>>8);
delay_us(100);

i2c_write(power3);
delay_us(100);

i2c_write(power3>>8);
delay_us(100);
i2c_write(power4);
delay_us(100);

i2c_write(power4>>8);
//delay_ms(1);


}

}

void main ()
{

set_tris_c(0xff);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while (TRUE) {;)



}
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jan 02, 2008 11:45 am     Reply with quote

Some general remarks first:
    - When posting code please use the 'code' buttons to preserve formatting and layout of your code. This makes reading the code a lot easier.
    - When posting code select the 'disable HTML in this post' option. Now several lines in your code are unreadable because they have been interpreted as HTML. Tip: become a registered user of this forum and you can activate this option as a default in your profile.
    - Always mention the version number of your compiler.


Even though your code is garbled there are some comments for improvement:
- Check the LVP fuse. 99% of the people are using a high voltage programmer and set it to NOLVP. Enabling the LVP fuse when you are not using Low Voltage Programming could cause problems: a voltage spike on the PGM pin (B5) will stall your processor. Note: I see you enabled the ICD fuse; the ICD-2 and CCS debuggers are high voltage programmers.

- A clock speed of 40MHz can only be achieved with an external 40MHz clock generator (EC fuse) or a 10MHz crystal in combination with the 4xPLL (H4 fuse). Your HS fuse setting only supports a crystal up to 25MHz, not 40MHz.

- The #use i2c directive uses a software I2C driver by default. Add FORCE_HW to ensure the hardware MSSP module is used, this is compulsory for a slave.

Fix the above mentioned problems and test again. If it still fails then post your code again with the above mentioned suggestions in place and all obsolete lines removed (the #byte lines and all commented code lines).
chentou
Guest







i2c can only send or receive but can not do both
PostPosted: Thu Jan 03, 2008 8:05 am     Reply with quote

Thanks.
PCH compiler v4.057. change to #fuses EC, change to NOLVP, and add FORCE_HW. the result is the same, only do one time sending and receiving.
master sends A0 (address), 78, 56. 34, 12, B4 (cheksum), and the slave receives all of these data, and after B4, the slave receives A1 in address_temp1, which i think is the address master sent for receiving data from slave.
chentou
Guest







code is here
PostPosted: Thu Jan 03, 2008 8:14 am     Reply with quote

Code:

#include <18F8722.h>

#device ICD=TRUE
#device adc=10
#use delay(clock=40000000)

#fuses EC   
#fuses FCMEN , NOSTVREN, NOLVP, IESO, MCLR, BORV45, NOWDT, NOPROTECT, DEBUG


#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xA0,FORCE_HW)



#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;
   TEMP1 = SSP1STAT;
   
 
   
   state = i2c_isr_state();

   if(state < 0x80)                     
   {
      incoming = i2c_read();
     
      if(state == 0)                   
     
        start_stop_master = incoming;
       
         
      if(state == 1)                   
         vdc_set_master = incoming;
         
 
      if (state == 2)
         frequency_master = incoming;

     
      if (state ==3)
         pulse_master = incoming;

   
      if (state ==4)
         cheksum = incoming; 
       
   
      if (state == 5)
         address_temp1 = incoming;

   
      if (state == 6)
         address_temp2 = incoming;
   
     
   }
   if(state == 0x80)                   
   {     
 
     
 
       delay_us(100);
       i2c_write(0x55);
     
       delay_us(100);
       i2c_write(0x33);

       delay_Us(100);
       i2c_write(protection_status);

       delay_us(100);
       i2c_write(power_reactor1);
     
       delay_us(100);
       i2c_write(power_reactor1>>8);

       delay_us(100);
       i2c_write(power_reactor2);

       delay_us(100);
       i2c_write(power_reactor2>>8);

       delay_us(100);   
       i2c_write(power_reactor3);

       delay_us(100);
       i2c_write(power_reactor3>>8);

       delay_us(100);
       i2c_write(power_reactor4);

       delay_us(100);
       i2c_write(power_reactor4>>8);
   
     

   }
   
}

void main ()
{
   
   

   set_tris_c(0xff);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE) ;
   
   
 
}
ckielstra



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

View user's profile Send private message

PostPosted: Thu Jan 03, 2008 4:28 pm     Reply with quote

Your program is not complete, several variable declarations are missing. This tells us you are not showing the exact version you are testing with.

In your first version you declared some variables as
Code:
#byte cheksum = 0x24
#byte address_temp1 = 0x25
#byte address_temp2 = 0x26
This is not the normal way of declaring variables, you only do this when you want to specify the exact memory location for a variable. A problem is that #byte does not prevent C from using the same memory for other (normal declared) variables. This overlapping of variables might be your problem.
If you do want to specify the memory location but for exclusive use you should have used #locate instead.

Quote:
master sends A0 (address), 78, 56. 34, 12, B4 (cheksum), and the slave receives all of these data, and after B4, the slave receives A1 in address_temp1, which i think is the address master sent for receiving data from slave.
You didn't show us the Master code and I'm no I2C expert but it could be you are missing an I2C stop command.

The method you use for sending the reply to the master is quick but very dirty. Check the example codes for a proper implementation.
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