您的位置 首页 主动

C51单片机模仿I2C总线驱动程序设计(1)

**********************************I2C总线驱动******************************模块名:I2C总线驱动型号:I2C功能描述:此模块

/********************************** I2C 总线驱动 ******************************

模块名:I2C 总线驱动 类型:I2C
功用描绘:
此模块包含发送数据及接纳数据,应对位发送,并供给了几个直接面临器材的操作函数,能
很便利的与用户程序进行衔接并扩展。需求留意的是,函数是选用延时办法发生 SCL 脉冲,
对高晶振频率要做必定的修正!!在写 E2PROM 的时分必定要延时!!!
阐明:
1us机器周期,晶振频率要小于12MHz
回来1:则操作成功,回来0:则操作失利。
sla为器材从地址,suba为器材子地址。
*******************************************************************************
#i nclude “AT89X52.h”
#i nclude
#define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //界说空指令
sbit SDA = P1^3; //模仿 I2C 数据传输位
sbit SCL = P1^2; //模仿 I2C 时钟操控位
bit bdata I2C_Ack; //应对标志位
/************************************ I2C_Start *******************************
函数名:void I2C_Start()
进口:
出口:
功用描绘:发动 I2C 总线,即发送 I2C 初始条件
解说: 在 I2C 总线协议中规则的开端位格局是:在 SCL 高电平期间,SDA 发生从高到低的电平
跳变.它与其它数据格局的差异在于,协议中规则有用的数据有必要在 SCL 的高电平期间坚持
不变,只要在 SCL 的低电平期间才干发生跳变.所以这一有别与其它格局的数据才干做为起
始位.
调用函数:
全局变量
*******************************************************************************
void I2C_Start()
{
SDA = 1; //发送开端条件的数据信号
_Nop();
SCL = 1;
SomeNOP(); //开端条件树立时刻大于 4.7us,延时
SDA = 0; //发送开端信号
SomeNOP(); //开端条件树立时刻大于 4us,延时
SCL = 0; //钳住 I2C 总线预备发送或接纳数据
//解说:I2C 总线在闲暇状况下都是被上拉为高电平的,所以当它们处于低电平时就表明忙的状况.
_nop_();
_nop_();
}
/************************************ I2C_Stop ********************************
函数名:void I2C_Stop()
进口:
出口:
功用描绘:完毕 I2C 总线,即发送 I2C 完毕条件
解说:同开端条件的格局相似,完毕条件的格局是在 SCL 高电平期间,SDA 由低电平向高电平
跳变.
调用函数:
全局变量:
*******************************************************************************
void I2C_Stop()
{
SDA = 0; //发送完毕条件的数据信号
_Nop();
SCL = 1; //发送完毕条件的时钟信号
SomeNOP();//完毕条件树立时刻大于 4us,延时
SDA = 1; //发送 I2C 总线完毕信号
SomeNOP();
}
/************************************ I2C_CheckAck ****************************
函数名:bit I2C_CheckAck(void)
进口:
出口:0(无应对),1(有应对)
功用描绘:
查验 I2C 总线应对信号,有应对则回来 1,不然回来 0,超时值取 255.
解说:I2C 总线协议中规则传输的每个字节之后有必要跟一个应对位,所以从器材在接纳到每
个字节之后有必要反应一个应对信号给主操控器,而主操控器就需求检测从器材回传的应对信
号,依据其信息做出相应的处理.别的,主从之别是相对的,接纳数据的即为从,发送数据的及
为主.
再看看应对信号的格局:在由发送器发生的时钟呼应周期里,发送器先开释 SDA(置高),然后
由接受器将 SDA 拉低,并在这个时钟脉冲周期的高电平期间坚持稳定的低电平.即表明从器
件做出了应对.
调用函数:void I2C_Stop()
全局变量:
*******************************************************************************
bit I2C_CheckAck(void)
{
uchar errtime = 255; // 因毛病接纳方无 Ack,超时值为 255
SDA = 1; //发送器先开释 SDA
SomeNOP();
SCL = 1;
SomeNOP(); //时钟电平周期大于 4 us
while(SDA) //判别 SDA 是否被拉低
{
errtime–;
if(errtime==0)
{
I2C_Stop();
return(0);
}
}
SCL = 0;
_nop_();
return(1);
}
/************************************ I2C_SendB *******************************
函数名:void I2C_SendB(uchar c)
进口:uchar 型数据
出口:
功用描绘:
字节数据传送函数,将数据 c 发送出去,可所以地址,也可所以数据,发完后等候应对,
并对
此状况位进行操作
留意:在传送数据时,数据(SDA)的改动只能发生在SCL的低电平期间,在SCL的高电平期间保
持不变
调用函数:bit I2C_CheckAck()
全局变量:I2C_Ack
*******************************************************************************
void I2C_SendB(uchar c)
{
uchar BitCnt;
for (BitCnt=0; BitCnt<8; BitCnt++) //要传送的数据长度为 8 位
{
if((c<
{
SDA = 1;
}
else
{
SDA = 0;
}
_nop_();
_nop_();
SCL = 1; //置时钟线为高告诉被控器开端接纳数据位
SomeNOP(); //确保时钟高电平周期大于 4us
SCL = 0;
}
_nop_();
_nop_();
I2C_Ack = I2C_CheckAck();//查验应对信号,作为发送方,所以要检测接纳器反应的应对信号.
_nop_();
_nop_();
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/258412.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部