📄 i2c.c
字号:
//模拟I2C总线的C51通用程序:
#include "reg51.h"
#include "intrins.h"
sbit SCL= P1^6; //定义SCL线所在口,可以根据自己的需要来定义
sbit SDA= P1^7; //定义SDA线所在口,可以根据自己的需要来定义
unsigned char error;
/*--------------------------------------------------------------------------------
调用方式:void Start_I2C (void)
函数说明:启动总线函数,发送I2C总线起始条件
---------------------------------------------------------------------------------*/
void Start_I2C(void)
{
EA=0;
SDA=1; //发送I2C总线起始条件的数据信号
SCL=1; //发送I2C总线起始条件的时钟信号
_nop_(); //数据线保持高,延时
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0; //发送起始信号
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0; //时钟线从高到低一次跳变,I2C通信开始
}
/*--------------------------------------------------------------------------------
调用方式:void Stop_I2C (void)
函数说明:结束总线函数,发送I2C总线停止条件
---------------------------------------------------------------------------------*/
void Stop_I2C (void)
{
SCL=0; //发送I2C总线停止条件的时钟信号
SDA=0; //发送I2C总线停止条件的数据信号
_nop_(); //数据线保持低,延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1; //时钟线从低到高一次跳变,I2C通信停止
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1; ///发送I2C总线停止的数据信号
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
EA=1;
}
/*--------------------------------------------------------------------------------
调用方式: void Ack_I2C (void)
函数说明:主控制器等待从器件接收方的应答
---------------------------------------------------------------------------------*/
void Ack_I2C(void)
{
unsigned char errtime=255; //因故障接收方无ACK,超时值为255。
SDA=1;
SCL=1;
error=0x10;
while(SDA)
{
errtime--;
if(!errtime)
{
Stop_I2C ();
error=0x11; //出错后给全局变量赋值
return;
}
}
SCL=0;
}
/*--------------------------------------------------------------------------------
调用方式:void SendAck(void)
函数说明:主器件为接收方,从器件为发送方时,从器件等待主器件的应答信号。
---------------------------------------------------------------------------------*/
void SendAck(void)
{
SDA=0; //数据线保持低,时钟线发生一次从高低的跳变 发送一个应答信号
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*--------------------------------------------------------------------------------
调用方式:void SendNotAck(void)
函数说明:主器件为接收方,从器件为发送方时,非应答信号。
--------------------------------------------------------------------------------*/
void SendNotAck(void)
{
SDA=1; //数据线保持高,时钟线发生一次从高低的跳变 没有应答
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*--------------------------------------------------------------------------------
调用方式:void Send_I2C (uchar ch) 2003/05/13
函数说明:I2C总线字节发送函数
---------------------------------------------------------------------------------*/
void Send_I2C (Byte ch)
{
unsigned char i;
for (i=0;i<=8;i++)
{
SCL=0; //时钟保持低可以发送数据
_nop_();
SDA=(ch&0x80);
ch<<=1;
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
}
SCL=0;
}
/*--------------------------------------------------------------------------------
调用方式:unsigned char Receive_I2C (void)
函数说明:接收I2C总线从器件传来的数据
---------------------------------------------------------------------------------*/
unsigned char Receive_I2C(void)
{
unsigned char i,data=0;
SDA=1;
for (i=0;i<=8;i++)
{
data<<=1;
SCL=0;
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1; //时钟做一次从低到高的跳变 可以接收数据
_nop_(); //延时
_nop_();
_nop_();
_nop_();
_nop_();
data|=SDA;
}
SCL=0;
return data;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -