📄 iic.c
字号:
#define IIC_GLOBALS
#include "includes.h"
/****************************
I2C总线的特点:
1。所有信息的传递都是在SCL为高电平的时候进行的,当SCL为低电平的时候,
SDA的变化不会对设备产生读写操作,也不会传递控制命令。
2。在SCL为高电平的时候,SDA从高电平变到低电平会产生启动条件
3。在SCL为高电平的时候,SDA从低电平变到高电平会产生停止条件
4。在传输数据信息时,当SCL为高电平的时候,SDA必须保持稳定,否则被认为是启动或停止条件。
这就是之所以传输方必须在SCL变高之前准备好数据的原因
*****************************/
void I2Cstart(void)
{
INT8U j;
SCL_DIRECTION_OUT;
SDA_DIRECTION_OUT;
SDA_DATA_OUT_HIGH;
SDA_DIRECTION_OUT;
SCL_OUT_HIGH;
nop();//开始条件setup时间延时至少600NS
nop();
SDA_DATA_OUT_LOW;
nop();//开始条件保持时间延时至少600NS
nop();
}
void I2CStop(void)
{
INT8U j;
SCL_DIRECTION_OUT;
SDA_DATA_OUT_LOW;
SDA_DIRECTION_OUT;
SCL_OUT_HIGH;
nop(); //开始条件SETUP时间延时至少600NS
nop();
SDA_DATA_OUT_HIGH;
nop(); //总线空闲时间至少延时1.3us
nop();
}
INT8U I2cWriteByte(INT8U ByteData)
{
INT8U dx01,dx02;
SCL_DIRECTION_OUT;
SDA_DIRECTION_OUT;
for(dx01=0;dx01<8;dx01++)
{
dx02=0x80&ByteData;
ByteData<<=1;
SCL_OUT_LOW;//SCL低电平延时1.3uS
if(dx02>0)
SDA_DATA_OUT_HIGH;
else
SDA_DATA_OUT_LOW;
nop();//SCL线数据SETUP时间延时200NS
SCL_OUT_HIGH;//SCL高电平延时600NS
};
nop();
nop();
SCL_OUT_LOW;//低电平延时1.3us
SDA_DIRECTION_IN;
nop();
nop();
SCL_OUT_HIGH;//SCL高电平延时600NS
nop();
nop();
dx01=SDA_DATA_IN;
SCL_OUT_LOW;//不能省略,产生下降沿,使从设备在完成应答后释放SDA
return dx01;
}
INT8U I2cReadByte(INT8U Ack)
{
INT8U ByteData,i;
ByteData=0;
SCL_DIRECTION_OUT;
SDA_DIRECTION_IN;
for(i=0;i<8;i++)
{
SCL_OUT_LOW;
nop();
nop();
SCL_OUT_HIGH;
ByteData<<=1;
nop();
nop();
if(SDA_DATA_IN)
ByteData|=0x01;
};
SCL_OUT_LOW;
nop();
nop();
if(Ack==0)
SDA_DATA_OUT_LOW;
else
SDA_DATA_OUT_HIGH;
SDA_DIRECTION_OUT;
nop();
nop();
SCL_OUT_HIGH;
nop();
nop();
SCL_OUT_LOW;
nop();
nop();
return ByteData;
}
void ClearI2cDevice(INT8U DeviceAddress,INT16U DataAddress,INT8U Length)
{
INT8U i;
INT8U TempVar;
TempVar=(DataAddress>>7);
TempVar&=0xfe;
I2Cstart();
I2cWriteByte(DeviceAddress|TempVar);//送出从器件地址?
I2cWriteByte((INT8U)DataAddress); //送出字节地址
for(i=0;i<Length;i++)
I2cWriteByte(0x00);
I2CStop();
}
void WriteI2cDevice(INT8U DeviceAddress,INT8U *SourceAddress,INT16U DestinationAddress,INT8U Length)
{
INT8U i,TempVar;
INT8U *TempPnt;
TempPnt=SourceAddress;
TempVar=(DestinationAddress>>7);
TempVar&=0xfe;
I2Cstart();
I2cWriteByte(DeviceAddress|TempVar); //送出从器件地址?
I2cWriteByte((INT8U)DestinationAddress); //送出字节地址
for(i=0;i<Length;i++)
{
I2cWriteByte(*TempPnt);
TempPnt++;
};
I2CStop();
}
void ReadI2cDevice(INT8U DeviceAddress,INT16U SourceAddress,INT8U *DestinationAddress,INT8U Length)
{
INT8U i,*TempPnt;
INT8U TempVar;
TempVar=(SourceAddress>>7);
TempVar&=0xfe;
TempPnt=DestinationAddress;
if(Length)
{
I2Cstart();
I2cWriteByte(DeviceAddress|TempVar); //送出从器件地址
I2cWriteByte((INT8U)SourceAddress); //送出字节地址
I2Cstart();
I2cWriteByte(DeviceAddress|TempVar|0x01); //送出从器件地址
for(i=0;i<Length-1;i++)
{
*TempPnt=I2cReadByte(0);
TempPnt++;
};
*TempPnt=I2cReadByte(1);
I2CStop();
};
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -