⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c eeprom.c

📁 PIC单片机的I2C通信程序 C语言版本
💻 C
字号:
//************************************************************************  
//*            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

/* Declare the Function Prototype */

void Initialize_I2C_Master(void);
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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -