//************************************************************************ //* 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 */
#include <p18f452.h> #include <i2c.h> // Load I2C Header file from defult direct #include <timers.h> #include "P18LCD.h" // Load P18LCD Header file form current working direct
#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
//*********************************************************** /* */ /* 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();
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--; }
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;
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 }