|
|
View previous topic :: View next topic |
Author |
Message |
Thomas Blake
Joined: 18 Jan 2004 Posts: 22 Location: Burbank CA
|
Multiple-master I2C with F87X |
Posted: Sun Jan 18, 2004 3:12 pm |
|
|
Wow, I go away for a mere year and they close my forum account.
Anyway - I need to use a 16F873 as the second master in an I2C system. (The other master is a different MCU that apparently makes I2C in software - I say that because of the irregular duty cycle of SCL.) The first trials have not gone so well. The i2c_start() function does not wait for the stop condition on the bus before attempting to communicate, so I have had to write a little assembler routine to check the P bit. No luck so far, although I'm still trying.
Just out of curiosity ... has anyone successfully implemented a multi-master system with the F87x, or am I blowing smoke? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Jan 18, 2004 8:30 pm |
|
|
Yes, we have a product that can use up to 18 devices. A word of warning to you. You cannot trust the start and stop bits when switching between master and slave. These bits are reset. BTW, I implemented the master in software. I didn't use any of the CCS functions so that I have complete control. |
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
multi master I2C |
Posted: Mon Jan 19, 2004 3:47 pm |
|
|
Mark,
thats a tempting answer, do you have any code you code post ? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Jan 19, 2004 3:59 pm |
|
|
The bit banging stuff is pretty easy and I could probably post that code. The isr routines are probably what would be of most use. Unfortunely, I think that if I posted them, they would confuse the people that would benefit from it. The devices communicate using the Access.bus specification. Actually a modified one. We included a checksum and an acknowlegement back (slave read). I don't think too many people are using this protocol to communicate so the receive isr's would be totally different. When I have some free time (ha, its never free), I will post a simple example but you can probably already find them on this board. |
|
|
tcb Guest
|
Sample code |
Posted: Mon Jan 19, 2004 9:00 pm |
|
|
Well, I'm going after it with AN735, the data sheet, and the Philips spec; if I succeed (and I have to do SOMETHING that works, or else), I'll put the code here. The PIC knows when the I2C has been stepped on - there's a flag in PIR2 that gets set when the bus is contended for. So I'm still going to try to use the hardware, which has performed very well in single-master situations. |
|
|
Thomas Blake
Joined: 18 Jan 2004 Posts: 22 Location: Burbank CA
|
Got it working |
Posted: Wed Feb 04, 2004 6:42 pm |
|
|
This turned out to be a bit more fussy than I thought, but I do have it working, using the MSSP hardware.
The original I2C master does seem to support arbitration properly. However, my new 2nd master (F873) hangs on repeated start every few hundred transactions. So I hooked up a scope and found places in the original data stream where stops are normally followed by idle bus for a few milliseconds. So I interrupt on stop, wait 100uS and test for stop again; if the state is till stop, I assume a space and drop my messages in.
Unfortunately, after going to all that trouble, the '873 still hangs the bus every few seconds, even though no contention is visible on the oscilloscope. So I took a hint from the MSSP errattum sheet (80131c.pdf) and disable the MSSP, then immediately enable it again, after each of my own datagrams. (But, the erratum was meant for MSSP used as a slave.) This works.
Sounds pretty messy and it is. But I'm really getting to like I2C; I'm not aware of any other commonly used bus that allows you just to drop in new control of existing devices with only a 2-wire connection and no reprogramming of the original controller. |
|
|
MikeW
Joined: 15 Sep 2003 Posts: 184 Location: Warrington UK
|
Multi-Master I2C |
Posted: Sat Feb 07, 2004 1:08 am |
|
|
please post your code when you are happy it works.
Mike |
|
|
Guest
|
Multi I2C |
Posted: Tue Jun 14, 2005 2:32 pm |
|
|
I have the PICDEMO 2 + board and I try to read the temperature (U5)and write it into the EEPROM U4(24LC256).
I got the temperature reading fine, but I kind of lost in writing the data to the EEPROM. I am totally lost...
My question is how to use 1 uP with multiple I2C devices? Please help...
Here is my code that I got from other member in this forum.
Code: |
#include <18f452.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(Master,fast,sda=PIN_C4, scl=PIN_C3, FORCE_HW)
//#include <PICDEM2_lcd2.c>
#include <lcda.c>
//*****************************************************************
main()
{
byte value,temp;
int16 bat_value;
float batt;
lcd_init();
setup_adc_ports( RA0_ANALOG );
setup_adc( ADC_CLOCK_INTERNAL );
while(1)
{
set_adc_channel( 0 );
delay_us(25);
bat_value = read_adc();
batt = bat_value * (float) 0.00488;
printf(lcd_putc,"\nBattery: %2.2f V",batt);
delay_ms(100);
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011010); // Address and Write Flag
i2c_Write(0x00); // Temperature Register
i2c_Start(); // Set a START condition I2C Bus
i2c_Write(0b10011011); // Address and Read Flag
value = i2c_Read(); // Read Teperature
i2c_stop();
delay_ms(5);
temp = value * 9/5 + 32;
printf(lcd_putc,"\fValue: %d Degree",temp);
}
}
|
Thanks in advance.. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 14, 2005 3:03 pm |
|
|
CCS has a driver for the 24LC256 eeprom. You don't have to do
that work all over again. The driver is called 24256.C and it's in
this folder: c:\Program Files\Picc\Drivers
Here is a short program that shows how to use the driver
to write to the 24LC256 eeprom:
Code: | #include <18F452.h>
#fuses XT, NOWDT, NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
// Tell the driver to use these pins for i2c:
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#include <24256.c> // This is the CCS EEPROM driver
//========================================
void main()
{
init_ext_eeprom();
write_ext_eeprom(0, 0x55);
while(1);
} |
The CCS driver uses software i2c by default. If you want to use
hardware i2c, you need to edit the #use i2c() statement in the 24256.C
file and add FORCE_HW to it. Example:
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL, FORCE_HW)
This requires that you use pin C4 for SDA and pin C3 for SCL, and
that is exactly how the PicDem2-Plus board is wired. |
|
|
Guest
|
EEPROM Block and Address |
Posted: Wed Jun 15, 2005 7:43 am |
|
|
Sorry for the basic question but I need some explaination..
I am new to EEPROM and PIC, after I read the previous post and some datasheet for 24LC01B and 24LC256 with I2C interface. The control byte or the device address always be 1010 for eeprom. Example the 24LC01 is a 1Kbit device.
The questions I have are,
1. How do I identify the block?
2. How do I identify the word address? (starting address like 0x00, 0x01, or what?)
3. How many blocks and how many word can it stores? Code: | void write_ext_eeprom(BYTE address, BYTE data) {
while(!ext_eeprom_ready());
i2c_start();
i2c_write(0xa0);
i2c_write(address); == > ??? what address do I need to start with?????
i2c_write(data);
i2c_stop();
}
BYTE read_ext_eeprom(BYTE address) {
BYTE data;
while(!ext_eeprom_ready());
i2c_start();
i2c_write(0xa0);
i2c_write(address); == > ??? what address do I need to start with?????
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
} |
I couldn't find the information on the 24LC01, 24LC256 datasheet.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 15, 2005 9:43 am |
|
|
Can you start a new thread for your topic ?
The reason is, this existing thread is about "Multi-Master i2c",
which is an advanced topic. You have newbie questions about
i2c Slave devices and eeproms, and it shouldn't be tacked onto
this thread. You should start a new thread. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Jun 15, 2005 5:11 pm |
|
|
Read the datasheets again. Its in there. I'll tell you this though. The 24c01 is a 128 byte device so the address will fit into an 8 bit variable. The code that you posted will work for that (if you use more than one of the 24C01's then you cannot hardcode 0xA0 as the address because you would need to address the other chips.) The larger memory devices do things a bit differently. Some look as though there are multiple chips connected and can therefore only have one per bus. You just have to read the datasheets to find out. |
|
|
|
|
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
|