//***************************************************************
// File Name : I2C.C
// Author : Steaven
// Created : 2008-06-09
// Modified :
// Revision : V0.0
//***************************************************************
#include "includes.h"
void Delayms(INT16U time)
{
while(time--) NOP();
}
//I2C操作状态位,反映操作是否成功
INT8U bI2C_Ack = 0;
//引脚属性定义,便于移植
#define DIR_REG_I2C DDRB
#define PORT_REG_I2C PORTB
#define PIN_REG_I2C PINB
#define SCL_BIT_I2C 0
#define SDA_BIT_I2C 1
//***************************************************************
// Function : I2C_Set_SDA
// Input : data - SDA Pin Level
// Output : none
// Description : Set SDA Pin Level.
//***************************************************************
void I2C_Set_SDA(INT8U data)
{
if(data == 0)
{
PORT_REG_I2C &= ~(1 << SDA_BIT_I2C);
}
else
{
PORT_REG_I2C |= (1 << SDA_BIT_I2C);
}
}
//***************************************************************
// Function : I2C_Set_SCL
// Input : data - SCL Pin Level
// Output : none
// Description : Set SCL Pin Level.
//***************************************************************
void I2C_Set_SCL(INT8U data)
{
if(data == 0)
{
PORT_REG_I2C &= ~(1 << SCL_BIT_I2C);
}
else
{
PORT_REG_I2C |= (1 << SCL_BIT_I2C);
}
}
//***************************************************************
// Function : I2C_Start_Condition
// Input : none
// Output : none
// Description : Generate a START Condition.
//***************************************************************
void I2C_Start_Condition(void)
{
I2C_Set_SDA(1);
I2C_Set_SCL(1);
I2C_Set_SDA(0);
I2C_Set_SCL(0);
}
//***************************************************************
// Function : I2C_Stop_Condition
// Input : none
// Output : none
// Description : Generate a STOP Condition.
//***************************************************************
void I2C_Stop_Condition(void)
{
I2C_Set_SDA(0);
I2C_Set_SCL(1);
I2C_Set_SDA(1);
}
//***************************************************************
// Function : I2C_Send_Byte
// Input : data - data to be transmitted
// Output : none
// Description : Send a byte on I2C Bus with the MSB first.
//***************************************************************
void I2C_Send_Byte(INT8U data)
{
INT8U cnt;
for(cnt = 0;cnt < 8;cnt++)
{
if((data << cnt) & 0x80)
{
I2C_Set_SDA(1);
}
else
{
I2C_Set_SDA(0);
}
I2C_Set_SCL(1);
I2C_Set_SCL(0);
}
I2C_Set_SDA(1);
I2C_Set_SCL(1);
DIR_REG_I2C &= ~(1 << SDA_BIT_I2C);
if(PIN_REG_I2C & (1 << SDA_BIT_I2C))
{
bI2C_Ack = 0;
}
else
{
bI2C_Ack = 1;
}
I2C_Set_SCL(0);
DIR_REG_I2C |= (1 << SDA_BIT_I2C);
Delayms(100);
}
//***************************************************************
// Function : I2C_Receive_Byte
// Input : none
// Output : Receive a byte from I2C Bus
// Description : Receive a byte on I2C Bus with the MSB first.
//***************************************************************
INT8U I2C_Receive_Byte(void)
{
INT8U data = 0;
INT8U cnt = 0;
DIR_REG_I2C &= ~(1 << SDA_BIT_I2C);
PORT_REG_I2C |= (1 << SDA_BIT_I2C);
for(cnt = 0; cnt < 8;cnt++)
{
I2C_Set_SCL(0);
I2C_Set_SCL(1);
data = data << 1;
if(PIN_REG_I2C & (1 << SDA_BIT_I2C))
{
data |= 0x01;
}
}
I2C_Set_SCL(0);
DIR_REG_I2C |= (1 << SDA_BIT_I2C);
return(data);
}
//***************************************************************
// Function : I2C_Ack
// Input : ack - Whether to ACK the transmitter
// Output : none
// Description : Acknowledge the transmitter with 0 or 1
//***************************************************************
void I2C_Ack(INT8U ack)
{
if(ack == 0)
{
I2C_Set_SDA(0);
}
else
{
I2C_Set_SDA(1);
}
I2C_Set_SCL(1);
I2C_Set_SCL(0);
}
//***************************************************************
// Function : I2C_Send_Data_without_SubAddress
// Input : bDevice - Slave Device with a I2C Address,
// bData - Data to be transmitted
// Output : I2C Operation Status - Success(1)/Fail(0)
// Description : Transmit a data to Slave without SubAddress
//***************************************************************
INT8U I2C_Send_Data_without_SubAddress(INT8U bDevice,INT8U bData)
{
I2C_Start_Condition();
I2C_Send_Byte(bDevice);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Send_Byte(bData);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Stop_Condition();
return(1);
}
//***************************************************************
// Function : I2C_Send_Data_with_SubAddress
// Input : bDevice - Slave Device with a I2C Address,
// bAddress - SubAddress of the Slave,
// bData - Data to be transmitted
// Output : I2C Operation Status - Success(1)/Fail(0)
// Description : Transmit a data to Slave with SubAddress
//***************************************************************
INT8U I2C_Send_Data_with_SubAddress(INT8U bDevice,INT8U bAddress,INT8U bData)
{
I2C_Start_Condition();
I2C_Send_Byte(bDevice);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Send_Byte(bAddress);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Send_Byte(bData);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Stop_Condition();
return(1);
}
//***************************************************************
// Function : I2C_Send_String_with_SubAddress
// Input : bDevice - Slave Device with a I2C Address,
// bAddress - SubAddress of the Slave,
// ptr - Pointer to the data buffter
// Output : I2C Operation Status - Success(1)/Fail(0)
// Description : Transmit a data to Slave with SubAddress
//***************************************************************
INT8U I2C_Send_String_with_SubAddress(INT8U bDevice,INT8U bAddress,INT8U *ptr,INT8U bLength)
{
INT8U cnt;
I2C_Start_Condition();
I2C_Send_Byte(bDevice);
if(bI2C_Ack == 0)
{
return(0);
}
I2C_Send_Byte(bAddress);
if(bI2C_Ack == 0)
{
return(0);
}
for(cnt = 0;cnt < bLength;cnt++)
{
I2C_Send_Byte(*ptr++);
if(bI2C_Ack == 0)
{
return(0);
}
}
I2C_Stop_Condition();
return(1);
}
//***************************************************************
// Function : I2C_Receive_Data_without_Address
// Input : bDevice - Slave Device with a I2C Address,
// ptr - Pointer to the receive data buffter
// Output : I2C Operation Status - Success(1)/Fail(0)
// Description : Receive N data from Slave without SubAddress
//***************************************************************
INT8U I2C_Receive_Data_without_SubAddress(INT8U bDevice,INT8U *ptr)
{
I2C_Start_Condition();
I2C_Send_Byte(bDevice | 0x01);
if(bI2C_Ack == 0)
{
return(0);
}
*ptr = I2C_Receive_Byte();
I2C_Ack(1);
I2C_Stop_Condition();
return(1);
}
//***************************************************************
// Function : I2C_Recive_String_with_AddressIRcvStr
// Input : bDevice - Slave Device with a I2C Address,
// bAddress - SubAddress of the Slave,
// ptr - Pointer to the receive data buffter
// Output : I2C Operation Status - Success(1)/Fail(0)
// Description : Receive N data from Slave with SubAddress
//***************************************************************
INT8U I2C_Recive_String_with_SubAddress(INT8U bDevice,INT8U