View previous topic :: View next topic |
Author |
Message |
ivanperino
Joined: 08 Jun 2006 Posts: 14
|
I2C on 16F88 fast and slow |
Posted: Tue Aug 08, 2006 8:47 am |
|
|
I have implemented I2C over 16F88 PIC and a 24LC1025 memory. This memory works up to 400KHz clock rate with a 2K resistor but...
When I configure the #USE I2C(master, sda=PIN_B1, scl=PIN_A6, fast) line with the fast option, it doesnt work fast, it keeps working at the same clock rate than before (without fast option).
I have tryed with the slow option and I have obtained the same result!
I could watch the clock on the osciloscope and it is 64Khz aproximately (16uS)
I am using internal clock #FUSE INTRC_IO and delay(8000000)
I understand that I should read the memory faster. What do you think I can do?
this forum has helped me a lot. I thank you a lot.
I am sorry for my english wich is not so good.
IVAN periNO |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 08, 2006 10:21 am |
|
|
Try it again, but put the speed into the FAST statement, as shown
below.
Code: | #USE I2C(master, sda=PIN_B1, scl=PIN_A6, FAST=400000) |
If that doesn't work, then post your compiler version. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 09, 2006 3:38 pm |
|
|
The reason it doesn't work any faster is because you're using software i2c.
The compiler requires a minimum number of instruction cycles to do
one i2c clock cycle. It takes approximately 28 cycles. With the 8 MHz
internal oscillator in the 16F88, this is 14 us. So the maximum clock
frequency will be approximately 71 KHz. It doesn't matter if you set
"FAST=400000". The compiler can't create a software i2c loop that
will run at that speed, as long as your clock is only 8 MHz.
If you use a 20 MHz crystal, the i2c clock speed will increase but you still
won't get 400 KHz. The 16F88 doesn't have a MSSP module (only a SSP),
so it can't do a hardware Master. It can only do a hardware slave.
So with this PIC you are really limited in the maximum i2c clock speed.
To get faster speed you would have to use hardware i2c and choose a
PIC that has an MSSP module. |
|
|
gs
Joined: 22 Aug 2005 Posts: 30 Location: Ioannina - Greece
|
|
Posted: Sun Nov 26, 2006 5:45 pm |
|
|
I would like to ask you something about the 24LC1025 driver.
Have you modified the 24512 file? If yes, what modifications have you made? do you have access above address 65535?
That's the 16bit limit I cant get over. If you solved this problem I would apprieciate your help.
PS. Sorry for my bad english, The time is also past midnight here.... _________________ www.hlektronika.gr |
|
|
ivanperino
Joined: 08 Jun 2006 Posts: 14
|
Well |
Posted: Sun Nov 26, 2006 5:58 pm |
|
|
First. Do you speak spanish? It is my native language.
I could access to the others 64Kb of 241025 memory I2C. I am going to answer you on tuesday and I will send you part of the modified code. I am proud for helping somebody!
Ivan Perino from Argentina-
gs wrote: | I would like to ask you something about the 24LC1025 driver.
Have you modified the 24512 file? If yes, what modifications have you made? do you have access above address 65535?
That's the 16bit limit I cant get over. If you solved this problem I would apprieciate your help.
PS. Sorry for my bad english, The time is also past midnight here.... |
|
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Nov 26, 2006 10:12 pm |
|
|
Quote: |
That's the 16bit limit I cant get over. If you solved this problem I would apprieciate your help.
|
I didnīt try it because I doesnīt have the device, but this should be the way.
The 24LC1025 stores 1024k bits, or 128k bytes. I think that you should use it as
two 24512 chips (64K), so the following definitions are still valid:
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 65535
I would define two Banks Select for R/W operations:
#define W_BANK_L 0xa0
#define W_BANK_H 0xa8
#define R_BANK_L 0xa1
#define R_BANK_H 0xa9
To access the lower block of memory (< 64K ) the first byte following the
Start condition for a write operation should be:
i2c_start();
write(W_BANK_L);
i2c_write(address>>8);
i2c_write(address);
.....................
To access the upper block of memory (> 64K ) the first byte following the
Start condition for a write operation should be:
i2c_start();
write(W_BANK_H);
i2c_write(address>>8);
i2c_write(address);
......................
Humberto |
|
|
gs
Joined: 22 Aug 2005 Posts: 30 Location: Ioannina - Greece
|
|
Posted: Mon Nov 27, 2006 10:08 am |
|
|
Thank you all for your answers.
First I dont speak spanish. Greek is my native language.
The truth is that I solved the problem late last night (about 4:30 night) and I was too tired to post here.
So the problem was not in software but in hardware. I had all the 3 address pins grounded (because I used 24256 before) but the 241025 needs pin3 (A2) tied to VCC.
About the code i used a register to keep the controlbyte.... If you think we can improve it someway, just post and I will test it.
Code: | // 24xx256 Edited by gsmaster 16/11/2006 for 24xx1025
///////////////////////////////////////////////////////////////////////////
#define EEPROM_ADDRESS int32
#define EEPROM_SIZE 131071
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(int32 address, BYTE data)
{
short int status;
int controlbyte;
//
if (address>65535)controlbyte=0xa8;
else controlbyte=0xa0;
//
i2c_start();
i2c_write(controlbyte);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(controlbyte);
while(status==1)
{
i2c_start();
status=i2c_write(controlbyte);
}
}
BYTE read_ext_eeprom(int32 address) {
BYTE data;
int controlbyte;
//
if (address>65535)controlbyte=0xa8;
else controlbyte=0xa0;
//
i2c_start();
i2c_write(controlbyte);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(controlbyte+1);
data=i2c_read(0);
i2c_stop();
return(data);
} |
Humberto alternatively we can use addressing to access the both 512 chips, if A1 and A0 grounded, the microcontroller thinks there are two 512 chips at address 0 and 4.
I wanted the microcontroller to use the two blocks as one so your way was not my way. Anyway thank you all for the help. _________________ www.hlektronika.gr |
|
|
Redpic
Joined: 18 Dec 2005 Posts: 5 Location: Spain
|
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Thu Apr 02, 2009 11:15 pm |
|
|
gs wrote: | Code: |
void write_ext_eeprom(int32 address, BYTE data)
{
// ...
while(status==1)
{
i2c_start();
status=i2c_write(controlbyte);
}
} |
|
Hi gs,
Just $0.02. Wouldn't i2c_stop() be useful after the i2c_write? It looks like your function will leave the EEPROM in an addressed state ready to receive the next I2C transaction (may be even for some other slave) and store the random contents at random address?
- Nick _________________ Read the label, before opening a can of worms. |
|
|
|