📄 i2c_demo.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 + -