Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

EEPROM write and read problem (PIC)

Status
Not open for further replies.

rezaf

Advanced Member level 4
Joined
Apr 11, 2009
Messages
106
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,298
Location
Montagram
Activity points
2,147
Hi,
I have problem for write and read to/from 25LC256 SPI EEPROM with PIC MCU. Please review my code for mistakes(the crystal oscillator of PIC is 25MHz).

Code:
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
        Delay_ms(100);
 do{
        buffer1 = 0;

        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS1 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_idle) 
            break;
          CS = 1;
          Delay_ms(200);
        }while(1);

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRSR);                //WRSR
        SPI1_Write(RDSR_idle);                //unprotecting
        CS = 1;
        Delay_ms(200);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
     
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS2 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready)
           break;
          CS = 1;
          Delay_ms(400);
        }while(1);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRITE);               //WRITE
        SPI1_Write(ipn1MSB);                  //ADDRESS  MSB
        SPI1_Write(ipn1LSB);                  //          LSB
        SPI1_Write(0b11000100);               //Data
        CS = 1;                               //Deactivate CS
        Delay_ms(2000);

        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS3 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
  

        CS = 0;
        Delay_ms(200);                          //Activate CS
        SPI1_Write(COMM_READ);                  //READ
        SPI1_Write(ipn1MSB);                    //ADDRESS  MSB
        SPI1_Write(ipn1LSB);                    //          LSB
        buffer1 = SPI1_Read(buffer);           //Data
        CS = 1;                                 //Deactivate CS
        Delay_ms(200);
        
        UART1_Write_Text("buf : \n");
        IntToStr(buffer1, buffer2);
        UART1_Write_Text(buffer2);
        UART1_Write_Text("\n");

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
        
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS4 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRDI);                //WRDI
        CS = 1;
        Delay_ms(200);

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRDI);                //WRDI
        CS = 1;
        Delay_ms(200);
   
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS5 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_idle) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
        UART1_Write_Text("\n");

the result in Serialcom software(RS232 port) : (the status register is always correct but the read data is always 2 instead of 196)
TS1 : 0
TS2 : 2
TS3 : 2
buf :
2
TS4 : 2
TS5 : 0

Thanks,
Best Regards.
 

Are you using mikroC Pro? Post the full project files and proteus file if you have.

The problem is your do {

}while(1) loops

You have so many of them, try to have only I such loop, otherwise the code will be running in just one of such do... while loops.

Only this code gets executed i.e., the first do...while(1) loop inside the main do... while(1) loop

Code:
do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS1 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_idle) 
            break;
          CS = 1;
          Delay_ms(200);
        }while(1);

the other code will not be executed and the code will be running in the above do... while(1) loop forever.

Did you see this link? http://www.mikroe.com/forum/viewtopic.php?t=14634

Have you enabled A0-A2 i.e., chip select?
 
Last edited:

Please Note that the if .... break will break the loop if TEST_result1 == 0b00000000 .yes I use mikroc pro but because of the EEPROM is one part of my project I insert related codes. I doubt that the routines to write and read the eeprom have problem or spi configurations.

Code:
#define CS RD0_bit
unsigned short COMM_WREN = 0b00000110;           //Commands
unsigned short COMM_WRDI = 0b00000100;
unsigned short COMM_RDSR = 0b00000101;
unsigned short COMM_WRSR = 0b00000001;
unsigned short COMM_READ = 0b00000011;
unsigned short COMM_WRITE = 0b00000010;

unsigned short ipn1MSB = 0b00000000;         //Addresses
unsigned short ipn1LSB = 0b00000000;
unsigned short ipn2MSB = 0b00000000;
unsigned short ipn2LSB = 0b00000000;
unsigned short ipn3MSB = 0b00000000;
unsigned short ipn3LSB = 0b00000000;
unsigned short ipn4MSB = 0b00000000;
unsigned short ipn4LSB = 0b00000000;

unsigned short RDSR_idle = 0b00000000;
unsigned short RDSR_ready = 0b00000010;
unsigned short RDSR_busy = 0b00000011;
unsigned short TEST_result1 = 255;
char TEST_result2[7];
unsigned int buffer1;
char buffer2[7];

SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
        Delay_ms(100);
 do{
        buffer1 = 0;

        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS1 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_idle) 
            break;
          CS = 1;
          Delay_ms(200);
        }while(1);

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRSR);                //WRSR
        SPI1_Write(RDSR_idle);                //unprotecting
        CS = 1;
        Delay_ms(200);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
     
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS2 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready)
           break;
          CS = 1;
          Delay_ms(400);
        }while(1);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRITE);               //WRITE
        SPI1_Write(ipn1MSB);                  //ADDRESS  MSB
        SPI1_Write(ipn1LSB);                  //          LSB
        SPI1_Write(0b11000100);               //Data
        CS = 1;                               //Deactivate CS
        Delay_ms(2000);

        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS3 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
  

        CS = 0;
        Delay_ms(200);                          //Activate CS
        SPI1_Write(COMM_READ);                  //READ
        SPI1_Write(ipn1MSB);                    //ADDRESS  MSB
        SPI1_Write(ipn1LSB);                    //          LSB
        buffer1 = SPI1_Read(buffer);           //Data
        CS = 1;                                 //Deactivate CS
        Delay_ms(200);
        
        UART1_Write_Text("buf : \n");
        IntToStr(buffer1, buffer2);
        UART1_Write_Text(buffer2);
        UART1_Write_Text("\n");

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WREN);                //WREN
        CS = 1;
        Delay_ms(200);
        
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS4 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_ready) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
        
        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRDI);                //WRDI
        CS = 1;
        Delay_ms(200);

        CS = 0;
        Delay_ms(200);
        SPI1_Write(COMM_WRDI);                //WRDI
        CS = 1;
        Delay_ms(200);
   
        do                                  //test status
        {
          CS = 0;                           //Activate CS
          Delay_ms(200);
          SPI1_Write(COMM_RDSR);            //RDSR
          TEST_result1 = SPI1_Read(buffer);
          ShortToStr(TEST_result1, TEST_result2);
          UART1_Write_Text("TS5 : ");
          UART1_Write_Text(TEST_result2);
          UART1_Write_Text("\n");
          if(TEST_result1 == RDSR_idle) break;
          CS = 1;
          Delay_ms(200);
        }while(1);
        UART1_Write_Text("\n");
 

You have to write 2 bytes that is Hi(e_addr); and Lo(e_addr); to the eeprom. Are you doing that? Did you see the link I mentioned. Even If you use SPI for read/write you have to use 2 bytes for address as 24LC256 has 16 bit address.
 

I splitted the 16bit address to two variable ( ipn1MSB = 0b00000000; and ipn1LSB = 0b00000000; ) Most significant bit and least significant bits also defined status register modes as idle, busy, and ready to test it's condition befor any command. I written my code according the datasheet but don't know why have problem.
 

What is your problem? Is the data not being written or do you have eeprom read problem? Can you post your schematic?

If you post the files I can simulate and see the working of your project in proteus. Which PIC are you using?


Change this code
Code:
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

to this code

Code:
 SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
and try.

Do you know that SPI1_Init(); have to be called befor calling SPI1_Init_Advanced(); ?
 
Last edited:

the problem is this that in Serialcom software(RS232 interface) I see the status register always have correct value but the read data is always 2 instead of 196 (SPI1_Write(0b11000100); //Data) in address 0x00 of memory. also sometimes give 255 or 0 after read command with some changes I made to codes.
 

See my last post. where is buffer variable defined? I see onlu buffer1 and buffer2 variables defined.
 
Last edited:


I tested _SPI_MASTER_OSC_DIV64 with DIV4 and DIV14 but see no changes. I think that yhe data written but the read process have problem. I try to edit my schematic and code for simulating it with proteus.
Thanks, I will come back again.
 

Is any of the pins connected from eeprom to PIC is analog? That is you have to make the pins digital by configuring ADCON regiaters. The pins of eeprom should be connected to digital pins. Can you zip and post your proteus file and mikroC Code?

How are you providing the clock to the eeprom? Is your mcu generating the clock?

Did you check this link http://www.mikroe.com/forum/viewtopic.php?f=88&t=31259
 
Last edited:
  • Like
Reactions: rezaf

    rezaf

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top