![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
srikala
Joined: 23 Mar 2020 Posts: 9
|
EEPROM and 18f27k42 write and read error |
Posted: Sat Mar 28, 2020 4:18 am |
|
|
Need help on I2c EEPROM (24lc256) and 18f27k42, code gets hanged at "write_ext_eeprom()" and if commented the write function, the value read thru read_ext_eeprom() is default 255. I tried all possible ways no luck.
Code: |
#include <18f27k42.h>
#fuses HS,WDT,NOPROTECT,BROWNOUT
#use delay(clock=20000000,RESTART_WDT)
#pin_select U1RX=PIN_C7
#pin_select U1TX=PIN_C6
#USE RS232(UART1,baud=9600,xmit=pin_C6,rcv=pin_C7,bits=8,stop=1,parity=n,errors)
#PIN_SELECT SCL1IN = PIN_C1
#PIN_SELECT SCL1OUT = PIN_C1
#PIN_SELECT SDA1IN = PIN_C2
#PIN_SELECT SDA1OUT = PIN_C2
#use i2c(Master,Slow,I2C1,FORCE_SW)
unsigned int16 value=0, value1=0;
#include<2X16LCD.c> //LCD display
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 32768
void init_ext_eeprom()
{
output_float(pin_c1);
output_float(pin_c2);
}
#separate
void write_ext_eeprom(long int address, unsigned int data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
}
unsigned int read_ext_eeprom(long int address) {
unsigned data;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}
void main(void)
{
init_ext_eeprom();
delay_ms(50);
while(True)
{
delay_ms(5000);
putc(value);
value=value+1;
putc(value1);
delay_ms(100);
putc(value);
write_ext_eeprom(1, 6);
delay_ms(100);
value1=read_ext_eeprom(1);
putc(value1);
}
}
|
Above code gives result as 000 000 001 and hangs.
If write_ext_eeprom(1, 6); is commented result as
000 000 001 255
001 255 002 255
002 255 003 255
Value is incremented but value1 read from ext eeprom is default 255.
seems bot write and read are not working. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sat Mar 28, 2020 4:57 am |
|
|
First start with the I2C scanner program in the code library and verify
that the chip is being seen at address 0xA0/A1. You need A0, 1 & 2 pulled
low for this to be the case.
WP also needs to be pulled low.
You have got pull up resistors on the I2C lines?.
Then 255, is the default value for an empty EEPROM.
On your code, you don't need the I2C_stop when doing a 'restart'.
Verify the chip is physically being seen with the bus scanner first. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9176 Location: Greensville,Ontario
|
|
Posted: Sat Mar 28, 2020 5:04 am |
|
|
Mr T beat me to posting !
I'll add...
WHAT value are the I2C pullup resistors ?
Typically they might be 3k3 for 3V VDD, 4k7 for 5 volt VDD.
Running the I2C scanner program is the FIRST program to run, it'll verify the base address of the EEPROM. |
|
![](templates/subSilver/images/spacer.gif) |
srikala
Joined: 23 Mar 2020 Posts: 9
|
|
Posted: Sat Mar 28, 2020 7:30 am |
|
|
Hi, Ttelmah
The 24lC256 PIN No's 1,2,3 are short with Pin 4 (GND/VSS) i.e A0, A1 & A2 are pulled low.
Pin No. 7, i.e WP pin, is also grounded.
temtronic,
Pin no.'s 5 & 6 i.e SCL and SDA are pulled up with 4.7K to 3.3V VDD and voltages at VDD - 3.319, SCL & SDA - 3.320.
I need to test the I2C scanner code. |
|
![](templates/subSilver/images/spacer.gif) |
srikala
Joined: 23 Mar 2020 Posts: 9
|
|
Posted: Sat Mar 28, 2020 8:12 am |
|
|
I run the below code and didn't find the address, is the program bug free ?
Code: | #include <18f27k42.h>
#fuses HS,WDT,NOPROTECT,BROWNOUT
#use delay(clock=20000000,RESTART_WDT)
#pin_select U1RX=PIN_C7
#pin_select U1TX=PIN_C6
#USE RS232(UART1,baud=9600,xmit=pin_C6,rcv=pin_C7,bits=8,stop=1,parity=n,errors)
#PIN_SELECT SCL1IN = PIN_C1
#PIN_SELECT SCL1OUT = PIN_C1
#PIN_SELECT SDA1IN = PIN_C2
#PIN_SELECT SDA1OUT = PIN_C2
#use i2c(Master,Slow,I2C1,FORCE_SW)
#include<input.c>
#include<stdlib.h>
void main(void)
{
unsigned int8 i;
unsigned int8 status;
while(True)
{
for(i=0x10; i < 0xF0; i+=1)
{
i2c_start();
status = i2c_write(i); // Status = 0 if got an ACK
i2c_stop();
delay_ms(100);
if(status == 0)
printf("EPROM Addr: %X\n\r", i);
else
printf("EPROM Not Found\n\r");
}
}
} |
I changed the IC and board also and not able to find the address. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sat Mar 28, 2020 8:13 am |
|
|
4K7 is a bit high for 3.3v.
If the wire length is at all significant, you might get rise time problems
with a resistor this large.
With 4K7, and 3.3v, you will exceed the maximum slew time, for a bus total
capacitance of just 70pF.... |
|
![](templates/subSilver/images/spacer.gif) |
srikala
Joined: 23 Mar 2020 Posts: 9
|
|
Posted: Sun Mar 29, 2020 1:32 am |
|
|
changed 4.7K to 3.3K on SCL and SDA lines, didn't get the address with above I2C scanner code. checked with two different boards.
when replaced Code: | #use i2c(Master,Slow,I2C1,FORCE_SW) |
with Code: | #use i2c(Master, I2C1) |
for every address received a ACK, i.e for every address in I2C_Write(address) received status = 0. didn't understand is it correct or error ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sun Mar 29, 2020 2:05 am |
|
|
First thing is to correct the code.
You can't specify a hardware I2C port and then say FORCE_SW.
Selecting the hardware port is equivalent to specifying FORCE_HW,
so you are saying force to both hardware & software ports at the same
time....
So change your I2C setup to:
Code: |
//for software
#use i2c(MASTER, SLOW, SCL=PIN_C1, SDA=PIN_C2, FORCE_SW)
|
I'm wondering if the 'crossed' setup is resulting in incorrect configuration.
Yes, PCM_Programmer's code does work. So get this working first.
Change the I2C setup, and see if you can get the chip just seen on it's
correct address.
Now the chip your are using is one that has the I2C peripheral, instead
of the MSSP. This is a different peripheral, and if you want to use hardware
you would need to use I2C_Transfer, rather than the I2C_Start, stop etc..
The peripheral in hardware does not support doing separate I2C
operations. In fact if the hardware was correctly configured, the
compiler should warn you that I2C_Start, stop etc, is not supported
when using the hardware I2C on this device. That it is not giving you
this warning, 'screams' that the port is not correctly configured. |
|
![](templates/subSilver/images/spacer.gif) |
srikala
Joined: 23 Mar 2020 Posts: 9
|
|
Posted: Sun Mar 29, 2020 5:58 am |
|
|
Thank you Ttelmah.
Code: |
#use i2c(MASTER, SLOW, SCL=PIN_C1, SDA=PIN_C2, FORCE_SW) |
It worked. It's issue with my #use I2C usage.
Now my EEPROM code also works. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Sun Mar 29, 2020 6:09 am |
|
|
Good.
When you posted that you had tried to use:
use i2c(Master, I2C1)
and the compiler had not complained, I realised the setup must be the
cause of the problem (since on this chip this would not allow, the 'standard'
I2C functions to be used).
In fact on the current compilers if you used this it would error on the
compile, telling you that you need to use I2C_Transfer.
Glad it is working now. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 29, 2020 7:29 am |
|
|
srikala wrote: |
it works its issue with my #use I2C usage.
Now my EEPROM Code also works.
|
Can you tell us what your CCS compiler version is ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19375
|
|
Posted: Mon Mar 30, 2020 12:54 am |
|
|
PCM is asking, since he reports that the compiler does seem to be correctly
setting up software I2C in this case, on the current compiler.
I've taken the time to investigate what happens when you setup
the I2C using FORCE_SW and the PPS like this.
The compiler is 'smart' (at the start), and recognises what pins you
have selected with PPS. It then recognises that you have said 'FORCE_SW',
and correctly sets up software I2C on the requested PINs. Sounds good.
This is what PCM_Programmer was seeing.
However it still leaves the PPS selections 'made'.
If you look at section 17-2 of the manual 'PPS Outputs', you see:
Quote: |
Peripherals that control the
pin output driver as part of the peripheral operation will
override the TRIS control as needed. These
peripherals include:
• UART I2C
|
The I2C hardware being enabled, therefore stops the TRIS operation
needed for the software driver.
So though the compiler tries to meet the conflicting demands being put on it
here, it fails, so the software port doesn't work....
So general comment, if you want to use software I2C, set it up with the
pin names, not by referencing the hardware port.
Quite nice to know what is actually happening. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
srikala
Joined: 23 Mar 2020 Posts: 9
|
|
Posted: Thu Apr 02, 2020 11:59 pm |
|
|
hi, PCM_Programmer
sry for delay response its 5.076. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|