Interfacing PIC18Fxxx with EEPROM using SPI

Updated on 2017/11/16 20:51

Syllabus

Interfacing PIC18Fxxx with EEPROM using SPI

Interfacing PIC18Fxxx with EEPROM using SPI

SPI MASTER MODE

  • The master can initiate the data transfer at any time because it controls the SCK.
  • The master determines when the slave (Processor 2) is to broadcast data by the software protocol.
  • In Master mode, the data is transmitted / received as soon as the SSPBUF register is written to.
  • If the SPI is only going to receive, the SDO output could be disabled (programmed as an input).
  • The SSPSR register will continue to shift in the signal present on the SDI pin at the programmed clock rate.
  • As each byte is received, it will be loaded into the SSPBUF register as if a normal received byte (interrupts and status bits appropriately set).
  • This could be useful in receiver applications as a “Line Activity Monitor” mode.
  • The clock polarity is selected by appropriately programming the CKP bit (SSPCON1<4>).
  • In Master mode, the SPI clock rate (bit rate) is user programmable to be one of the following.
  • This allows a maximum data rate (at 48 MHz) of 2.00 Mbps.
    • FOSC/4 (or TCY)
    • FOSC/16 (or 4 • TCY)
    • FOSC/64 (or 16 • TCY)
    • Timer2 output/2

Initialization of SPI Module in Master Mode

  • Configure SCK, SDO pins as output and SDI as input through TRIS Register.
  • Configure one of port pin as output to use as chip select/slave select.
  • Set CKE and SMP bit in SSPSTAT register
  • Enable Master SPI mode in SSPCON1 register SSPM3:SSPM0=0010 = SPI Master mode, clock = FOSC/64
  • Enable SPI in SSPCON1 register by setting SSPEN bit in SSPCON1

To send data to a slave device

  • Select slave device by making chip select or slave select low.
  • Send the data. SSPBUF = data.
  • Poll the BF bit from SSPSTAT for successful transmission
  • De-select slave device by making chip select or slave select high.

To receive data from a slave device

  • Select slave device by making chip select or slave select low.
  • Send the dummy data. SSPBUF = dummy data.
  • Poll the BF bit from SSPSTAT for successful reception
  • Read the SSPBUF for received data.
  • De-select slave device by making chip select or slave select high.

25C128/256 : SPI based Serial EEPROM

  • The 25C128 / 25C256 are 128Kbit/ 256 Kbit Serial Electrically Erasable PROMs. The memory is accessed via a simple Serial Peripheral InterfaceTM (SPITM) compatible serial bus.
  • The bus signals required are a clock input (SCK) plus separate data in (SI) and data out (SO) lines.
  • Access to the device is controlled through a Chip Select (CS) input. Communication to the device can be paused via the hold pin (HOLD).
  • While the device is paused, transitions on its inputs will be ignored, with the exception of Chip Select, allowing the host to service higher priority interrupts.
  • The 25XX256 is available in standard packages including 8 -lead PDIP and SOIC, and advanced packaging including 8-lead DFN and 8-lead TSSOP.

Serial-EEPROM.png

Fig. Serial EEPROM IC No. 25CXXX 

Functional Description

The AT25128/256 is designed to interface directly with the synchronous serial peripheral interface (SPI) of microcontrollers. The AT25128/256 utilizes an 8-bit instruction register. The list of instructions and their operation codes are contained in Table 1.1. All instructions, addresses, and data are transferred with the MSB first and start with a high-to-low CS transition.

WRITE ENABLE (WREN): The device will power-up in the write disable state when VCC is applied. All programming instructions must therefore be preceded by a Write Enable instruction.

WRITE DISABLE (WRDI): To protect the device against inadvertent writes, the Write Disable instruction disables all programming modes. The WRDI instruction is independent of the status of the WP pin.

READ STATUS REGISTER (RDSR): The Read Status Register instruction provides access to the status register. The Ready/Busy and Write Enable status of the device can be determined by the RDSR instruction. Similarly, the Block Write Protection bits indicate the extent of protection employed. These bits are set by using the WRSR instruction.

RDSR.png

