📄 i2c.c
字号:
#include "I2c.h"
#include"string.h"
//#ifdef _USE_I2C
void Init_I2c()
{
SDA_1;
SCL_1;
SCL_OUT; //CLK为输出状态
SDA_OUT;
}
//----------------------------------------------------------------------------------
//I2C 软件模拟程序
//----------------------------------------------------------------------------------
void i2c_start(void)
{
SDA_OUT;
SDA_1; //将数据置1
NOP2;
SCL_1; //时钟置1
NOP2
SDA_0; //启动
NOP2;
SCL_0; //start
NOP2;
}
void i2c_stop(void)
{
SDA_OUT;
SDA_0;
NOP2;
SCL_1;
NOP2;
SDA_1;
NOP2;
}
void i2c_bytewrite(uchar writedata)
{
uchar i;
for(i=0; i<8; i++)
{
if (writedata & BIT7)
SDA_1;
else
SDA_0;
writedata <<= 1;
SCL_1;
NOP4;
SCL_0;
NOP2;
}
}
uchar i2c_byteread(void)
{
uchar i,tempdata=0;
SDA_IN; //置为输入
for (i=0; i<8; i++)
{
SCL_1;
_NOP();
tempdata <<= 1;
if (SDA_VAL)
tempdata |= 1;
SCL_0;
NOP4;
}
return tempdata;
}
void Acknowledge(void)
{
SCL_0;
NOP2;
SDA_OUT;
SDA_0;
SCL_1;
NOP2;
SCL_0;
}
void ReceiveAck(void)
{
uchar i = 0;
SCL_1;
SDA_IN; //送回应脉冲
NOP2;
while ((SDA_VAL) && (i < 20))i++;
SDA_OUT;
SCL_0;
NOP2;
}
uchar I2c_Read(uint i2caddr)
{
uchar tempdata;
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_start();
i2c_bytewrite(DEVADDR_RD); //读地址
ReceiveAck();
tempdata = i2c_byteread();
i2c_stop();
Delay(20);
return tempdata;
}
//从I2C读取字符串,数据保存在 p 指向的缓冲区
//返回读取的字节数
#define MAX_I2C_STRING 32
uchar I2cReadString(uint addr,uchar*p)
{
uchar *pDst = p;
uchar i;
for(i=0;i<MAX_I2C_STRING-1;i++)
{
*pDst = I2c_Read(addr);
if(*pDst++ == 0) break;
}
*pDst =0;//体面结束
return i;
}
void I2c_Write(uint i2caddr,uchar i2cdata)
{
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_bytewrite(i2cdata);
ReceiveAck();
i2c_stop();
Delay(4800);
}
//高位在前
uint I2c_ReadInt(uint i2caddr)
{
uint tempdata;
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_start();
i2c_bytewrite(DEVADDR_RD); //写读取地址
ReceiveAck();
tempdata = i2c_byteread()&0xFF;
tempdata <<=8;
Acknowledge();
tempdata += i2c_byteread()&0xFF;
i2c_stop();
return tempdata;
}
//高位在前
ulong I2c_ReadLong(uint i2caddr)
{
ulong tempdata;
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_start();
i2c_bytewrite(DEVADDR_RD); //写读取地址
ReceiveAck();
tempdata = i2c_byteread()&0xFF;
tempdata <<=8;
Acknowledge();
tempdata += i2c_byteread()&0xFF;
tempdata <<=8;
Acknowledge();
tempdata += i2c_byteread()&0xFF;
tempdata <<=8;
Acknowledge();
tempdata += i2c_byteread()&0xFF;
i2c_stop();
return tempdata;
}
//高位在前
void I2c_WriteInt(uint i2caddr,uint i2cdata)
{
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_bytewrite(i2cdata>>8);
ReceiveAck();
i2c_bytewrite(i2cdata);
ReceiveAck();
i2c_stop();
Delay(4800);
}
void I2CWritestring(ulong addr,const char*p)
{
uchar i;
i=strlen(p);
for( ; i ; i -- )
I2c_Write(addr++, *(p++));
}
//高位在前
void I2c_WriteLong(uint i2caddr, ulong i2cdata)
{
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite(i2caddr>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr); //写低地址
ReceiveAck();
i2c_bytewrite(i2cdata>>24);
ReceiveAck();
i2c_bytewrite(i2cdata>>16);
ReceiveAck();
i2c_bytewrite(i2cdata>>8);
ReceiveAck();
i2c_bytewrite(i2cdata);
ReceiveAck();
i2c_stop();
Delay(4800);
}
//页写入
void I2c_WriteData(uint i2caddr, uchar len , uchar *pdata)
{
uchar idx,idx2,cnt=(len+31)>>5;
//每次可以写入32字节
for (idx=0;idx<cnt;idx++)
{
i2c_start();
i2c_bytewrite(DEVADDR_WR); //写地址
ReceiveAck();
i2c_bytewrite((i2caddr+(idx<<5))>>8); //写高地址
ReceiveAck();
i2c_bytewrite(i2caddr+(idx<<5)); //写低地址
ReceiveAck();
for (idx2=idx<<5;idx2<(idx<<5)+32 && idx2<len;idx2++)
{
i2c_bytewrite(*(pdata+idx2));
ReceiveAck();
}
i2c_stop();
Delay(4800);
}
}
//#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -