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

help on i2c: hangs up i2c_write

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








help on i2c: hangs up i2c_write
PostPosted: Wed Jan 28, 2009 9:20 pm     Reply with quote

Hi,
We are trying to communicate 2 PIC16F877A using I2C. We are using MPLAB ICD2 Debugger with CCS as compiler (CCS PCWH + PCW + IdeUtils 4.013 plugin.)

here is our master's code:


Code:
#if defined(__PCM__)
#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#DEVICE *=16 ICD=TRUE
#use Delay (Clock=8000000)
#use rs232 (Baud=4800,Xmit=PIN_C6,parity=e,bits=8,INVERT)
#use i2c (MASTER,SDA=PIN_C4,SCL=PIN_C3,FORCE_HW)

//For BCD converted Keypad Module
#define keyA input_state(PIN_D0)
#define keyB input_state(PIN_D1)
#define keyC input_state(PIN_D2)
#define keyD input_state(PIN_D3)
#define Strobe input_state(PIN_D4) //if a key is pressed

int msg;
int1 isDisplay = 1;
int getKey()
{
   char c;
   int u;
   c = 0x13;
start_again:
   while(input_d() & 0x10){
   if ((keyD == 0)&&(keyC == 0)&&(keyB==0)&&(keyA==0)){c=0x30;u=0;}
   if ((keyD == 0)&&(keyC == 0)&&(keyB==0)&&(keyA==1)){c=0x31;u=1;}
   if ((keyD == 0)&&(keyC == 0)&&(keyB==1)&&(keyA==0)){c=0x32;u=2;}
   if ((keyD == 0)&&(keyC == 0)&&(keyB==1)&&(keyA==1)){c=0x33;u=3;}
   if ((keyD == 0)&&(keyC == 1)&&(keyB==0)&&(keyA==0)){c=0x34;u=4;}
   if ((keyD == 0)&&(keyC == 1)&&(keyB==0)&&(keyA==1)){c=0x35;u=5;}
   if ((keyD == 0)&&(keyC == 1)&&(keyB==1)&&(keyA==0)){c=0x36;u=6;}
   if ((keyD == 0)&&(keyC == 1)&&(keyB==1)&&(keyA==1)){c=0x37;u=7;}
   if ((keyD == 1)&&(keyC == 0)&&(keyB==0)&&(keyA==0)){c=0x38;u=8;}
   if ((keyD == 1)&&(keyC == 0)&&(keyB==0)&&(keyA==1)){c=0x39;u=9;}
   if ((keyD == 1)&&(keyC == 0)&&(keyB==1)&&(keyA==0)){c=0x1B;u=255;} // Enter
   if ((keyD == 1)&&(keyC == 0)&&(keyB==1)&&(keyA==1)){c=0x7F;u=127;} // Back
   }
   if(c==0x13){goto start_again;}
   if (isDisplay == 1){ printf("%c",c);} // reflect key pressed on LCD
   return(u);
}

void main()
{
   set_tris_d(0xFF);
   isDisplay = 1;
   while(TRUE)
   {   
      printf("%c", 0x0D); //Q-term LCD command function
      printf("Press A Key");
      msg = getKey();
      i2c_start();
      i2c_write(0xA0);
      i2c_write(msg);
      i2c_stop
   }      
}



and here is the slave's code:




Code:
#if defined(__PCM__)
#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#DEVICE *=16 ICD=TRUE ADC=8
#use Delay (Clock=8000000)
#use i2c (SLAVE,sda=PIN_C4,scl=PIN_C3,address=0xa0)

int mode;
int1 isBlink;

#INT_SSP
void ssp_interrupt()
{
   int ch;
   if (i2c_poll()) // if there is data to be read
   {
      ch = i2c_read(); // read from i2c
      if (mode == address) // if mode is address
      {
         mode = data; // set mode to data
      }
      else
      {
         if (ch == 1)
         {
            isBlink = 0;
         }
         mode = address;
      }
   }
}

void main ()
{
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   set_tris_d(0x00);
//   set_tris_c(0xFF);
   output_low(PIN_D3);
   output_high(PIN_D2);
   isBlink = 1;
   mode = address;
   while(TRUE)
   {
      if (isBlink==0)
      {
         isBlink = 1;
         output_high(PIN_D0);
         delay_ms(1000);
         output_low(PIN_D0);
      }   
   }
}


The program always hangs up during i2c_write as pinpointed by the ICD2 Debugger. We also tried to place a 10k pull-up resistors to both SDA and SCL pins of the master, yet it still hangs up. We can't seem to find out what is wrong. Can you kindly tell us what we did wrong. Thank you for any response.
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Wed Jan 28, 2009 10:14 pm     Reply with quote

Pull-up resistors are very necessary. If 10k didn't work try 2k on both lines. That is the likely cause of hanging during i2c_write.
_________________
The search for better is endless. Instead simply find very good and get the job done.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 29, 2009 12:47 am     Reply with quote

Your slave code doesn't compile. That's not your real code. Results:
Quote:

>>> Warning 204 "pcm_test.c" Line 18(1,1): Condition always FALSE address
*** Error 12 "pcm_test.c" Line 18(19,26): Undefined identifier
*** Error 12 "pcm_test.c" Line 20(17,21): Undefined identifier data
*** Error 51 "pcm_test.c" Line 22(7,11): A numeric expression must appear here
*** Error 12 "pcm_test.c" Line 28(17,24): Undefined identifier address
*** Error 12 "pcm_test.c" Line 42(11,18): Undefined identifier address
5 Errors, 1 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Wed Jan 28 22:21:17 2009

