📄 i2c.c
字号:
/*-------------------------------------------------------------------------
I2C.C
(I2C+I2L)
Copyright 2004 Macronix International Co., Ltd.
-------------------------------------------------------------------------*/
#define _I2C_
#include "..\inc\public2.h"
#define I2C_ACK 0
#define I2C_NACK 1
//-------------------------------------------------------------------
// I2C_ReleaseBus(void)
//-------------------------------------------------------------------
void I2C_ReleaseBus(void)
{
I2C_SCL = 1;
I2C_SDA = 1;
}
//-------------------------------------------------------------------
// I2C_SendStart(void)
//-------------------------------------------------------------------
void I2C_SendStart(void)
{
I2C_SDA = 1;
I2C_SCL = 1;
DELAY(2);
I2C_SDA = 0;
DELAY(2);
I2C_SCL = 0;
}
//-------------------------------------------------------------------
// I2C_SendStop(void)
//-------------------------------------------------------------------
void I2C_SendStop(void)
{
I2C_SDA = 0;
I2C_SCL = 1;
DELAY(2);
I2C_SDA = 1;
DELAY(2);
I2C_SCL = 1;
}
//-------------------------------------------------------------------
// I2C_GetACK(void)
//-------------------------------------------------------------------
bit I2C_GetACK(void)
{
bit value;
I2C_SDA = 1;
I2C_SCL = 1;
DELAY(5);
value = I2C_SDA;
I2C_SCL = 0;
DELAY(2);
return (!value);
}
// if success return 1, fail return 0
//-------------------------------------------------------------------
// I2C_SendByte(BYTE val)
//-------------------------------------------------------------------
bit I2C_SendByte(BYTE val)
{
BYTE i;
for (i=0; i<8; i++)
{
if (val & 0x80) I2C_SDA = 1;
else I2C_SDA = 0;
I2C_SCL = 1;
DELAY(2);
I2C_SCL = 0;
DELAY(2);
val <<= 1;
}
return(I2C_GetACK());
}
//-------------------------------------------------------------------
// I2C_GetByte(bit ACK_NACK)
// ACK ->I2C_SDA = 0
// NACK ->I2C_SDA = 1
//-------------------------------------------------------------------
BYTE I2C_GetByte(bit ACK_NACK)
{
BYTE i;
BYTE temp;
temp = 0;
for(i=0; i<8; i++)
{
temp <<= 1;
I2C_SCL = 1;
DELAY(2);
temp |= I2C_SDA;
I2C_SCL = 0;
DELAY(2);
}
I2C_SDA = ACK_NACK;
I2C_SCL = 1;
DELAY(2);
I2C_SCL = 0;
I2C_SDA = 1;
DELAY(2);
return(temp);
}
//-------------------------------------------------------------------
// I2C_SendByteWithStart(BYTE val)
//-------------------------------------------------------------------
bit I2C_SendByteWithStart(BYTE val)
{
bit retVal;
I2C_SendStart();
retVal = I2C_SendByte(val);
//delay(1); // delay 1ms
return(retVal);
}
//-------------------------------------------------------------------
//Description: DELAY(int)
//-------------------------------------------------------------------
void DELAY(unsigned int value)
{
while(value>0)
value--;
}
/**--------------------------------------------------------------------------
* Name void I2L_Write(BYTE addr, BYTE i2ldata);
*
* Description I2L write a byte data to 15xx
*
* Flow Chart
*
* Return None
*
* DATE Author Description
* ===========================================================================
* 2004-07-09 K.M. Ho This is first time implement
**/
/*
void I2L_Write(BYTE addr, BYTE i2ldata)
{
BYTE i;
I2L_SCS = 1; //Init
I2L_SCL = 1;
I2L_SDQ = 1;
I2L_SCS = 0; //Serial Interface Chip Select
I2L_SDQ = 0; //Write command
I2L_SCL = 0;
DELAY(2);
I2L_SCL = 1; //rising edge latch data
for (i=0; i<8; i++) //move out 8 bit addr to 15xx
{
I2L_SDQ = addr & 0x01; //move out the LSB
I2L_SCL = 0;
addr >>= 1; //shift bit to LSB
I2L_SCL = 1;
}
for (i=0; i<8; i++) //move out 8 bit data to 15xx
{
I2L_SDQ = i2ldata & 0x01; //move out the LSB
I2L_SCL = 0;
i2ldata >>= 1; //shift bit to LSB
I2L_SCL = 1;
}
I2L_SCS = 1; //Stop the I2L all signal will set to HI
I2L_SDQ = 1;
}
*/
/**--------------------------------------------------------------------------
* Name BYTE I2L_Read(BYTE addr);
*
* Description I2L read a byte data from 15xx
*
* Flow Chart
*
* Return None
*
* DATE Author Description
* ===========================================================================
* 2004-07-09 K.M. Ho This is first time implement
**/
/*
BYTE I2L_Read(BYTE addr)
{
BYTE i, i2ldata, mask_bit;
I2L_SCS = 1; //Init
I2L_SCL = 1;
I2L_SDQ = 1;
I2L_SCS = 0; //Serial Interface Chip Select
I2L_SDQ = 1; //Read command
I2L_SCL = 0;
DELAY(1);
I2L_SCL = 1; //rising edge latch data
for (i=0; i<8; i++) //move out 8 bit addr to 15xx from LSB
{
I2L_SDQ = addr & 0x01; //move out the LSB
I2L_SCL = 0;
addr >>= 1; //shift bit to LSB
I2L_SCL = 1;
}
I2L_SDQ=1; //tai data bit to Hi
i2ldata = 0; //clean the reading buffer
mask_bit = 0x01; //init set mask bit from 0x01
I2L_SCL = 0; // falling edge chage data
for (i=0; i<8; i++) //move in 8 bit data from 15xx
{
I2L_SCL = 1; // sample data on rising edge
if (I2L_SDQ) i2ldata |= mask_bit;
mask_bit <<= 1;
I2L_SCL = 0; // falling edge chage data
}
I2L_SCL = 1; //Stop the I2L all signal will set to HI
I2L_SCS = 1;
I2L_SDQ = 1;
return (i2ldata); //return the data byte
}
*/
/**--------------------------------------------------------------------------
* Name void I2C_Write(BYTE dev_addr, BYTE start_addr,
* BYTE count , BYTE *write_buf)
*
* Description WRITE Control register BY I2C
*
* Flow Chart 1.Send Module Write ID address
* 2.Send Subaddress
* 3.Send Data(n byte)
*
* Return
*
* DATE Author Description
* ===========================================================================
**/
void I2C_Write(BYTE dev_addr, BYTE start_addr, BYTE count , BYTE *write_buf)
{
BYTE i;
I2C_SendByteWithStart(dev_addr); //Write W_ID
I2C_SendByte(start_addr); //Write Address
DELAY(1);
for(i=0;i<count;i++)
{
I2C_SendByte(*(write_buf+i)); //Write multi-data
DELAY(1);
}
I2C_SendStop(); //Stop
DELAY(1);
I2C_ReleaseBus();
}
void I2C_WriteByte(BYTE dev_addr, BYTE start_addr, BYTE write_byte)
{
I2C_SendByteWithStart(dev_addr); //Write W_ID
I2C_SendByte(start_addr); //Write Address
DELAY(1);
I2C_SendByte(write_byte);
DELAY(1);
I2C_SendStop(); //Stop
DELAY(1);
I2C_ReleaseBus();
}
/**--------------------------------------------------------------------------
* Name void I2C_Read(BYTE dev_addr, BYTE start_addr,
* BYTE count, BYTE *DATA_BUF )
*
* Description READ Control register BY I2C
*
* Flow Chart 1.Send Module Write ID address
* 2.Send Subaddress
* 3.Send Module Read ID address
* 4.Read Data(n byte)
*
* Return
*
* DATE Author Description
* ===========================================================================
**/
void I2C_Read(BYTE dev_addr, BYTE start_addr, BYTE count, BYTE *DATA_BUF)
{
BYTE i;
I2C_SendByteWithStart(dev_addr); //Write W_ID
I2C_SendByte(start_addr); //Write Address
DELAY(1);
I2C_SendByteWithStart(dev_addr|0x01); //Write R_ID
DELAY(1);
for(i=0;i<count-1;i++)
{
*(DATA_BUF+i)=I2C_GetByte(I2C_ACK); //Read data from device(burst mode)
DELAY(1); //After every data need to send ACK,
// if the reading is not stop
}
*(DATA_BUF+i) = I2C_GetByte(I2C_NACK); //Read the last data then send NACK to STOP
DELAY(1);
I2C_SendStop(); //Stop
DELAY(1);
I2C_ReleaseBus();
}
BYTE I2C_ReadByte(BYTE dev_addr, BYTE start_addr)
{
BYTE rd_byte;
I2C_SendByteWithStart(dev_addr); //Write W_ID
I2C_SendByte(start_addr); //Write Address
DELAY(1);
I2C_SendByteWithStart(dev_addr|0x01); //Write R_ID
DELAY(1);
rd_byte = I2C_GetByte(I2C_NACK); //Read the last data then send NACK to STOP
DELAY(1);
I2C_SendStop(); //Stop
DELAY(1);
I2C_ReleaseBus();
return(rd_byte);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -