View previous topic :: View next topic |
Author |
Message |
rald
Joined: 04 Sep 2013 Posts: 25
|
problem with write/read external eeprom 2408 |
Posted: Fri Mar 27, 2015 1:46 pm |
|
|
Hello experts,
I have tried to read and write an external eeprom, I have read all examples and info found in this forum and net. I have 2 resistor pull up into to eeprom SDL and SDA but nothing.
Code: | #include <18F2450.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PLL1 //No PLL PreScaler
#FUSES CPUDIV1 //No System Clock Postscaler
#FUSES NOUSBDIV //USB clock source comes from primary oscillator
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOVREGEN //USB voltage regulator disabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=12000000)
#define LED PIN_A1
#define DELAY 1000
#use rs232(baud=9600,parity=N,xmit=pin_c6,rcv=pin_c7,bits=8,stream=PORT1)
#include <2408.C>
void main()
{
setup_timer_2(T2_DIV_BY_1,67,1); //22.7 us overflow, 22.7 us interrupt
setup_ccp1(CCP_PWM);
set_pwm1_duty((int16)0);
EEPROM_ADDRESS address;
init_ext_eeprom();
//Example blinking LED program
int x, d;
int16 contador;
for(x=0;x<=3;x++){
output_low(LED);
delay_ms(DELAY);
output_high(LED);
delay_ms(DELAY);
}
contador = 0;
delay_ms(6000);
printf("conectado\r\n");
while(true){
d = read_ext_eeprom(address);
printf("valor guardado: %X\r\n", d);
//set_pwm1_duty(d);
delay_ms(100);
}
}
|
if anyone can tell me what is wrong this this please. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 2:14 pm |
|
|
Quote: | EEPROM_ADDRESS address;
d = read_ext_eeprom(address);
|
The variable 'address' is never initialized.
Quote: | I have tried to read and write an external eeprom |
Your program doesn't write to the eeprom. You can preset values
in eeprom with your ICD programmer. See this example:
http://www.ccsinfo.com/forum/viewtopic.php?t=53671&start=2
This driver expects you to use Pin C4 for SDA and pin C3 for SCL.
Are you doing that ? Pullups should be 4.7K ohms (4700).
Run this i2c bus scanner program in your PIC. See if it finds the eeprom chip:
http://www.ccsinfo.com/forum/viewtopic.php?t=49713 |
|
|
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Fri Mar 27, 2015 3:07 pm |
|
|
hi,
yes sorry this program just read the eeprom, I "wrote" a small wav file into this eeprom 2408, but does not read it.
I test with your program recommendation however did not work either. just print start then nothing more.
I changed the pull up resistor to 4.7K but nothing... here is the test program. Code: | #include <18F2450.h>
#device adc=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PLL1 //No PLL PreScaler
#FUSES CPUDIV1 //No System Clock Postscaler
#FUSES NOUSBDIV //USB clock source comes from primary oscillator
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOVREGEN //USB voltage regulator disabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#use i2c(Master, sda=PIN_C4, scl=PIN_C5)
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
int8 get_ack_status(int8 address){
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0)
return(TRUE);
else
return(FALSE);
}
//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;
delay_ms(10000); //linea de tiempo
printf("\n\rStart:\n\r");
delay_ms(1000);
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status = get_ack_status(i);
if(status == TRUE)
{
printf("ACK addr: %X\n\r", i);
count++;
delay_ms(2000);
}
}
if(count == 0)
printf("\n\rNothing Found");
else
printf("\n\rNumber of i2c chips found: %u", count);
while(1);
} |
what do you mean with no starting EEPROM_ADDRESS?
any other idea? please this is urgent....
thanks so mucho |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 5:06 pm |
|
|
Quote: |
I test with your program recommendation however did not work either.
just print start then nothing more.
|
Check your connections to the 2408 eeprom:
Pins 1, 2, 3, 4, and 7 should all connect to ground.
Pin 8 should connect to +5 volts.
Pins 5 and 6 should connect to pullups and to the PIC as shown below:
Code: |
+5v
|
<
> 4.7K
<
To PIC | To eeprom
pin C4 ------------------ SDA pin 5
(SDA)
+5v
|
<
> 4.7K
<
To PIC | To eeprom
pin C3 ------------------ SCL pin 6
(SCL)
|
Wait a minute. What is this ?
Quote: | #use i2c(Master, sda=PIN_C4, scl=PIN_C5) |
Is that how your board is wired ? Do you really have SCL on pin C5 ?
Quote: | delay_ms(10000); //linea de tiempo |
What's the purpose of this 10 second delay at the beginning of the program ?
Quote: | what do you mean with no starting EEPROM_ADDRESS? |
You didn't set 'address' to any value. If you want to read the contents
of the eeprom at address 0, then you need to set it. Example:
|
|
|
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Fri Mar 27, 2015 5:29 pm |
|
|
Hi PCM,
yes the connectivity is the same that you are mentioning for 24C08 and about the pins from the pic are C5 and C4, I am using PIC18F2450 does not have I2C hardware everything is for software.
about 10 secs waiting instruction is because I am using bluetooth RS232 to communicate with my laptop.
about the resistors, yes those are 4.7Kohms.
what is rare for me is the hyperterminal only appears "start" and then nothing like the PIC is waiting for something...
any idea?
thanks so much.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 5:45 pm |
|
|
Pins C4 and C5 can't be used for software i2c on the 18F2450.
These pins are digital input only. They can't be digital outputs.
This is the reason why nothing works.
You need to use two other pins. |
|
|
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Fri Mar 27, 2015 5:52 pm |
|
|
Dude you are a genius!!!!!!
now is working... thanks...
can you explain why those ports can't be used?
thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 27, 2015 6:23 pm |
|
|
It's by design, at Microchip. Look at this table in the 18F2450 data sheet
which lists pins C4 and C5 as digital input only.
Quote: | TABLE 1-2: PIC18F2450 PINOUT I/O DESCRIPTIONS (CONTINUED) |
With regard to the reason for this, I think it may be because the chip
designers at Microchip can't easily (or a low cost), design a multiplexer
circuit that can switch between CMOS output levels and the low voltage
differential output levels used by USB. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Mar 28, 2015 5:25 am |
|
|
Agreed.
I think it is the low output impedance of the USB drivers that they find difficult. |
|
|
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Mon Mar 30, 2015 1:40 pm |
|
|
hi PCM,
I hope you can help me with this one. I wrote this code what it does is read the ADC and save the data into the eeprom, I can't save anything and I dont know why Code: |
#include <18F2450.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES PLL1 //No PLL PreScaler
#FUSES CPUDIV1 //No System Clock Postscaler
#FUSES NOUSBDIV //USB clock source comes from primary oscillator
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOVREGEN //USB voltage regulator disabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOLPT1OSC //Timer1 configured for higher power operation
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOSTVREN //Stack full/underflow will not cause reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(clock=12000000)
#use rs232(baud=9600,parity=N,xmit=pin_c6,rcv=pin_c7,bits=8,stream=PORT1)
#use I2C(master, scl=PIN_B0, sda=PIN_B1, fast=450000)
#include <2408.C>
#define boton input(pin_b7)
#define boton2 input(pin_b6)
#define led pin_a1
#define on output_high
#define off output_low
void main()
{
setup_timer_2(T2_DIV_BY_1,67,1); //22.7 us overflow, 22.7 us interrupt
setup_ccp1(CCP_PWM);
set_pwm1_duty((int16)0);
init_ext_eeprom();
//Example blinking LED program
int x, valor;
int16 address;
for(x=1;x<=3;x++){
on(led);
delay_ms(1000);
off(led);
delay_ms(1000);
}
address = 0x01;
while(true){
if (boton == 1){
while(address <= 0x400){
on(led);
set_adc_channel(0);
valor = read_adc();
delay_ms(10);
write_ext_eeprom(address, valor);
set_pwm1_duty(valor);
address = address + 0x01;
}
}else{
off(led);
}
address = 0x01;
if(boton2 == 1){
while(address <= 0x400){
on(led);
valor = read_ext_eeprom(address);
address = address + 0x001;
delay_ms(10);
set_pwm1_duty(valor);
}
}else{
off(led);
}
}
} |
I dont know what is wrong, I am using 4.7K resistor. pins 1, 2, 3 & 7 it matters? or something wrong with my code?
I thanks your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 30, 2015 1:47 pm |
|
|
You shouldn't address this question just to me. I have an appointment
I have to go to this afternoon and won't be back for a while. Perhaps
others can help you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Mon Mar 30, 2015 2:15 pm |
|
|
One obvious thing. What is the maximum clock rate the 2408 EEPROM supports on I2C?..... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 30, 2015 3:14 pm |
|
|
I am back from my appointment. In addition to what Ttelmah said,
Quote: | pins 1, 2, 3 & 7 it matters? |
yes it matters. Those pins should be connected to ground.
And, you are missing calls to these two functions to setup the ADC:
setup_adc_ports()
setup_adc()
You need to give those functions the appropriate parameters, as listed
in the 18F2450.h file, in the ADC section. |
|
|
rald
Joined: 04 Sep 2013 Posts: 25
|
|
Posted: Tue Mar 31, 2015 6:16 pm |
|
|
Hello everyone,
Thanks for all your help, I have fixed all recommendations.
Now I can save info into the eeprom but something interesting is happening, I am converting the ADC and save it into the eeprom however I just can hear random bits saved into the eeprom... I think that is related with the sample speed or the eeprom read speed, do you know how can I calculate this?
thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Apr 01, 2015 2:23 am |
|
|
You are approaching things rather the wrong way.
Forget about the EEPROM.
Make a nice simple serial connection to your PIC, get your ADC reading, and send that reading to the serial. Only once you have a reliable reading, think about saving this.
However then there is another worry. You start talking about speed. EEPROM's are not fast. It takes several mSec to save a reading to EEPROM, and worse if you try doing this quickly (saving multiple readings), you will kill the EEPROM very fast indeed. EEPROM's are designed to store things that only change occasionally. Not things that are changed at all quickly. Your EEPROM takes 10mSec to save a single byte. Write to it at this speed, and it'll be dead in 1000 seconds.
For things that change repeatedly, this is _not_ the device to use. |
|
|
|