|
|
View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
problem with multiple I2C buses on 18F26J11 |
Posted: Sat Sep 18, 2010 6:40 pm |
|
|
I've reviewed the posts related to this problem but didn't see quite the description of the problem I'm having...
I have to use two I2C devices with the same bus address so I'm trying to create two I2C buses on a PIC18F26J11 as:
Code: |
#define SDA_PIN1 PIN_C4
#define SCL_PIN1 PIN_C3
#use i2c(MASTER, FAST, SDA=SDA_PIN1, SCL=SCL_PIN1, STREAM=BUS1)
#define SDA_PIN2 PIN_C1
#define SCL_PIN2 PIN_C0
#use i2c(MASTER, FAST, SDA=SDA_PIN2, SCL=SCL_PIN2, STREAM=BUS2)
|
When I tested with a program which called i2c_read(BUS1) and i2c_read(BUS2), the device on BUS1 responds correctly but accesses to the device on BUS2 locked up the system. I've exchanged the devices between buses to confirm the individual devices are acting correctly. BUS1 is on the hardware port. Does that have an influence on a software bus?
I have pullups on the SDA and SCL lines on each bus.
I'm using PCWHD version 4.112.
Thanks for any help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Sep 18, 2010 7:28 pm |
|
|
Quote: | When I tested with a program which called i2c_read(BUS1) and i2c_read(BUS2)
|
The CCS manual says:
Quote: |
I2C_read( )
Syntax:
data = i2c_read();
data = i2c_read(ack);
data = i2c_read(stream, ack);
|
This implies that if you specify a stream, then you must explicitly put in
the ACK/NACK parameter. You're not doing that, and it's probably the
cause of your problem. |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Sat Sep 18, 2010 10:00 pm |
|
|
Thanks for the reply.
I am using the ack and nack format as specified in the manual. Actually the part I am reading is an MCP3221 12-bit ADC so the code for reading the part on BUS2 is:
Code: |
// ---- read a value from the mcp3221 on bus 2 ----
long mcp3221_read2(void)
{
long data;
long tmp;
i2c_start(BUS2);
i2c_write(BUS2, MCP3221_RD_ADDR);
tmp = i2c_read(BUS2, 1);
tmp <<= 8;
data = i2c_read(BUS2, 0);
data |= tmp;
data &= 0xfff;
i2c_stop(BUS2);
return(data);
}
|
The reads include the stream and the ack/nack. This exact code works on BUS1 where the BUS2 values are changed for BUS1. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 19, 2010 1:58 pm |
|
|
I made the following test program, compiled it with vs. 4.112, and looked
at the .LST file code for each i2c stream, and they track. They only
differences in the ASM code are the pin numbers.
If you're getting a failure, you need to post a test program that shows it.
It may be something else you're doing, such as Wizard code or peripheral
pin remapping. I need a test program to see it.
Code: |
#include <18F26J11.h>
#fuses HS,NOWDT
#use delay(clock=4000000)
#define MCP3221_RD_ADDR 0x9B
#define SDA_PIN1 PIN_C4
#define SCL_PIN1 PIN_C3
#use i2c(MASTER, FAST, SDA=SDA_PIN1, SCL=SCL_PIN1, STREAM=BUS1)
#define SDA_PIN2 PIN_C1
#define SCL_PIN2 PIN_C0
#use i2c(MASTER, FAST, SDA=SDA_PIN2, SCL=SCL_PIN2, STREAM=BUS2)
//--------------------------------
long mcp3221_read1(void)
{
long data;
long tmp;
i2c_start(BUS1);
i2c_write(BUS1, MCP3221_RD_ADDR);
tmp = i2c_read(BUS1, 1);
tmp <<= 8;
data = i2c_read(BUS1, 0);
data |= tmp;
data &= 0xfff;
i2c_stop(BUS1);
return(data);
}
//---------------------------------
long mcp3221_read2(void)
{
long data;
long tmp;
i2c_start(BUS2);
i2c_write(BUS2, MCP3221_RD_ADDR);
tmp = i2c_read(BUS2, 1);
tmp <<= 8;
data = i2c_read(BUS2, 0);
data |= tmp;
data &= 0xfff;
i2c_stop(BUS2);
return(data);
}
//====================================
void main()
{
long result;
result = mcp3221_read1();
result = mcp3221_read2();
while(1);
} |
|
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Mon Sep 20, 2010 10:29 am |
|
|
Thanks very much for the response.
I copied your program into a new project and modified it with some serial interface to give me some runtime visibility and it worked perfectly! Both channels are working correctly.
I went back to my original program and looked for the problem. I found the problem in the #fuses where I was using a template program I had previously developed for testing the built in RTC functionality. The #FUSES RTCOSC_T1 and the call to setup_rtc(RTC_ENABLE, 0x00); in the main() program was the cause of the problem. The RTC is using the C0 and C1 lines which just happened to be the two lines I'd picked for BUS2!
My bad...
Thanks again... |
|
|
|
|
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
|