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

📄 i2c_demo.c

📁 用于ATmega128的一些通讯程序
💻 C
字号:
// ***************   I2C driver Demo V 1.0   *************
// ***           Written By P. Fletcher-Jones          ***
// ***                Written on 16/11/01			   ***
// ***                 Last MOD 21/11/01			   ***
// *******************************************************
// ***************     I2C driver V 1.0    ***************
// ***           Written By P. Fletcher-Jones          ***
// ***                Written on 16/11/01			   ***
// ***                 Last MOD 21/11/01			   ***
// ***       Compiled using ImageCraft C Comiler       ***
// *******************************************************

#include <iom128v.h>
#include <MACROS.h>
#include <dc_defines.h>

#include "I2C.h"


// ******************************************** //
// *** This routine will setup the I2C Port *** //
// ******************************************** //

void Init_I2C(void)
{
 SETBIT(I2C_DIR,SCL);   	   // Set SCL to output	
 SETBIT(I2C_DIR,SDA );	   // Set SDA to output
	
 SETBIT(I2C_PORT,SCL);		   // Set SCL high
 SETBIT(I2C_PORT,SDA );		   // Set SDA high
}



// ************************************************ //
// *** This routine will send the I2C Start Bit *** //
// ************************************************ //

void I2C_Start (void)
{
 SETBIT(I2C_PORT,SCL);				// Set SCL High
 SETBIT(I2C_PORT,SDA);				// Set SDA High
 
 SETBIT(I2C_DIR,SDA);   		   // Set SDA to output	
 CLEARBIT(I2C_PORT,SDA);		   // Clear SDA
}


// *********************************************** //
// *** This routine will send the I2C Stop Bit *** //
// *********************************************** //

void I2C_Stop (void)
{
 
 SETBIT(I2C_DIR,SDA);   		   // Set SDA to output
	
 CLEARBIT(I2C_PORT,SDA);		   // Clear SDA
 CLEARBIT(I2C_PORT,SCL);		   // Clear SCL
	
 SETBIT(I2C_PORT,SCL);			   // Set SCL High
 SETBIT(I2C_PORT,SDA);			   // Set SDA High
}





// ************************************************** //
// *** This routine will send the I2C clock pulse *** //
// ************************************************** //

void I2C_Clock (void)
{
 SETBIT(I2C_PORT,SCL);				// Set SCL high
 NOP();								// Small Delay
 CLEARBIT(I2C_PORT,SCL);			// Set SCL low
}




// ******************************************************** //
// *** This routine will write a byte to the I2C device *** //
// ******************************************************** //

void Write_I2C_Byte(unsigned char byte)
{
 unsigned char i;

 SETBIT(I2C_DIR,SDA);   		   // Set SDA to output	
 CLEARBIT(I2C_PORT,SCL);
 	
 for (i = 0; i < 8; i++){  		 // Loop for our 8 bits
 
	// Set or Clear SDA pin
	 if((byte & 0x80) == 0x80) SETBIT(I2C_PORT, SDA);	// Set I2C SDA PIN
	 else CLEARBIT(I2C_PORT,SDA);		  				// Clear I2C SDA PIN
	 
	 SETBIT(I2C_PORT,SCL);			   // Set SCL High, Clock data

	 byte = byte << 1;				   // Shift data in buffer right one
	
     CLEARBIT(I2C_PORT,SCL);		   // Clear SCL
	}

	
 while(I2C_Ackn() );				   // Check for acknowledge from I2C device	
}





// ********************************************************* //
// *** This routine will read a byte from the I2C device *** //
// ********************************************************* //

unsigned char Read_I2C_Byte(void)
{	
 unsigned char i,buff = 0;
	
	for (i = 0; i < 8; i++){
	
		buff = buff << 1;
		
 		CLEARBIT(I2C_DIR,SDA);   		   // Set SDA to input
		
		SETBIT(I2C_PORT,SCL);	  	  	   // Set SCL High,Clock bit out
	
		// Read data on SDA pin
		if ( CHECKBIT( I2C_IN,SDA ) ) buff = buff | 0x01;	
		
		CLEARBIT(I2C_PORT,SCL);	  	  	   // Clear SCL 	
        }

 // *** No ACK *** //
 
 I2C_Clock();						       // Clock I2C bit
	
 return buff;							   // Return our I2C byte
}




// *********************************************************************** //
// *** This routine returns a 0 if the I2C device sends an acknowledge *** //
// *********************************************************************** //

unsigned char I2C_Ackn(void)
{
 unsigned char Ackn = 0;		   // Temp RAM for Ackn flag
	
 CLEARBIT(I2C_PORT,SCL);
 CLEARBIT(I2C_DIR,SDA);   		   // Set SDA to input	
 
 SETBIT(I2C_PORT,SCL);			   // Clock the ACK bit

 if ( CHECKBIT( I2C_IN,SDA ) ) Ackn = 1;	  // Check the ACK bit on SDA	
 
 CLEARBIT(I2C_PORT,SCL);	  	   // Clear the clock

 return Ackn;					   // Return our ACK bit
}	





// ***************************************************** //
// *** This routine will write the I2C device code,  *** //
// *** set the device chip select bits, 	   	   	 *** //
// *** and set or clear the I2C R/W bit				 *** //
// ***************************************************** //

