#include "config.h"
#include "I2C1.h"
#include "Uart_Print.h"
static void i2c_delay(void)
{
#if (0)
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
#else
volatile uint8_t i;
for (i=0; i<10; i++)
{
}
#endif
}
void I2C1_Init(void)
{
SET_SCL1_OUT();
SET_SDA1_OUT();
SCL1 = 1;
SDA1 = 1;
}
void I2C1_Start(void)
{
// SDA1 1->0 while SCL1 High
SDA1 = 1;
SCL1 = 1;
i2c_delay();
SDA1 = 0;
i2c_delay();
SCL1 = 0;
}
void I2C1_Stop(void)
{
// SDA1 0->1 while SCL1 High
SDA1 = 0;
SCL1 = 1;
i2c_delay();
SDA1 = 1;
i2c_delay();
}
void I2C1_SendACK(void)
{
SDA1 = 0;
SCL1 = 1;
i2c_delay();
SCL1 = 0;
i2c_delay();
}
void I2C1_SendNACK(void)
{
SDA1 = 1;
SCL1 = 1;
i2c_delay();
SCL1 = 0;
i2c_delay();
}
uint8_t I2C1_WriteByte(uint8_t val)
{
uint8_t i, revAck;
for (i= 0 ; i< 8; i++)
{
SCL1 = 0;
if (val & 0x80) // write data
{
SDA1 = 1;
}
else
{
SDA1 = 0;
}
val <<= 1;
i2c_delay();
SCL1 = 1;
i2c_delay();
}
SCL1 = 0;
i2c_delay();
SET_SDA1_IN();
SCL1 = 1;
i2c_delay();
revAck = (uint8_t)SDA1;
SCL1 = 0;
SET_SDA1_OUT();
i2c_delay();
return !revAck; //ACK - 0, NACK - 1
}
uint8_t I2C1_ReadByte(void)
{
uint8_t i;
uint8_t val = 0;
SDA1 = 1; // latch the Data port befor reading
SET_SDA1_IN();
for (i=0; i<8; i++)
{
val <<= 1;
SCL1 = 1;
//asm("nop");
//asm("nop");
//asm("nop");
i2c_delay();
val |= SDA1;
SCL1 = 0;
i2c_delay();
}
SET_SDA1_OUT();
return val;
}
//===================================================================
// 函数功能:通过I2C1写器件寄存器
// 参数:slaveId - 设备IIC从地址(7位),使用时先移位,低位添加读写标志位(0-写,1-读)
// addr - 设备寄存器地址
// dataBuf - 数据缓冲区首地址
// byteNum - 数据长度
// 返回值:无
//===================================================================
uint8_t I2C1_WriteRegs(uint8_t slaveId, uint8_t addr, uint8_t *pBuffer, uint8_t byteNum)
{
uint8_t revAck;
I2C1_Start();
slaveId <<= 1; //移位,低位添加读写标志(0-写)
revAck = I2C1_WriteByte(slaveId); //写slave id(外加读写标志 bit0 - 0写)
revAck &= I2C1_WriteByte(addr); //写寄存器地址
while (byteNum)
{
revAck &= I2C1_WriteByte(*pBuffer); //写数据
pBuffer++;
byteNum--;
}
I2C1_Stop();
return revAck;
}
//===================================================================
// 函数功能:通过I2C1读器件寄存器
// 参数:slaveId - 设备IIC从地址(7位),使用时先移位,低位添加读写标志位(0-写,1-读)
// addr - 设备寄存器地址
// dataBuf - 数据缓冲区首地址
// byteNum - 数据长度
// 返回值:无
//===================================================================
uint8_t I2C1_ReadRegs(uint8_t slaveId, uint8_t addr, uint8_t *pBuffer, uint8_t byteNum)
{
uint8_t revAck;
I2C1_Start();
slaveId <<= 1; //移位,低位添加读写标志(0-写)
revAck = I2C1_WriteByte(slaveId); //写slave id(外加读写标志 bit0 - 0写)
revAck &= I2C1_WriteByte(addr); //写寄存器地址
I2C1_Start();
revAck &= I2C1_WriteByte(slaveId | 0x01); //写slave id(外加读写标志 bit0 - 1读)
while (byteNum)
{
*pBuffer = I2C1_ReadByte();
pBuffer++;
if (--byteNum)
{
I2C1_SendACK(); //读取未完成,发送应答信号
}
else
{
I2C1_SendNACK(); //读最后一个字节时发NACK
}
}
I2C1_Stop();
return revAck;
}