|
|
View previous topic :: View next topic |
Author |
Message |
severo
Joined: 01 Feb 2013 Posts: 3
|
EEPROM and Mux i2c |
Posted: Tue Mar 12, 2013 11:52 am |
|
|
Greetings!
I am currently working on a project that involves the following ICs:
> DS2431 1024-Bit 1-Wire EEPROM (7 of them)
> DS2482-100 1-Wire to I²C converter (7 of them)
> PCA9547 8-channel I2C-bus multiplexer
> PIC18F46J11
What I want to do is the following: use the PIC to read the 7 EEPROMs with the I²C multiplexer.
The communication PIC -> Mux is working perfectly, I can easily select which channel I want.
I would like to know, how can I use CCS to my advantage when it comes down to reading, writing and programming the EEPROMs with I²C protocol?
Thanks! |
|
|
AndresRam
Joined: 27 May 2017 Posts: 16 Location: Colombia
|
Hi, please help |
Posted: Tue Dec 05, 2017 9:57 pm |
|
|
Hi, I am work in a PCA9548 and I have not been able to achieve communication between the pic and the mux.
Could you help me with this driver or code? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Dec 06, 2017 12:20 am |
|
|
You need to start one step at a time.
I2C bus on the PIC connecting to the SDA/SCL of the 9548.
Vcc/Vdd on the 9548 connected to the supply.
Pull-ups on the SDA/SCL to the PIC Vdd.
Connect the A0..A2 to Vss/Vdd to select an address for the multiplexer that does not clash with any of your target devices (0xE0 to 0xEE in steps of 2).
Then run the I2C bus scanner program from the code library and verify the device acknowledges on the correct address.
Then attach your first external device. Remember you need pull ups on this second bus as well. Each of the multiplexed buses needs it's own pull ups.
Write a byte to the device. You know it's address from the scanner test. The write is to the write address (even address of the pair the device sits on). You set the bit on the byte you write for the bus you want to use. So, assuming the bus you want is the first one, and the multiplexer is on 0xE0:
Code: |
#define MULTIPLEXER 0xE0 //write address for the chip
void enable_bus(int8 n)
{
int8 bus=0;
bit_set(bus,n); //set the bit for the bus we want to enable
i2c_start();
i2c_write(MULTIPLEXER); //talk to the multiplexer
i2c_write(bus); //turn on the selected bus
i2c_stop();
}
//so for the first bus:
enable_bus(0);
|
Your I2C bus will now be talking to bus 'n' on the device (0 to 7). Bus 0 called as shown.
So attach a device to this, and run the I2C scanner again, and see if you now get an acknowledgement from this.
Neat thing is the device can also act as a level converter. So (for instance) you can have a 5v PIC, talking to it (with the device powered off 5v and the PIC powered off 5v), and then attach the external bus to a device at 3.3v (with this bus pulled up to 3.3v), and the device will provide the multiplexing, and the level conversion at the same time. |
|
|
AndresRam
Joined: 27 May 2017 Posts: 16 Location: Colombia
|
problems with the PCA9548 |
Posted: Thu Dec 07, 2017 5:53 pm |
|
|
Thank you very much Ttelmah for the help. Only now can I return to the subject. I already have the electronic cards elaborated to be able to do the tests.
I have taken into consideration everything mentioned but I still can not obtain satisfactory values through PCA9548.
I decided to test it in Proteus the following: PIC18F47J53, PCA9548 and DS1307. The latter is an RTCC I2C and I want to connect it on channel 0 of PCA9548. (This is just to test the Mux.) I have taken into account all the pull up resistors that you said in your comment and the three addressing pins of PCA9548 are grounded therefore the address of PCA9548 is 0x70.
My code is as follows:
Code: | #include <18F47J53.h>
#device ADC=16
#use delay(clock=16000000,crystal=16000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_D6,rcv=PIN_D5,bits=8,stream=PRINTER)
#use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bits=8,stream=PRINTER)
#use i2c(Master,sda=PIN_B5,scl=PIN_B4)
#include <RTC_DS1307.C>
int dat_in, cnt, hr,min,sec;
int16 address=0;
int dat_serie[7];
float dato;
void main()
{
// enable_bus(0);
while(1)
{
delay_ms(1000);
tiempo(hr,min,sec); //Lee tiempo del DS1307
//ds1307_get_date(day,month,yr,dow);
//ds1307_get_time(hrs,min,sec);
//fprintf(PRINTER,"\f\%02d/\%02d/\%02d\r\n",day,month,yr);
//fprintf(PRINTER,"\%02d:\%02d:\%02d", hrs,min,sec);
fprintf(PRINTER,"%2u:%2u:%2u\r\n",hr,min,sec);
//TODO: User Code
}
} |
And the driver where I put your suggested code for the Mux (inside the DS1307 driver):
Code: | int BCDaBIN(int bcd){
int varia;
varia = bcd;
varia >>= 1;
varia &= 0x78;
return(varia + (varia >> 2) + (bcd & 0x0f));
}
#define MULTIPLEXER 0x70 //write address for the chip
void enable_bus(int8 n)
{
int8 bus=0;
bit_set(bus,n); //set the bit for the bus we want to enable
i2c_start();
i2c_write(MULTIPLEXER); //talk to the multiplexer
i2c_write(bus); //turn on the selected bus
i2c_stop();
}
void tiempo(byte &hor, byte &min, byte &sec){
enable_bus(0); //channel 0 of MUX
i2c_start(); //Escritura
//i2c_write(0x68);
i2c_write(0xD0); //Código de escritura
i2c_write(0x00); //Puntero a la primera dirección
//enable_bus(0);
i2c_start(); //Lectura
i2c_write(0xD1); //Código de lectura
sec = BCDaBIN(i2c_read()&0x7f); //Lectura de los 7bit de los segundos
min = BCDaBIN(i2c_read()&0x7f); //Lectura de los 7bit de los minutos
hor = BCDaBIN(i2c_read(0)&0x3f); //Lectura de los 7bit de las horas
i2c_stop();
} |
The only answer I get from the serial port is:
45:85:85
45:85:85
45:85:85
... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Dec 07, 2017 6:31 pm |
|
|
A real DS1307 requires a battery (coin cell) for it to run properly. That's somewhere in the DS1307 datasheet. Pin 3 is +bat, 4 is gnd, 1-2 xtal.
Got one in front of me running...
jay |
|
|
AndresRam
Joined: 27 May 2017 Posts: 16 Location: Colombia
|
|
Posted: Thu Dec 07, 2017 8:26 pm |
|
|
Thanks temtronic.
I first test the driver of the DS1307 connected directly to the microcontroller and everything works ok. To simulate it in Proteus I do not require crystal or coin cell battery. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Fri Dec 08, 2017 2:35 am |
|
|
Whoa. You do not put the stuff to talk to the second chip inside the multiplexer function.
You switch the multiplexer, finish the transaction to this, and then talk to the RTC as separate operations afterwards.
Also forget 0x70. You have the chip on 0xE0.
Texas use 7 bit I2C addresses. Just about everyone else uses 8 bit.
A Texas address of 0x70 is a PIC address of 0xE0 for write and 0xE1 for read. You have to multiply the address by two when sending it.
Use the enable bus function as I posted it.
Then once the bus is switched, call the standard RTC functions. |
|
|
|
|
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
|