I suggest that you use the following code for your master and slave,
to see if your hardware is working correctly. Then you can try your
own code later. See below:

Use the code in the CCS example file, Ex_Slave.c for your slave.
Here's the file location:
Quote:
c:\program files\picc\examples\ex_slave.c


For the master, use the code shown in this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=28097&start=9

See if it works.
Guest








PostPosted: Thu Jan 29, 2009 12:54 am     Reply with quote

@sherpadoug

2k pull-ups resistor didn't work. How low should be the resistance be?
Or do I need to also put pull-ups at the slave side??? Thanks for any reply

@PCM programmer

Sorry. I did remove some identifiers to shorten the code in order to post it. But my code shows no error when building. we also tried the ex_slave, but it didn't work. Tnx
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 29, 2009 1:06 am     Reply with quote

Try Ex_Slave.c with the master code that I linked to. Also try running
the slave faster than the master. Run the slave at 8 MHz. Run the
master at 4 MHz. Your goal is to get something working.
Once you do that, you can then experiment. The easiest way is to
do what I suggest above. And make sure you have these connections:
Code:

Board #1     Board #2
SDA <-------> SDA
SCL <-------> SCL
Ground <----> Ground

There must be one pullup resistor on SDA line, and another pull-up
resistor on the SCL line. They can be 2.2K or 4.7K. They can be
on the slave board or the master board. Pick one. They must go
to the same Vdd voltage that powers the PIC (typically +5v).
Guest








PostPosted: Sat Jan 31, 2009 10:44 am     Reply with quote

Hi. I've tried most of what was said. it does not hang up anymore but unfortunately, the PICs can't still communicate with each other properly. One time, the LCD display "read []"
Note: ( [] <-- a filled box/undistinguishable char)

I have a feeling that the reason of the failure is due to my compiler version(version 4.016).

So here is now my question: If I bought a ICD2 package and that's where I get the installer for my ccs compiler, am I entitled to the upgrades?? (sorry if the question is at the wrong section/side)
n-squared



Joined: 03 Oct 2006
Posts: 99

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Jan 31, 2009 10:43 pm     Reply with quote

I suggest you add force_hw to the slave #use i2c statement.
_________________
Every solution has a problem.
Guest








Thanks
PostPosted: Sun Feb 01, 2009 9:57 pm     Reply with quote

Thank you , guys. I've managed to make it work. Thanks for your suggestion/advice. The solution was a mix of what you said and the compiler version!!!
Guest








PostPosted: Thu Feb 12, 2009 1:27 am     Reply with quote

PCM programmer wrote:
Also try running
the slave faster than the master. Run the slave at 8 MHz. Run the
master at 4 MHz.


hi, its me again, i'm wondering if i need to run the slave faster than the master if i'm storing 3 sets of array to the slave. although there are times it hangs up. I tried to put the debugger in the place of the slave and it wont enter the interrupt, wherein I place a breakpoint. Can you suggest a way to test if its working? tnx
master:
Code:

void i2cUpdate()  //Updates Changes in Modem Config & Modes
{
   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x41);
   for (ctr1=0;ctr1<5;ctr1++)
   {
      i2c_write(0x30 + modemConf[ctr1]);
   }
   for (ctr1=0;ctr1<2;ctr1++)
   {
      for (ctr2=0;ctr2<5;ctr2++)
      {
         i2c_write(0x30 + priority[ctr1][ctr2]);
      }
   }
   for (ctr1=0;ctr1<2;ctr1++)
   {
      i2c_write(0x30 + maxOn[ctr1]);
   }
   i2c_write(0x04);
   i2c_stop();
}



slave:
Code:

#if defined(__PCM__)
#include <16f877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#DEVICE *=16 ICD=TRUE ADC=8
#use Delay (Clock=8000000)
#use i2c (SLAVE, sda=PIN_C4, scl=PIN_C3, address=0xa0,force_hw)

short int SOT_i2c=0;
//int maxOn[2], modemConf[], priority[2][5];
int rcv[];
int ctr1;

#INT_SSP
void ssp_interrupt()
{
   int ch;
   ch = i2c_read(); // read from i2c
   output_D(ch);
   if ((ch == 0x41) && (SOT_i2c == 0))
   {
      SOT_i2c = 1;
      ctr1 = 0;
   }
   else if ((ch == 0x04) && (SOT_i2c == 1))
   {
      SOT_i2c = 0;
   }
   else
   {
      if (SOT_i2c == 1)
      {
         rcv[ctr1] = ch - 30;
         ctr1++;
      }
   }
}

void main ()
{
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   set_tris_d(0x00);
   set_tris_c(0xFF);
   while(TRUE)
   {
   }
}
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Feb 12, 2009 10:03 am     Reply with quote

It really doesn't matter what clock frequency you run each PIC at as long as the master code gives the slave time to do it's job.

When the master sends a command to the slave it takes a certain amount of time for the slave to react and process the command. The master must wait until the slave is ready to accept the next command. You can either have the slave pull the SCL line low, which will force the master to wait until the slave releases the SCL line, or you can put delays into your master code. An oscilloscope is very useful in determining the bus timing required.

Ronald
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