CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

problem with write/read external eeprom 2408

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rald



Joined: 04 Sep 2013
Posts: 25

View user's profile Send private message

problem with write/read external eeprom 2408
PostPosted: Fri Mar 27, 2015 1:46 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 2:14 pm     Reply with quote

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


Quote:
#include <2408.C>

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 3:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 5:06 pm     Reply with quote

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:
Code:
address = 0;
rald



Joined: 04 Sep 2013
Posts: 25

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 5:29 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 5:45 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 5:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 6:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Mar 28, 2015 5:25 am     Reply with quote

Agreed.

I think it is the low output impedance of the USB drivers that they find difficult.
rald



Joined: 04 Sep 2013
Posts: 25

View user's profile Send private message

PostPosted: Mon Mar 30, 2015 1:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Mar 30, 2015 1:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Mar 30, 2015 2:15 pm     Reply with quote

One obvious thing. What is the maximum clock rate the 2408 EEPROM supports on I2C?.....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Mar 30, 2015 3:14 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Mar 31, 2015 6:16 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Apr 01, 2015 2:23 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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