//* Using I2C Master Mode for access Slave (EEPRM)
//*
//* Written by: Richard Yang
//* Sr. Corporate Application Engineer
//* Microchip Technology Inc.
//* Date: Oct. 3nd '2002
//* Revision: 1.00
//* Language tools : MPLAB-C18 v2.09.13
//* MPLINK v3.10
//* MPLAB-IDE v6.00.17 & ICD2
//***********************************************************
/* Include Header files */ #i nclude
#i nclude
#i nclude
#i nclude "P18LCD.h" // Load P18LCD Header file form current working direct
void EE_Page_Write(unsigned char,unsigned char,unsigned char,unsigned char *);
void EE_SEQU_Read(unsigned char,unsigned char,unsigned char,unsigned char *);
void EEPROM_Write(unsigned char,unsigned char,unsigned char);
void EEPROM_ACK(unsigned char);
unsigned char EEPROM_Read(unsigned char,unsigned char);
void I2C_Done(void);
void Initialize_Timer2(void);
void isr_high_direct(void);
void isr_high(void); #pragma romdata My_romdata=0x1000
const rom far unsigned char LCD_MSG1[]="SW2: Byte Write ";
const rom far unsigned char LCD_MSG2[]="SW6: Random Read";
const rom far unsigned char LCD_MSG3[]="Byte Write Mode ";
const rom far unsigned char LCD_MSG4[]="Random Read Mode";
const rom far unsigned char LCD_MSG5[]="Sended: ";
const rom far unsigned char LCD_MSG6[]="Send: ";
const rom unsigned char I2C_Write_Buffer[]="Microchip Technology";
#pragma romdata /* Define following array in data memory */ unsigned char I2C_Read_Buffer [32]; /* define following variable in data memory at Access Bank */
#pragma udata access My_RAM
near unsigned char Debounce;
near unsigned char Send_Addr;
near unsigned char Send_Data;
near unsigned char Send_Length;
near unsigned char Read_Data;
near unsigned char P_SW2;
near unsigned char P_SW6;
#pragma udata #define Page_Length 8
#define SW2 PORTAbits.RA4
#define SW6 PORTEbits.RE1
#define Bounce_Time 6
#define EE_CMD 0xA0 //***********************************************************
/* */
/* Main Program */
/* */
//***********************************************************
void main(void)
{
ADCON1=0b00000110; // Disable A/D Function
TRISAbits.TRISA4=1; // Set SW2 for input
TRISEbits.TRISE1=1; // Set SW6 for Input
Initialize_Timer2( );
Initialize_I2C_Master( );
OpenLCD( );
if (SW2 & SW6)Debounce=0;
else Debounce = Bounce_Time;
while(1)
{
LCD_Set_Cursor(0,0); // Put LCD Cursor on (0,0)
putrsLCD(LCD_MSG1);
LCD_Set_Cursor(1,0); // Put LCD Cursor on (1,0)
putrsLCD(LCD_MSG2);
P_SW2=P_SW6=0;
Send_Addr=0;
while(1)
{
if (P_SW2)
{
P_SW2=0;
Debounce = Bounce_Time;
LCD_Set_Cursor(0,0); // Put LCD Cursor on (0,0)
putrsLCD(LCD_MSG3);
LCD_Set_Cursor(1,0); // Put LCD Cursor on (0,0)
putrsLCD(LCD_MSG5);
do
{
while (!P_SW2);
P_SW2=0;
LCD_Set_Cursor(1,8);
Send_Data=I2C_Write_Buffer[Send_Addr];
EEPROM_Write(EE_CMD,Send_Addr,Send_Data);
puthexLCD(EE_CMD);
putcLCD(' ');
puthexLCD(Send_Addr);
putcLCD(' ');
puthexLCD(Send_Data);
EEPROM_ACK(EE_CMD);
Send_Addr++;
} while (I2C_Write_Buffer[Send_Addr]!=0x00);
break;
}
if (P_SW6)
{
P_SW6=0;
Debounce = Bounce_Time;
LCD_Set_Cursor(0,0); // Put LCD Cursor on (0,0)
putrsLCD(LCD_MSG4);
LCD_Set_Cursor(1,0); // Put LCD Cursor on (0,0)
putrsLCD(LCD_MSG6);
while(1)
{
if (P_SW6)
{
P_SW6=0;
LCD_Set_Cursor(1,5);
Read_Data = EEPROM_Read(EE_CMD,Send_Addr);
puthexLCD(EE_CMD);
putcLCD(' ');
puthexLCD(Send_Addr);
putcLCD(' ');
puthexLCD(EE_CMD);
putcLCD(' ');
puthexLCD(Read_Data);
Send_Addr++;
}
if (P_SW2) break;
}
if (P_SW2) break;
}
if (P_SW2)
{
P_SW2=0;
break;
}
}
}
}
//************************************************
//* #pragma Interrupt Declarations *
//* *
//* Function: isr_high_direct *
//* - Direct execution to the actual *
//* high-priority interrupt code. *
//************************************************
#pragma code isrhighcode = 0x0008 void isr_high_direct(void)
{
_asm //begin in-line assembly
goto isr_high //go to isr_high function
_endasm //end in-line assembly
}
#pragma code //************************************************
//* Function: isr_high(void) *
//* High priority interrupt for Timer2 *
//************************************************
#pragma interrupt isr_high void isr_high(void)
{
PIR1bits.TMR2IF=0; // Clear Timer2 interrupt Flag
if (Debounce==0)
{
if (!SW2)
{ P_SW2=1; Debounce =Bounce_Time; }
if (!SW6)
{ P_SW6=1; Debounce =Bounce_Time; }
}
else if (SW2 & SW6)Debounce--;
else Debounce =Bounce_Time;
}
#pragma code //***********************************************
//* Write a Byte to EEPROM
//* - ctrl : Control Byte of EEPROM
//* - addr : Location of EEPROM
//* - data : Data Byte of EEPROM
//*********************************************** void Initialize_Timer2(void)
{ RCONbits.IPEN=1; // Enable Interrupt Priority bit
IPR1bits.TMR2IP=1; // Set Timer2 for High Priority
INTCONbits.GIEH=1; // Enable High Priority Interrupt OpenTimer2 (TIMER_INT_ON // Turn On the Timer2 with Interrupt
& T2_PS_1_4 // (4Mhz/4) [4*10*(99+1)] = 4mS */
& T2_POST_1_10); PR2 = 99;
} //***********************************************
//* Write a Byte to EEPROM *
//* - ctrl : Control Byte of EEPROM *
//* - addr : Location of EEPROM *
//* - data : Data Byte of EEPROM *
//***********************************************
void EEPROM_Write(unsigned char ctrl,unsigned char addr,unsigned char data)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed and clear SSPIF flag WriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flag
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); // Clear SSPIF flag WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); WriteI2C(data); // Write Data to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); StopI2C(); // Stop condition
I2C_Done(); // Wait the Stop condition completed
} //***********************************************
//* Pae Write to EEPROM
//*
//* - ctrl : Control Byte of EEPROM
//* - addr : Location of EEPROM
//* - length : Write counter
//* - *dptr : RAM point --> EEPROM
//*
//***********************************************
void EE_Page_Write(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed
WriteI2C(ctrl); // Write Control+Write to EEPROM & Check BF flag
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); // Clear SSPIF flag WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done(); while (length!=0) // Check write completed ?
{
WriteI2C(*dptr); // Write data to EEPROM
while(SSPCON2bits.ACKSTAT); // wait until received the Acknowledge from EEPROM
I2C_Done();
dptr++; // Point to next byte
length--;
}
StopI2C(); // Stop condition
I2C_Done(); // Wait the Stop condition completed
}
//***********************************************
//* EEPROM Acknowledge Polling *
//* -- The routine will polling the ACK *
//* response from EEPROM *
//* -- ACK=0 return *
//* -- ACK=1 send Restart & loop check *
//***********************************************
void EEPROM_ACK(unsigned char ctrl)
{
unsigned char i; IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed WriteI2C(ctrl); // Write Control to EEPROM (WRITE)
I2C_Done(); // Clear SSPIF flag while (SSPCON2bits.ACKSTAT) // test for Acknowledge from EEPROM
{
for (i=0;i<100;i++); // Delay for next Repet-Start RestartI2C(); // initiate Repet-Start condition
I2C_Done(); // Wait Repet-Start condition completed WriteI2C(ctrl); // Write Control to EEPROM (WRITE)
I2C_Done(); // Clear SSPIF flag
}
StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over
} //***********************************************
//* Random Read a Byte from EEPROM *
//* - ctrl : Control Byte of EEPROM (Write) *
//* (Ctrl +1 ) : Read Command *
//* - addr : Address Byte of EEPROM *
//* - Return : Read Data from EEPROM *
//***********************************************
unsigned char EEPROM_Read(unsigned char ctrl,unsigned char addr)
{
unsigned char f;
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed WriteI2C(ctrl); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag RestartI2C(); // initiate Restart condition
I2C_Done(); WriteI2C(ctrl+1); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag f=ReadI2C(); // Enable I2C Receiver & wait BF=1 until received data
I2C_Done(); // Clear SSPIF flag NotAckI2C(); // Genarate Non_Acknowledge to EEPROM
I2C_Done();
StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over return(f); // Return Data from EEPROM
} //***********************************************
//* Sequential Read from EEPROM
//*
//* - ctrl : Control Byte of EEPROM
//* - addr : Location of EEPROM
//* - length : Read counter
//* - *dptr : Store EEPROM data to RAM
//*
//***********************************************
void EE_SEQU_Read(unsigned char ctrl,unsigned char addr,unsigned char length,unsigned char *dptr)
{
IdleI2C(); // ensure module is idle
StartI2C(); // Start condition
I2C_Done(); // Wait Start condition completed WriteI2C(ctrl); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag WriteI2C(addr); // Write Address to EEPROM
while(SSPCON2bits.ACKSTAT); // test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag RestartI2C(); // initiate Restart condition
I2C_Done(); WriteI2C(ctrl+1); // Write Control to EEPROM
while(SSPCON2bits.ACKSTAT); // Test for ACK condition, if received
I2C_Done(); // Clear SSPIF flag while (length!=0)
{
*dptr=ReadI2C(); // Enable I2C Receiver & Store EEPROM data to Point buffer
I2C_Done();
dptr++;
length--;
if (length==0) NotAckI2C();
else AckI2C(); // Continue read next data, send a acknowledge to EEPROM
I2C_Done();
} StopI2C(); // send STOP condition
I2C_Done(); // wait until stop condition is over
} //***********************************************
//* Check I2C action that is completed *
//***********************************************
void I2C_Done(void)
{
while (!PIR1bits.SSPIF); // Completed the action when the SSPIF is Hi.
PIR1bits.SSPIF=0; // Clear SSPIF
} //************************************************
//* Initial I2C Master Mode with 7 bits Address *
//* Clock Speed : 100KHz @4MHz *
//************************************************
void Initialize_I2C_Master(void)
{
OpenI2C(MASTER,SLEW_ON);
SSPADD= 9;
}