void Write_I2C_Control(unsigned char D_Code,unsigned char H_ADD,unsigned char RW)
{

 // *** Send the I2C device Control code *** //

 CLEARBIT(I2C_PORT,SCL);	  	   // Clear SCL clock
 
 if( (D_Code & 0x08) == 0x08) SETBIT(I2C_PORT, SDA);	// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
 
 if( (D_Code & 0x04) == 0x04) SETBIT(I2C_PORT, SDA);	// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
	
 if( (D_Code & 0x02) == 0x02) SETBIT(I2C_PORT, SDA);	// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
 
 if( (D_Code & 0x01) == 0x01) SETBIT(I2C_PORT, SDA);	// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit

 
 
 // *** Send the I2C Control byte chip selects bits *** //

 if( (H_ADD & 0x04) == 0x04) SETBIT(I2C_PORT, SDA);		// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
	
 if( (H_ADD & 0x02) == 0x02) SETBIT(I2C_PORT, SDA);		// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
 
 if( (H_ADD & 0x01) == 0x01) SETBIT(I2C_PORT, SDA);		// Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);		  					// Clear I2C SDA PIN

 I2C_Clock();			// Clock I2C bit
 
 // *** Set or Clear the read / write bit for I2C control *** //
	
 if(RW) SETBIT(I2C_PORT,SDA);		  	  	  		 	 // Set I2C SDA PIN
 else CLEARBIT(I2C_PORT,SDA);							 // Clear I2C SDA PIN
 
 I2C_Clock();			// Clock I2C bit
 
 while(I2C_Ackn() );				   // Check for acknowledge from I2C device
}














void EEPROM_Write(unsigned char, unsigned char, unsigned char);
unsigned char EEPROM_Read(unsigned char, unsigned char);


// **************************************************************** //
// ***                     Init_I2C();							*** //
// *** This routine will setup the I2C port direction registers *** //
// **************************************************************** //

// ***************************************************************** //
// ***                     I2C_Start();	 		  		 	   	 *** //
// *** This routine will set the I2C start condition on the bus, *** //
// *** All commands must be preceded by a START condition 		 *** //
// ***************************************************************** //

// ***************************************************************** //
// ***                     I2C_Stop();	 		  		 	   	 *** //
// *** This routine will set the I2C stop condition on the bus,  *** //
// *** All commands must end with a STOP condition 		         *** //
// ***************************************************************** //

// *********************************************************************** //
// ***                Write_I2C_Control(0x0A,0,0);	  		  	       *** //
// *** This routine will write the I2C device code, the device address *** //
// *** setup on the hardware pins A0,A1 & A2, and also the W/R bit     *** //
// *** So for an external EEPROM, such as the 24LC04B you would need   *** //
// *** a device code of 1010 (0x0A),   	  	  		  	  			   *** //
// *** hardware address 0 (if pins A0,A1 & A2 are left unconnected,    *** //
// *** and the last parameter is R/W. Write is active low			   *** //
// *********************************************************************** //

// *********************************************************************** //
// ***                          I2C_Ackn();							   *** //
// *** This routine will clock the ACK bit from the I2C slave device   *** //
// *** it will return TRUE for a fail, and FALSE for a correct ACK bit *** //
// *********************************************************************** //

// ************************************************************** //
// ***                     Write_I2C_Byte();				  *** //
// *** This routine will clock a byte to the slave I2C device *** //
// ************************************************************** //

// ************************************************************************** //
// ***                       Read_I2C_Byte();					          *** //
// *** This routine will read and return a byte from the I2C slave device *** //
// ************************************************************************** //



// *********************************************************************** //
// ***                 Example of using Imagecraft I2C driver          *** //
// ***              to write to an external 8 bit address EEPROM       *** //
// *** H_ADD is the hardware address set on the device A0,A1 & A2 pins *** //
// *** M_ADD is the devices internal memory address                    *** //
// *** Data is user data to be writen 								   *** //
// *********************************************************************** //

void EEPROM_Write(unsigned char H_ADD, unsigned char M_ADD, unsigned char Data)
{
 I2C_Start();			   			   // Set I2C start condition

 Write_I2C_Control(0x0A,H_ADD,0);	   // Send the EEPROM control Byte

 Write_I2C_Byte(M_ADD);				   // Send the EEPROM internal Address
  
 Write_I2C_Byte(Data);				   // Send the EEPROM Data
 
 I2C_Stop();	  					   // Set I2C Stop condition
}



// *********************************************************************** //
// ***              Example of using Imagecraft I2C driver             *** //
// ***            to Read an external 8 bit address EEPROM             *** //
// *** H_ADD is the hardware address set on the device A0,A1 & A2 pins *** //
// *** M_ADD is the devices internal memory address                    *** //
// *** Data is user data to be writen 								   *** //
// *********************************************************************** //

unsigned char EEPROM_Read(unsigned char H_ADD, unsigned char M_ADD)
{
 unsigned char Temp;			   		// Temp RAM for EEPROM Read
 
 I2C_Start();			   			   // Set I2C start condition

 Write_I2C_Control(0x0A,H_ADD,0);	   // Send the EEPROM control Byte
 									   // Dummy write to set address

 Write_I2C_Byte(M_ADD);				   // Send the EEPROM internal Address
 
 I2C_Start();			   			   // Set I2C start condition
 
 Write_I2C_Control(0x0A,H_ADD,1);	   // Send the EEPROM control Byte
 
 Temp = Read_I2C_Byte();			   // Read data from EEPROM
 
 I2C_Stop();	  					   // Set I2C Stop condition

 return Temp;						   // Return data from EEPROM
}










void main (void)
{
 unsigned long c;			  // Temp Ram used for write delay
 
 DDRB = 0xFF;  	 			  // Set Port B to Outputs

 Init_I2C();	   			  // Setup the hardware port

 EEPROM_Write(0xa2,1,0xAA);	  // Write to device 0, memory address 1, Data 0xAA			
 
 for(c=0;c<1000;c++);		  // Delay for EEPROM Write
 
 PORTB = EEPROM_Read(0xa3,1);	  // Read device 0, memory address 1
}

⌨️ 快捷键说明

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