+ Post New Thread
Results 1 to 16 of 16
  1. #1
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    pic16f877a + spi + 93LC46A-I/OT EEPROM

    Hi members,
    i'm working on pic16f877a micro controller, i want to interface 96LC46A-I/OT EEPROM with pic controller using spi module.
    my pic oscillator is about 20MHz, and eeprom Fclk is max 2MHz.
    now im unable to generate clock at SCL pin , i don't know why. i checked spi separately, it is generating clock signal, but when i interface with external eeprom problem comes.any help from members?

  2. #2
    Super Moderator
    Points: 76,326, Level: 67
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,474
    Helped
    3519 / 3519
    Points
    76,326
    Level
    67

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Hi,

    "SCL" usually is an "I2C" pin, not an "SPI" pin. Please check this.

    And for the rest: How do you think we can help you without showing your code and schematic?

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  3. #3
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Check your connections ! Obviously some mistake in your wiring.
    But also give more details of "problem comes". What problem exactly ?



    •   AltAdvertisement

        
       

  4. #4
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Quote Originally Posted by KlausST View Post
    Hi,

    "SCL" usually is an "I2C" pin, not an "SPI" pin. Please check this.

    And for the rest: How do you think we can help you without showing your code and schematic?

    Klaus
    Thanks for your reply ,
    klausST "SCL/SCK" is the clock pin for both SPI & I2C according to pic16f877a datasheet.

    - - - Updated - - -

    Quote Originally Posted by kripacharya View Post
    Check your connections ! Obviously some mistake in your wiring.
    But also give more details of "problem comes". What problem exactly ?
    i made a mistake in setting bit to CKE pin, i made this pin high now i can see the clock from master. now the problem im facing is whatever the data i'm writing to eeprom is showing as 0xFF, (SSPBUF = 0XFF), i don't know why,
    below is my spi code can you check please


    Code:
    #pragma config FOSC = HS                                 // Oscillator Selection bits (HS oscillator)
    #pragma config WDTE = OFF                                // Watchdog Timer Enable bit (WDT disabled)
    #pragma config PWRTE = ON                                // Power-up Timer Enable bit (PWRT enabled)
    #pragma config BOREN = ON                                // Brown-out Reset Enable bit (BOR enabled)
    #pragma config LVP = OFF                                 // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    #pragma config CPD = OFF                                 // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    #pragma config WRT = OFF                                 // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    #pragma config CP = OFF                                  // Flash Program Memory Code Protection bit (Code protection off)
    
    #include 
    #define _XTAL_FREQ 20000000
    
    //SPI lines
    #define CS RA5 //Chip select ON RA5
    #define MOSI RC5 //Master Out Slave In
    #define MISO RC4 //Master in slave out
    #define SCK RC3 //Clock
    
    /*SPI_COMMANDS
    #define READ 0b00001100;
    #define WRITE 0b00001010;
    #define EWEN  0b10001001; 
    #define EWDS 0b00001000;
    #define ERASE 0b00001110;*/
    
    unsigned char HiByte;                                        //High Order Byte 
    unsigned char LoByte;                                        //Low Order Byte
    unsigned char HiData;                                        //Hi Data Byte (upper 8 bits of word)
    unsigned char ReadData[1];                                   //Holds Device data being read back
    unsigned char Length;                                        //Number of Bytes to read (1 for x8 mode)
    unsigned char Result,rxdata;
    
    void SPI_init(void);                                         // Init. function
    void Ewen(void);                                             // Erase/Write Enable function
    void Ewds(void);                                             // Erase/Write Disable function
    void SPI_write_cmd(unsigned char, unsigned char, unsigned char);            // 8-bit Write function
    unsigned char DataRdyMwire(void );
    char SPI_Write(char);
    unsigned char SPI_Read (unsigned char, unsigned char, unsigned char , unsigned char);
    char getdata( unsigned char, unsigned char );
    
    void main(void)
    {
        HiByte = 0x0A;                                                //Dummy Zero's, Start Bit and Op Code for Byte Write
        LoByte = 0x10;                                                //Address bits for 93LC66C
        HiData = 0x5A;                                                  //Upper 8 bits of Data word
        Length = 0x01;                                                  //Number of bytes to read  (1 for x8)
        while(1){
        SPI_init();
     
        Ewen();
        //  __delay_ms(1);
        SPI_write_cmd(HiByte, LoByte, HiData);
       // __delay_ms(1);
        Ewds();
        HiByte = 0x0C;                                                //Changes OpCode from Write to Read for next function
        __delay_us(1);
        SPI_Read(HiByte, LoByte, ReadData, Length);
        }
        while(1);                                                    //Loop here forever
    }
    
    void SPI_init()
    {  
      //  ADCON1 = 0X4F;
        TRISC5 = 0;                                                  // Configure PORTC I/O, MOSI
        TRISC3 = 0;                                                  // Configure PORTC I/O, CLK
        TRISC4 = 1;                                                  // Configure PORTC I/O, MISO  
        PORTA = 0;                                                   // Clear all PORTA pins
        TRISA = 0; 
        SSPSTAT = 0b01000000; 
        SSPCON = 0b00100001; 
    }
    
    
    
    void Ewen(void)
    {
        CS = 1;                                                     //Select Device
        SPI_Write(0x09);                                            //EWEN Command
        SPI_Write(0x08);
         __delay_us(1);
        CS = 0;                                                     //Deselect Device
    }
    
    char SPI_Write(char incoming)
    {
        SSPBUF = incoming;                                          //Write the user given data into buffer
        if (SSPCONbits.WCOL == 1)                                   // test if write collision occurred
        {
             return(-1);   
        }                                                           // if WCOL bit is set return negative #
        else
        {
            while(!SSPSTATbits.BF );                                // wait until bus cycle complete
            //rxdata = SSPBUF;
            return (0);                                             // if WCOL bit is not set return non-negative#
        }    
    }
    
    void SPI_write_cmd(unsigned char HiByte, unsigned char LoByte, unsigned char HiData)
    {
        CS = 1;                                                     // Select Device
        SPI_Write(HiByte);                                            // Send HiByte (Dummy bits, SB, and Op Code)
        SPI_Write(LoByte);                                            // Send LoByte (Address for the 93LC66C)    
        SPI_Write(HiData);                                            // Send HiData to EEPROM
        CS = 0;                                                       // Deselect Device and initiate write
        __delay_us(1);
        CS = 1;                                                        // Select Device
        while (!DataRdyMwire());                                    // Wait for Write to complete
        CS = 0;                                                        // Deselect device
        
       // __delay_us(1);
    }
    
    unsigned char DataRdyMwire(void)
    {
        if(PORTCbits.RC4)                                             // test if DO line is high    
          return (1);                                                 // return ready = true
        else
          return (0);                                                 // else ready = false
    }
    
    void Ewds(void)
    {
        CS = 1;                                                     //Select Device
         SPI_Write(0x08);                                           //EWDS Command to disable write/erase operation
         SPI_Write(0x00);   
          __delay_us(1);
        CS = 0;                                                     //Deselect Device
    }
    
    unsigned char SPI_Read(unsigned char HiByte, unsigned char LoByte, unsigned char ReadData, unsigned char Length )
    {
        LoByte = LoByte << 1;
        CS = 1;                                                       // Select Device
        SPI_Write( HiByte );                                          // Send Read OpCode 
        SPI_Write( LoByte );                                          // WRITE word address to EEPROM
        Result=getdata(ReadData, Length);                             // Reads 1 byte
        __delay_us(1);
        CS = 0;                                                       // Deselect Device
                                      
    } 
    
    char getdata( unsigned char ReadData, unsigned char length )
    {
        while ( length )                                              // stay in loop until length = 0
        {
          SSPBUF = 0x00;                                              // initiate bus cycle
          while(!SSPSTATbits.BF );                                    // wait until byte has been received
          __delay_us(1);
          ReadData = SSPBUF;                                          // save byte
          length--;                                                   // reduce string byte count by 1
        }
      return(ReadData);
          
    }
    Last edited by betwixt; 18th July 2019 at 08:26. Reason: Fixed code tag error



    •   AltAdvertisement

        
       

  5. #5
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Many points can come to mind. However most important one is that the Instruction set for your ic is 9- bits length. I cannot see where/ how these 9- bits are being formed or managed.



  6. #6
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    i'm in confusion, in eeprom datasheet they mention like this s.b(startbit),opcode,address(A6-A0) , this total comes to 10bits
    but you are saying 9th bit, can you explain it little clear

    - - - Updated - - -

    one more thing my eeprom size is 1kb



  7. #7
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    I am simply looking at datasheet of 93LC46A, which is what you mentioned. Clearly mentions 9-bit in many places. Also, it's A5.. A0 and not A6.. A0



    •   AltAdvertisement

        
       

  8. #8
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Quote Originally Posted by kripacharya View Post
    I am simply looking at datasheet of 93LC46A, which is what you mentioned. Clearly mentions 9-bit in many places. Also, it's A5.. A0 and not A6.. A0
    sir, please check X8 organization, ORG=0



  9. #9
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Clearly you are referring to datasheet of some other device. Please cross-check and confirm precisely which eeprom you are talking about.

    - - - Updated - - -

    Okay, I think I have located the variant you are using.

    - - - Updated - - -

    So back to my point, where are you handling 10-bits?

    - - - Updated - - -

    Start with functions EWEN and EWDS



  10. #10
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    EWEN 1(S.B) 00(OP) 1 1 XXXX (A6-A0) for this

    SPI_Write(0x04); //EWEN Command
    SPI_Write(0xC0);

    im little confused how to handle this 10bits

    SPI_Write(0x04); //EWDS Command to disable write/erase operation
    SPI_Write(0x00);
    Last edited by mayasunny; 18th July 2019 at 10:03.



  11. #11
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    I don't know how your SPI_write works. It is probably byte oriented. Also what control is there for clock speed?

    You could write your own bit-banged routines which handle non 8-bit transfers and also allow control of clock speed below maximum of chip.



    •   AltAdvertisement

        
       

  12. #12
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    now i'm operating it with 1.25MHz frequency



  13. #13
    Advanced Member level 4
    Points: 7,740, Level: 20

    Join Date
    Jan 2015
    Posts
    1,086
    Helped
    345 / 345
    Points
    7,740
    Level
    20

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    The EEPROM says that it is "microwire compatible" and while mirowire and SPI are related, they are NOT the same.
    You haev two choices: 1) use a newer EEPROM that has a standard SPI or I2C interface (Microchip and many others make these in abundance) which will let you use the MCU's MSSP module; 2) bit-bang the interface as the MSSP module ONLY works with 8-bit values and you need the 9/10/18/25/whatever clocks for each transfer.
    Susan


    1 members found this post helpful.

  14. #14
    Member level 2
    Points: 295, Level: 3

    Join Date
    Mar 2019
    Posts
    49
    Helped
    0 / 0
    Points
    295
    Level
    3

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    susan sir, in microchip website there are some example applications based on 93lc66 series, in that they used microwire compatible eepprom with MSSP module,(pic16f877a has MSSP module) this is the following link https://www.microchip.com/wwwproducts/en/93LC46A



  15. #15
    Advanced Member level 4
    Points: 7,740, Level: 20

    Join Date
    Jan 2015
    Posts
    1,086
    Helped
    345 / 345
    Points
    7,740
    Level
    20

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    OK - I had not seen that. Thanks for pointing it out.
    AN1023 (linked from the EEPROMs data sheet page you linked to) certainly shows the MSSP module being used. What it also shows is that the EEPROM will ignore leading '0's in the MSByte which I did not pick up from the data sheet itself. Also many (other) devices can be a but sensitive to too many clocks - looks like this one is not.
    Given that Application Note, you should now be all set.
    Susan


    1 members found this post helpful.

  16. #16
    Advanced Member level 4
    Points: 6,247, Level: 18
    kripacharya's Avatar
    Join Date
    Dec 2012
    Location
    New Delhi
    Posts
    1,209
    Helped
    182 / 182
    Points
    6,247
    Level
    18

    Re: pic16f877a + spi + 93LC46A-I/OT EEPROM

    Interesting AppNote. Especially this line quoted from the text "Since the Microwire protocol is not native to the MSSP module, a version of SPI mode 0,0 has been implemented and works within the data sheet specifications for Microwire".

    Also the purpose of that Start-Bit (SB) becomes clear.



--[[ ]]--