|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
help on i2c: hangs up i2c_write |
Posted: Wed Jan 28, 2009 9:20 pm |
|
|
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
|
|
Posted: Wed Jan 28, 2009 10:14 pm |
|
|
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
|
|
Posted: Thu Jan 29, 2009 12:47 am |
|
|
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
|
|
Posted: Thu Jan 29, 2009 12:54 am |
|
|
@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
|
|
Posted: Thu Jan 29, 2009 1:06 am |
|
|
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
|
|
Posted: Sat Jan 31, 2009 10:44 am |
|
|
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
|
|
Posted: Sat Jan 31, 2009 10:43 pm |
|
|
I suggest you add force_hw to the slave #use i2c statement. _________________ Every solution has a problem. |
|
|
Guest
|
Thanks |
Posted: Sun Feb 01, 2009 9:57 pm |
|
|
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
|
|
Posted: Thu Feb 12, 2009 1:27 am |
|
|
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
|
|
Posted: Thu Feb 12, 2009 10:03 am |
|
|
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 |
|
|
|
|
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
|