钻石会员
  
主题
帖子
积分11988
阅读权限50
注册时间2011-1-9
最后登录1970-1-1
在线时间 小时
|
发上来参考一下,i2c_delay()里面是延时,调整ii初值即可.我是用rtx系统的,一般往里面放个系统等待就行了
#include <stc15f.h> /*头文件的包含*/
//#include <rtx51tny.h>
/*端口位定义*/
sbit SCL=P3^3;/*模拟I2C数据传送位*/
sbit SDA=P3^4;/*模拟I2C时钟控制位*/
void i2c_delay()
{
unsigned char ii=50;
while(ii--);
}
#define true 1
#define false 0
bit I2CStart(void)
{
SDA=1; i2c_delay();
if(!SDA) i2c_delay();
if(!SDA) i2c_delay();
if(!SDA) i2c_delay();
if(!SDA) i2c_delay();
if(!SDA) i2c_delay();
SCL=1; i2c_delay();
if(!SDA) return false; //SDA线为低电平则总线忙,退出
SDA=0; i2c_delay();
while(SDA) return false;//SDA线为高电平则总线出错,退出
SCL=0;
return true;
}
void I2CStop(void)
{ SDA=0;i2c_delay();
SCL=0;i2c_delay();
SCL=1;i2c_delay();
SDA=1;
if(!SDA) { SCL=0;i2c_delay(); SCL=1;i2c_delay(); }
if(!SDA) { SCL=0;i2c_delay(); SCL=1;i2c_delay(); }
if(!SDA) { SCL=0;i2c_delay(); SCL=1;i2c_delay(); }
if(!SDA) { SCL=0;i2c_delay(); SCL=1;i2c_delay(); }
if(!SDA) { SCL=0;i2c_delay(); SCL=1;i2c_delay(); }
}
//*********发送 ACK********
void I2CAck(void)
{ SDA=0;i2c_delay(); SCL=0;i2c_delay(); SCL=1;i2c_delay(); SCL=0;i2c_delay(); }
//*********发送NO ACK********
void I2CNoAck(void)
{ SDA=1;i2c_delay(); SCL=0;i2c_delay(); SCL=1;i2c_delay(); SCL=0;i2c_delay(); }
//*********读取ACK信号********
bit I2CWaitAck(void) //返回为:1=有ACK,0=无ACK
{ SCL=0;i2c_delay(); SDA=1;i2c_delay(); //设置SDA为输入
SCL=1;i2c_delay();
while(SDA) { SCL=0; return false; }
SCL=0;
return true;
}
void I2CSendByte(unsigned char demand) //数据从高位到低位//
{
xdata unsigned char i=8;
while(i--) { SCL=0; i2c_delay();
SDA=(bit)(demand&0x80);
demand<<=1; i2c_delay();
SCL=1; i2c_delay();
}
SCL=0;
}
unsigned char I2CReceiveByte(void) //数据从高位到低位//
{
xdata unsigned char i=8;
xdata unsigned char ddata=0;
SDA=1; //设置SDA为输入
while(i--) { ddata<<=1; //数据从高位开始读取
SCL=0; i2c_delay();
SCL=1; i2c_delay(); //从高位开始 ddata|=SDA;ddata<<=1
if(SDA) { ddata|=0x01; }
}
SCL=0;
return ddata;
}
/*******************************************************************
向无子地址器件发送字节数据函数
函数原型: bit ISendByte(unsigned char sla,ucahr c);
功能:从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
返回1表示操作成功,否则操作有误。
********************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
{
I2CStart(); /*启动总线*/
I2CSendByte(sla); /*发送器件地址*/
if(!(I2CWaitAck()))return 0;
I2CSendByte(c); /*发送数据*/
if(!(I2CWaitAck()))return 0;
I2CStop(); /*结束总线*/
return 1;
}
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
功能:从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,
子地址suba,发送内容是s指向的内容,发送no个字节。如果返回1表示
操作成功,否则操作有误。
********************************************************************/
bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
xdata unsigned char i;
I2CStart(); /*启动总线*/
I2CSendByte(sla); /*发送器件地址*/
if(!(I2CWaitAck()))return 0;
I2CSendByte(suba); /*发送数据*/
if(!(I2CWaitAck()))return 0;
for(i=0;i<no;i++)
{
I2CSendByte(*s); /*发送数据*/
if(!(I2CWaitAck()))return 0;
s++;
}
I2CStop(); /*结束总线*/
return 1;
}
/*******************************************************************
向无子地址器件读字节数据函数
函数原型: bit IRcvByte(unsigned char sla,ucahr *c);
功能:从启动总线到发送地址,读数据,结束总线的全过程,从器件地址sla,返
回值在c。如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit IRcvByte(unsigned char sla,unsigned char *s,unsigned char no)
{
I2CStart(); /*启动总线*/
I2CSendByte(sla+1); /*发送器件地址*/
if(!(I2CWaitAck()))return 0;
while(no!=1)
{
*s=I2CReceiveByte();/*发送数据*/
I2CAck(); /*发送就答位*/
s++;
no--;
}
*s=I2CReceiveByte();
I2CNoAck();
I2CStop(); /*结束总线*/
return 1;
}
/**********************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
功能:从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla,
子地址suba,读出的内容放入s指向的存储区,读no个字节。如果返回1
表示操作成功,否则操作有误。
**********************************************************************/
bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
I2CStart(); /*启动总线*/
I2CSendByte(sla); /*发送器件地址*/
if(!(I2CWaitAck()))return 0;
I2CSendByte(suba); /*发送器件子地址*/
if(!(I2CWaitAck()))return 0;
I2CStart(); /*启动总线*/
I2CSendByte(sla+1);
if(!(I2CWaitAck()))return 0;
while(no!=1)
{
*s=I2CReceiveByte();/*发送数据*/
I2CAck(); /*发送就答位*/
s++;
no--;
}
*s=I2CReceiveByte();
I2CNoAck();
I2CStop(); /*结束总线*/
return(1);
}
|
|