WRITE STATUS REGISTER (WRSR): The WRSR instruction allows the user to select one of four levels of protection.

The AT25128/256 is divided into four array segments. Top quarter (1/4), top half (1/2), or all of the memory segments can be protected. Any of the data within any selected segment will therefore be READ only.The block write protection levels and corresponding status register control bits are shown in Table 1.2.The three bits, BP0, BP1, and WPEN are nonvolatile cells that have the same properties and functions as the regular memory cells (e.g. WREN, tWC, RDSR).

Instruction-format.png

READ SEQUENCE (READ):

Reading the AT25128/256 via the SO pin requires the following sequence.

Read-Sequence-1.png

After the CS line ispulled low to select a device, the READ op- codeis transmitted via the SI line followed by the byte address to be read.

Read-Sequence-2.png

Upon completion, any data on the SI line will be ignored.The data (D7 – D0) at the specified address is then shifted out onto the SO line. If only one byte is to be read, the CS line should be driven high after the data comes out.The read sequence can be continued since the byte address is automatically incremented and data will continue to be shifted out.When the highest address is reached, the address counter will roll over to the lowest address allowing the entire memory to be read in one continuous read cycle.

WRITE SEQUENCE (WRITE):

In order to program the AT25128/256, two separate instructions must be executed. First, the device must be write enabled via the WREN instruction. Then a Write instruction may be executed. Also, the address of the memory location(s) to be programmed must be outside the protected address field location selected by the block write protection level. During an internal write cycle, all commands will be ignored except the RDSR instruction.

write-sequence-1.png

A Write instruction requires the following sequence.

After the CS line is pulled low to select the device, the Writeop - code is transmitted via the SI line followed by the byte address and the data (D7 – D0) to be programmed. 

write-sequence-2.png

Programming will start after the CS pin is brought high. The low-to-high transition of the CS pin must occur during the SCK low time immediately after clocking in the D0 (LSB) data bit. The Ready/Busy status of the device can be determined by initiating a Read Status Register (RDSR) instruction. If Bit 0 = “1”, the write cycle is still in progress. If Bit 0 = “0”, the write cycle has ended. Only the RDSR instruction is enabled during the write programming cycle.

Interfacing Diagram

EEPROM-Interfacing-with-PIC18FXXX-using-SPI.png

Embedded C Program

Program:- Write an Embedded C program to interface Serial EEPROM IC 25CXXX with PIC18FXXXX using SPI protocol and write a character and read the same character and display it on to the LED's

//Program to Write and read from SPI EEPROM 25Cxxx
//Write a character and read it to display the read data on LED
#include <p18f4550.h> 
#pragma config FOSC = HS 
//Oscillator Selection
#pragma config WDT = OFF //Disable Watchdog timer
#pragma config LVP = OFF //Disable Low Voltage Programming
#pragma config PBADEN = OFF //Disable PORTB Analog inputs

/*Declare PORT pin to use as chip select/Slave select*/

#define CS_EEPROM_TRIS TRISAbits.TRISA5

#define CS_EEPROM PORTAbits.RA5

/************ SPI EEPROM Commands *******************/

#define EEPROM_CMD_READ (unsigned)0b00000011

#define EEPROM_CMD_WRITE (unsigned)0b00000010

#define EEPROM_CMD_WRDI (unsigned)0b00000100

#define EEPROM_CMD_WREN (unsigned)0b00000110

#define EEPROM_CMD_RDSR (unsigned)0b00000101

#define EEPROM_CMD_WRSR (unsigned)0b00000001

//Function Prototypes

void msdelay (unsigned int time); //Function to generate delay

void SPIinit(); //Function to Initialize SPI Module
unsigned char SPISend(unsigned char data); //Function to send data to SPI Slave
unsigned char SPIReceive(); //Function to receive data from SPI Slave
//Function to Write the single byte to SPI EEPROM IC
void EEPROMWriteByte(unsigned char Data, unsigned int Address);
//Funcction to read the single byte from SPI EEPROM IC
unsigned char EEPROMReadByte(unsigned int Address);

//Start of Main Program void main(void)

{

unsigned char rx_data;

TRISD = 0x00; //Configuring PORTD as output
PORTD = 0x00; //Initially PORTD made low
SPIinit(); //Initializing SPI module
EEPROMWriteByte(0xAA, 0x0010);  //Write Data to SPI EEPROM
msdelay(500);    
rx_data =  EEPROMReadByte(0x10); //Read Data from SPI EEPROM
PORTD = rx_data;    //Verify the data using PORTD

while(1);   //Endless loop

}   //End of main program

//Function Definitions //Function to generate delay void msdelay (unsigned int time)

{

unsigned int i, j;

for (i = 0; i < time; i++)

for (j = 0; j < 275; j++);/*Calibrated for a 1 ms delay in MPLAB*/

}

//Function to Initialize SPI Module void SPIinit()

{  
TRISCbits.TRISC3=0; //SCK = output
TRISCbits.TRISC5=1; //SDI = input
TRISCbits.TRISC4=0; //SDO = output
PORTCbits.RC3=0; //Clearing SDO,SCK initially
PORTCbits.RC4=0;  
CS_EEPROM_TRIS=0; //Chip select pin = Output
CS_EEPROM =1; //Initially slave not selected
SSPSTATbits.SMP=1; //0 = Input data sampled at middle of data output time
SSPSTATbits.CKE=1; //0 = Transmit occurs on transition from Idle to active clock state
SSPCON1=0X02; //SPI Master mode, clock = FOSC/64

File: /home/vedant/Music/MCA_2014/CEEPROM_LED/SPI_EEPROM_Simple.c Page 2 of 2
  
SSPCON1bits.SSPEN=1; //Enabling SPI module  
}   
//Function to send data to SPI Slave  
unsigned char SPISend(unsigned char data)  
{ //Load SSPBUF with data  
SSPBUF=data;   
while(!SSPSTATbits.BF); //Check for Buffer full status

}

//Function to receive data from SPI Slave unsigned char SPIReceive()

{

SSPBUF=0x0; //dummy write to receive data while(!SSPSTATbits.BF); //Check for Buffer full status return(SSPBUF); //return the received data

}

//Function to Write the single byte to SPI EEPROM IC

void EEPROMWriteByte(unsigned char Data, unsigned int Address)

{

unsigned char low_address, high_address;

low_address = (unsigned char)(Address & 0x00ff);     //Separate out lower address

high_address = (unsigned char)((Address>>8)&0x00ff); //Separate out higher address

//Send the Wrtie Enable Command to SPI EEPROM CS_EEPROM =0;

SPISend(EEPROM_CMD_WREN); CS_EEPROM =1;

//Write the Data to SPI EEPROM

CS_EEPROM =0;

SPISend(EEPROM_CMD_WRITE);  //Send Write Command

SPISend(high_address); //Send Higher Address (A15 - A8)

SPISend(low_address); //Send Lower Address (A7 - A0)

SPISend(Data); //Send data to be written

CS_EEPROM =1;

msdelay (100); //Keep Some delay before disabling

//Send the Wrtie Disable Command to SPI EEPROM CS_EEPROM =0;

SPISend(EEPROM_CMD_WRDI); CS_EEPROM =1;
}

//Funcction to read the single byte from SPI EEPROM IC unsigned char EEPROMReadByte(unsigned int Address)

{

unsigned char temp;

unsigned char low_address, high_address;

low_address = (unsigned char)(Address & 0x00ff); //Separate out lower address high_address = (unsigned char)((Address>>8)&0x00ff); //Separate out higher address

CS_EEPROM =0;

SPISend(EEPROM_CMD_READ); //Send Read Command

SPISend(high_address); //Send Higher Address (A15 - A8)

SPISend(low_address); //Send Lower Address (A7 - A0)

temp = SPIReceive(); //Read the data from specified location

CS_EEPROM =1;

return temp; //return the received data

}

References

  • Notes by Prof. S.S.Kendre, Created and Edited by Prof Sujit Wagh, SKNCOE, Pune
  • Interfacing Diagram by Mr. Jayesh Gopal, WikiNote Volunteer
  • WikiNote Foundation
Tags:
Created by Sujit Wagh on 2017/11/13 13:11